aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-samsung
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
commitc6da2cfeb05178a11c6d062a06f8078150ee492f (patch)
treef3b4021d252c52d6463a9b3c1bb7245e399b009c /arch/arm/plat-samsung
parentc6d7c4dbff353eac7919342ae6b3299a378160a6 (diff)
downloadkernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2
samsung update 1
Diffstat (limited to 'arch/arm/plat-samsung')
-rw-r--r--arch/arm/plat-samsung/Kconfig89
-rw-r--r--arch/arm/plat-samsung/Makefile10
-rw-r--r--arch/arm/plat-samsung/adc.c271
-rw-r--r--arch/arm/plat-samsung/clock.c131
-rw-r--r--arch/arm/plat-samsung/cpu.c58
-rw-r--r--arch/arm/plat-samsung/dev-adc.c4
-rw-r--r--arch/arm/plat-samsung/dev-asocdma.c14
-rw-r--r--arch/arm/plat-samsung/dev-backlight.c149
-rw-r--r--arch/arm/plat-samsung/dev-fb.c14
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c3
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c1
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c7
-rw-r--r--arch/arm/plat-samsung/dev-hwmon.c14
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c16
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c3.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c4.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c5.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c6.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c7.c24
-rw-r--r--arch/arm/plat-samsung/dev-mshc.c101
-rw-r--r--arch/arm/plat-samsung/dev-nand.c9
-rw-r--r--arch/arm/plat-samsung/dev-pwm.c93
-rw-r--r--arch/arm/plat-samsung/dev-ts.c16
-rw-r--r--arch/arm/plat-samsung/dev-ts1.c60
-rw-r--r--arch/arm/plat-samsung/dev-usb.c9
-rw-r--r--arch/arm/plat-samsung/dev-usb3-exynos-drd.c103
-rw-r--r--arch/arm/plat-samsung/dev-wdt.c2
-rw-r--r--arch/arm/plat-samsung/dma_m2m_test.c323
-rw-r--r--arch/arm/plat-samsung/gpio-config.c96
-rw-r--r--arch/arm/plat-samsung/include/plat/adc.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/backlight.h26
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h12
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h145
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h120
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h18
-rw-r--r--arch/arm/plat-samsung/include/plat/fb-core.h21
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h63
-rw-r--r--arch/arm/plat-samsung/include/plat/fimd_lite_ext.h99
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h81
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h9
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/iovmm.h76
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h14
-rw-r--r--arch/arm/plat-samsung/include/plat/mshci.h161
-rw-r--r--arch/arm/plat-samsung/include/plat/pd.h37
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h17
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-adc.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb-v4.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb.h117
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-otg.h260
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h75
-rw-r--r--arch/arm/plat-samsung/include/plat/rtc-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h22
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h67
-rw-r--r--arch/arm/plat-samsung/include/plat/sysmmu.h107
-rw-r--r--arch/arm/plat-samsung/include/plat/ts.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/tv-core.h37
-rw-r--r--arch/arm/plat-samsung/include/plat/udc-hs.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/watchdog-reset.h12
-rw-r--r--arch/arm/plat-samsung/irq-uart.c11
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c5
-rw-r--r--arch/arm/plat-samsung/pd.c42
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c33
-rw-r--r--arch/arm/plat-samsung/pm.c69
-rw-r--r--arch/arm/plat-samsung/pwm.c103
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c109
72 files changed, 3304 insertions, 511 deletions
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 4d79519..8c0b49f 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -15,6 +15,17 @@ config PLAT_SAMSUNG
if PLAT_SAMSUNG
+# vmalloc area and io map configurations
+
+comment "Base Address for SFR mapping"
+
+config S3C_ADDR_BASE
+ hex "S3C Base Address for SFR mapping"
+ default 0xF6000000
+ help
+ This value will be base address for S3C SFR mapping and
+ VMALLC_END should be less or euqal to this value.
+
# boot configurations
comment "Boot options"
@@ -149,6 +160,23 @@ config S3C_ADC
Core support for the ADC block found in the Samsung SoC systems
for drivers such as the touchscreen and hwmon to use to share
this resource.
+choice
+ prompt "Select ADC Number"
+ depends on S3C_ADC
+ default S3C_DEV_ADC
+
+config S3C_DEV_ADC
+ bool "ADC 0 selection"
+ depends on S3C_ADC
+ help
+ Say Y here if you want to use S3C SMDK ADC 0.
+
+config S3C_DEV_ADC1
+ bool "ADC 1 selection"
+ depends on S3C_ADC
+ help
+ Say Y here if you want to use S3C SMDK ADC 1.
+endchoice
# device definitions to compile in
@@ -172,6 +200,11 @@ config S3C_DEV_HSMMC3
help
Compile in platform device definitions for HSMMC channel 3
+config EXYNOS4_DEV_MSHC
+ bool
+ help
+ Compile in platform device definitions for MSHC
+
config S3C_DEV_HWMON
bool
help
@@ -212,6 +245,36 @@ config S3C_DEV_I2C7
help
Compile in platform device definition for I2C controller 7
+config S3C_DEV_I2C8_EMUL
+ depends on CPU_EXYNOS4210
+ bool "I2C8 Information GPIO bitbanging emulation"
+ help
+ Compile in platform device definitions for I2C channel 8
+
+config S3C_DEV_I2C9_EMUL
+ bool "I2C9 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 9
+
+config S3C_DEV_I2C11_EMUL
+ bool "I2C11 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 11
+
+config S3C_DEV_I2C14_EMUL
+ bool "I2C14 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 14
+
+config S3C_DEV_I2C16_EMUL
+ bool "I2C16 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 16
+
config S3C_DEV_FB
bool
help
@@ -227,6 +290,12 @@ config S3C_DEV_USB_HSOTG
help
Compile in platform device definition for USB high-speed OtG
+config EXYNOS_DEV_SS_UDC
+ bool
+ help
+ Compile in platform device definition for EXYNOS SuperSpeed USB 3.0
+ Device controller
+
config S3C_DEV_WDT
bool
default y if ARCH_S3C2410
@@ -260,6 +329,7 @@ config SAMSUNG_DEV_IDE
config S3C64XX_DEV_SPI
bool
+ default y if SPI_S3C64XX
help
Compile in platform device definitions for S3C64XX's type
SPI controllers.
@@ -267,7 +337,12 @@ config S3C64XX_DEV_SPI
config SAMSUNG_DEV_TS
bool
help
- Common in platform device definitions for touchscreen device
+ Common in platform device definitions for touchscreen device
+
+config SAMSUNG_DEV_TS1
+ bool
+ help
+ Common in platform device definitions for touchscreen-1 device
config SAMSUNG_DEV_KEYPAD
bool
@@ -280,6 +355,12 @@ config SAMSUNG_DEV_PWM
help
Compile in platform device definition for PWM Timer
+config SAMSUNG_DEV_BACKLIGHT
+ bool
+ depends on SAMSUNG_DEV_PWM
+ help
+ Compile in platform device definition LCD backlight with PWM Timer
+
config S3C24XX_PWM
bool "PWM device support"
select HAVE_PWM
@@ -300,6 +381,12 @@ config S3C_PL330_DMA
help
S3C DMA API Driver for PL330 DMAC.
+config DMA_M2M_TEST
+ tristate "S3C DMA API Test client"
+ help
+ Samsung DMA API test client. Say N unless you're debugging a
+ DMA Device driver.
+
comment "Power management"
config SAMSUNG_PM_DEBUG
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 53eb15b..ab0fa91 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -11,7 +11,7 @@ obj- :=
# Objects we always build independent of SoC choice
-obj-y += init.o
+obj-y += init.o cpu.o
obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
obj-y += clock.o
obj-y += pwm-clock.o
@@ -36,6 +36,7 @@ obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o
obj-$(CONFIG_S3C_DEV_HSMMC3) += dev-hsmmc3.o
+obj-$(CONFIG_EXYNOS4_DEV_MSHC) += dev-mshc.o
obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
@@ -50,6 +51,7 @@ obj-y += dev-uart.o
obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
obj-$(CONFIG_S3C_DEV_WDT) += dev-wdt.o
+obj-$(CONFIG_EXYNOS_DEV_SS_UDC) += dev-usb3-exynos-drd.o
obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
obj-$(CONFIG_S3C_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
@@ -57,8 +59,10 @@ obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o
obj-$(CONFIG_SAMSUNG_DEV_IDE) += dev-ide.o
obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o
+obj-$(CONFIG_SAMSUNG_DEV_TS1) += dev-ts1.o
obj-$(CONFIG_SAMSUNG_DEV_KEYPAD) += dev-keypad.o
-obj-$(CONFIG_SAMSUNG_DEV_PWM) += dev-pwm.o
+obj-$(CONFIG_HAVE_PWM) += dev-pwm.o
+obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
# DMA support
@@ -66,6 +70,8 @@ obj-$(CONFIG_S3C_DMA) += dma.o
obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o
+obj-$(CONFIG_DMA_M2M_TEST) += dma_m2m_test.o
+
# PM support
obj-$(CONFIG_PM) += pm.o
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
index e8f2be2..389e7e0 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -39,24 +39,28 @@
*/
enum s3c_cpu_type {
- TYPE_S3C24XX,
- TYPE_S3C64XX
+ TYPE_ADCV1, /* S3C24XX */
+ TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */
+ TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */
+ TYPE_ADCV4, /* EXYNOS4412, EXYNOS5250 */
};
struct s3c_adc_client {
struct platform_device *pdev;
- struct list_head pend;
+ struct list_head pend;
wait_queue_head_t *wait;
- unsigned int nr_samples;
- int result;
- unsigned char is_ts;
- unsigned char channel;
+ unsigned int nr_samples;
+ int result;
+ unsigned char is_ts;
+ unsigned char channel;
void (*select_cb)(struct s3c_adc_client *c, unsigned selected);
void (*convert_cb)(struct s3c_adc_client *c,
unsigned val1, unsigned val2,
unsigned *samples_left);
+ atomic_t running;
+ int error_count;
};
struct adc_device {
@@ -91,30 +95,37 @@ static inline void s3c_adc_select(struct adc_device *adc,
struct s3c_adc_client *client)
{
unsigned con = readl(adc->regs + S3C2410_ADCCON);
+ enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
client->select_cb(client, 1);
con &= ~S3C2410_ADCCON_MUXMASK;
con &= ~S3C2410_ADCCON_STDBM;
con &= ~S3C2410_ADCCON_STARTMASK;
-
- if (!client->is_ts)
- con |= S3C2410_ADCCON_SELMUX(client->channel);
+ con |= S3C2410_ADCCON_PRSCEN;
+
+ if (!client->is_ts) {
+ if (cpu >= TYPE_ADCV3)
+ writel(S5PV210_ADCCON_SELMUX(client->channel),
+ adc->regs + S5P_ADCMUX);
+ else
+ con |= S3C2410_ADCCON_SELMUX(client->channel);
+ }
writel(con, adc->regs + S3C2410_ADCCON);
}
static void s3c_adc_dbgshow(struct adc_device *adc)
{
- adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
+ adc_dbg(adc, "CON=%08x, DLY=%08x\n",
readl(adc->regs + S3C2410_ADCCON),
- readl(adc->regs + S3C2410_ADCTSC),
readl(adc->regs + S3C2410_ADCDLY));
}
static void s3c_adc_try(struct adc_device *adc)
{
struct s3c_adc_client *next = adc->ts_pend;
+ unsigned int con = readl(adc->regs + S3C2410_ADCCON);
if (!next && !list_empty(&adc_pending)) {
next = list_first_entry(&adc_pending,
@@ -129,25 +140,43 @@ static void s3c_adc_try(struct adc_device *adc)
s3c_adc_select(adc, next);
s3c_adc_convert(adc);
s3c_adc_dbgshow(adc);
+ } else {
+ con &= ~S3C2410_ADCCON_PRSCEN;
+ con |= S3C2410_ADCCON_STDBM;
+ writel(con, adc->regs + S3C2410_ADCCON);
}
}
+static void s3c_convert_done(struct s3c_adc_client *client,
+ unsigned v, unsigned u, unsigned *left)
+{
+ client->result = v;
+ wake_up(client->wait);
+}
+
int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples)
+ unsigned int channel, unsigned int nr_samples,
+ wait_queue_head_t *pwake)
{
struct adc_device *adc = adc_dev;
unsigned long flags;
- if (!adc) {
- printk(KERN_ERR "%s: failed to find adc\n", __func__);
- return -EINVAL;
- }
+ BUG_ON(!adc);
if (client->is_ts && adc->ts_pend)
return -EAGAIN;
+ if (atomic_xchg(&client->running, 1)) {
+ WARN(1, "%s: %p is already running\n", __func__, client);
+ return -EAGAIN;
+ }
+
spin_lock_irqsave(&adc->lock, flags);
+ client->convert_cb = s3c_convert_done;
+ client->wait = pwake;
+ client->result = -1;
+
client->channel = channel;
client->nr_samples = nr_samples;
@@ -165,30 +194,68 @@ int s3c_adc_start(struct s3c_adc_client *client,
}
EXPORT_SYMBOL_GPL(s3c_adc_start);
-static void s3c_convert_done(struct s3c_adc_client *client,
- unsigned v, unsigned u, unsigned *left)
+static void s3c_adc_stop(struct s3c_adc_client *client)
{
- client->result = v;
- wake_up(client->wait);
+ unsigned long flags;
+
+ spin_lock_irqsave(&adc_dev->lock, flags);
+
+ /* We should really check that nothing is in progress. */
+ if (adc_dev->cur == client)
+ adc_dev->cur = NULL;
+ if (adc_dev->ts_pend == client)
+ adc_dev->ts_pend = NULL;
+ else {
+ struct list_head *p, *n;
+ struct s3c_adc_client *tmp;
+
+ list_for_each_safe(p, n, &adc_pending) {
+ tmp = list_entry(p, struct s3c_adc_client, pend);
+ if (tmp == client)
+ list_del(&tmp->pend);
+ }
+ }
+
+ if (!atomic_xchg(&client->running, 0))
+ WARN(1, "%s: %p is already stopped\n", __func__, client);
+
+ if (adc_dev->cur == NULL)
+ s3c_adc_try(adc_dev);
+
+ spin_unlock_irqrestore(&adc_dev->lock, flags);
}
int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
{
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+ struct adc_device *adc = adc_dev;
+ unsigned long flags;
int ret;
- client->convert_cb = s3c_convert_done;
- client->wait = &wake;
- client->result = -1;
-
- ret = s3c_adc_start(client, ch, 1);
+ ret = s3c_adc_start(client, ch, 1, &wake);
if (ret < 0)
goto err;
ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
if (client->result < 0) {
+ s3c_adc_stop(client);
+ dev_warn(&adc_dev->pdev->dev, "%s: %p is timed out\n",
+ __func__, client);
+ ++client->error_count;
+ BUG_ON(client->error_count > 10);
ret = -ETIMEDOUT;
goto err;
+ } else {
+ client->error_count = 0;
+
+ spin_lock_irqsave(&adc->lock, flags);
+ /* client->result >=0 means s3c_adc_irq ->
+ s3c_convert_done is running or finished. Make sure
+ it is *finished* (not running) by lock/unlocking
+ spin lock. Otherwise, after return of this
+ function, wake_up() on destroyed 'wake' may be
+ executed which will destroy stack */
+ spin_unlock_irqrestore(&adc->lock, flags);
}
client->convert_cb = NULL;
@@ -239,30 +306,7 @@ EXPORT_SYMBOL_GPL(s3c_adc_register);
void s3c_adc_release(struct s3c_adc_client *client)
{
- unsigned long flags;
-
- spin_lock_irqsave(&adc_dev->lock, flags);
-
- /* We should really check that nothing is in progress. */
- if (adc_dev->cur == client)
- adc_dev->cur = NULL;
- if (adc_dev->ts_pend == client)
- adc_dev->ts_pend = NULL;
- else {
- struct list_head *p, *n;
- struct s3c_adc_client *tmp;
-
- list_for_each_safe(p, n, &adc_pending) {
- tmp = list_entry(p, struct s3c_adc_client, pend);
- if (tmp == client)
- list_del(&tmp->pend);
- }
- }
-
- if (adc_dev->cur == NULL)
- s3c_adc_try(adc_dev);
-
- spin_unlock_irqrestore(&adc_dev->lock, flags);
+ s3c_adc_stop(client);
kfree(client);
}
EXPORT_SYMBOL_GPL(s3c_adc_release);
@@ -272,50 +316,60 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
struct adc_device *adc = pw;
struct s3c_adc_client *client = adc->cur;
enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
- unsigned data0, data1;
+ unsigned data0 = 0, data1 = 0;
- if (!client) {
+ spin_lock(&adc->lock);
+
+ if (!client || !client->nr_samples) {
dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
goto exit;
}
data0 = readl(adc->regs + S3C2410_ADCDAT0);
- data1 = readl(adc->regs + S3C2410_ADCDAT1);
+ if (cpu != TYPE_ADCV4)
+ data1 = readl(adc->regs + S3C2410_ADCDAT1);
+
adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
- client->nr_samples--;
+ if (client->nr_samples > 0)
+ client->nr_samples--;
- if (cpu == TYPE_S3C64XX) {
- /* S3C64XX ADC resolution is 12-bit */
- data0 &= 0xfff;
- data1 &= 0xfff;
- } else {
+ if (cpu == TYPE_ADCV1) {
data0 &= 0x3ff;
data1 &= 0x3ff;
+ } else {
+ /* S3C64XX/S5P ADC resolution is 12-bit */
+ data0 &= 0xfff;
+ data1 &= 0xfff;
}
if (client->convert_cb)
(client->convert_cb)(client, data0, data1, &client->nr_samples);
if (client->nr_samples > 0) {
- /* fire another conversion for this */
-
- client->select_cb(client, 1);
+ /* fire another conversion for this client */
+ (client->select_cb)(client, 1);
s3c_adc_convert(adc);
} else {
- spin_lock(&adc->lock);
+ /* finish conversion for this client */
(client->select_cb)(client, 0);
- adc->cur = NULL;
+ if (!atomic_xchg(&client->running, 0))
+ WARN(1, "%s: %p is already stopped\n", __func__,
+ client);
+ /* fire conversion for next client if any */
+ adc->cur = NULL;
s3c_adc_try(adc);
- spin_unlock(&adc->lock);
}
exit:
- if (cpu == TYPE_S3C64XX) {
+ if (cpu != TYPE_ADCV1) {
/* Clear ADC interrupt */
writel(0, adc->regs + S3C64XX_ADCCLRINT);
}
+
+ spin_unlock(&adc->lock);
+
return IRQ_HANDLED;
}
@@ -324,11 +378,12 @@ static int s3c_adc_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct adc_device *adc;
struct resource *regs;
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
int ret;
unsigned tmp;
adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
- if (adc == NULL) {
+ if (unlikely(adc == NULL)) {
dev_err(dev, "failed to allocate adc_device\n");
return -ENOMEM;
}
@@ -338,35 +393,22 @@ static int s3c_adc_probe(struct platform_device *pdev)
adc->pdev = pdev;
adc->prescale = S3C2410_ADCCON_PRSCVL(49);
- adc->irq = platform_get_irq(pdev, 1);
- if (adc->irq <= 0) {
- dev_err(dev, "failed to get adc irq\n");
- ret = -ENOENT;
- goto err_alloc;
- }
-
- ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
- if (ret < 0) {
- dev_err(dev, "failed to attach adc irq\n");
- goto err_alloc;
- }
-
- adc->clk = clk_get(dev, "adc");
- if (IS_ERR(adc->clk)) {
+ adc->clk = clk_get(NULL, "adc");
+ if (unlikely(IS_ERR(adc->clk))) {
dev_err(dev, "failed to get adc clock\n");
ret = PTR_ERR(adc->clk);
- goto err_irq;
+ goto err_alloc;
}
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
+ if (unlikely(!regs)) {
dev_err(dev, "failed to find registers\n");
ret = -ENXIO;
goto err_clk;
}
adc->regs = ioremap(regs->start, resource_size(regs));
- if (!adc->regs) {
+ if (unlikely(!adc->regs)) {
dev_err(dev, "failed to map registers\n");
ret = -ENXIO;
goto err_clk;
@@ -374,13 +416,35 @@ static int s3c_adc_probe(struct platform_device *pdev)
clk_enable(adc->clk);
+#if defined(CONFIG_S3C_DEV_ADC1)
+ tmp = readl(adc->regs + S3C2410_ADCCON);
+ tmp |= S3C64XX_ADCCON_TSSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->regs += 0x1000;
+#endif
+
tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
- if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) {
- /* Enable 12-bit ADC resolution */
+
+ /* Enable 12-bit ADC resolution */
+ if (cpu != TYPE_ADCV1) {
tmp |= S3C64XX_ADCCON_RESSEL;
}
+ tmp |= S3C2410_ADCCON_STDBM;
writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->irq = platform_get_irq(pdev, 1);
+ if (unlikely(adc->irq <= 0)) {
+ dev_err(dev, "failed to get adc irq\n");
+ ret = -ENOENT;
+ goto err_clk;
+ }
+
+ ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
+ if (unlikely(ret < 0)) {
+ dev_err(dev, "failed to attach adc irq\n");
+ goto err_clk;
+ }
+
dev_info(dev, "attached adc driver\n");
platform_set_drvdata(pdev, adc);
@@ -391,9 +455,6 @@ static int s3c_adc_probe(struct platform_device *pdev)
err_clk:
clk_put(adc->clk);
- err_irq:
- free_irq(adc->irq, adc);
-
err_alloc:
kfree(adc);
return ret;
@@ -435,12 +496,24 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
static int s3c_adc_resume(struct platform_device *pdev)
{
struct adc_device *adc = platform_get_drvdata(pdev);
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
+ unsigned int tmp = 0;
clk_enable(adc->clk);
enable_irq(adc->irq);
- writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
- adc->regs + S3C2410_ADCCON);
+#if defined(CONFIG_S3C_DEV_ADC1)
+ adc->regs -= 0x1000;
+ tmp = readl(adc->regs + S3C2410_ADCCON);
+ tmp |= S3C64XX_ADCCON_TSSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->regs += 0x1000;
+#endif
+ tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+ /* Enable 12-bit ADC resolution */
+ if (cpu != TYPE_ADCV1)
+ tmp |= S3C64XX_ADCCON_RESSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
return 0;
}
@@ -452,11 +525,17 @@ static int s3c_adc_resume(struct platform_device *pdev)
static struct platform_device_id s3c_adc_driver_ids[] = {
{
- .name = "s3c24xx-adc",
- .driver_data = TYPE_S3C24XX,
+ .name = "s3c24xx-adc",
+ .driver_data = TYPE_ADCV1,
+ }, {
+ .name = "s3c64xx-adc",
+ .driver_data = TYPE_ADCV2,
+ }, {
+ .name = "samsung-adc-v3",
+ .driver_data = TYPE_ADCV3,
}, {
- .name = "s3c64xx-adc",
- .driver_data = TYPE_S3C64XX,
+ .name = "samsung-adc-v4",
+ .driver_data = TYPE_ADCV4,
},
{ }
};
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 7728928..40454d7 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -27,7 +27,6 @@
*/
#include <linux/init.h>
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
@@ -64,108 +63,55 @@ static LIST_HEAD(clocks);
*/
DEFINE_SPINLOCK(clocks_lock);
-/* enable and disable calls for use with the clk struct */
-
-static int clk_null_enable(struct clk *clk, int enable)
-{
- return 0;
-}
-
-static int dev_is_s3c_uart(struct device *dev)
+/* Global watchdog clock used by arch_wtd_reset() callback */
+struct clk *s3c2410_wdtclk;
+static int __init s3c_wdt_reset_init(void)
{
- struct platform_device **pdev = s3c24xx_uart_devs;
- int i;
- for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
- if (*pdev && dev == &(*pdev)->dev)
- return 1;
+ s3c2410_wdtclk = clk_get(NULL, "watchdog");
+ if (IS_ERR(s3c2410_wdtclk))
+ printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
return 0;
}
+arch_initcall(s3c_wdt_reset_init);
-/*
- * Serial drivers call get_clock() very early, before platform bus
- * has been set up, this requires a special check to let them get
- * a proper clock
- */
-
-static int dev_is_platform_device(struct device *dev)
-{
- return dev->bus == &platform_bus_type ||
- (dev->bus == NULL && dev_is_s3c_uart(dev));
-}
-
-/* Clock API calls */
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
- struct clk *p;
- struct clk *clk = ERR_PTR(-ENOENT);
- int idno;
-
- if (dev == NULL || !dev_is_platform_device(dev))
- idno = -1;
- else
- idno = to_platform_device(dev)->id;
-
- spin_lock(&clocks_lock);
-
- list_for_each_entry(p, &clocks, list) {
- if (p->id == idno &&
- strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
-
- /* check for the case where a device was supplied, but the
- * clock that was being searched for is not device specific */
-
- if (IS_ERR(clk)) {
- list_for_each_entry(p, &clocks, list) {
- if (p->id == -1 && strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
- }
-
- spin_unlock(&clocks_lock);
- return clk;
-}
+/* enable and disable calls for use with the clk struct */
-void clk_put(struct clk *clk)
+static int clk_null_enable(struct clk *clk, int enable)
{
- module_put(clk->owner);
+ return 0;
}
int clk_enable(struct clk *clk)
{
+ unsigned long flags;
+
if (IS_ERR(clk) || clk == NULL)
return -EINVAL;
clk_enable(clk->parent);
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if ((clk->usage++) == 0)
(clk->enable)(clk, 1);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
void clk_disable(struct clk *clk)
{
+ unsigned long flags;
+
if (IS_ERR(clk) || clk == NULL)
return;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if ((--clk->usage) == 0)
(clk->enable)(clk, 0);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
clk_disable(clk->parent);
}
@@ -197,6 +143,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
int clk_set_rate(struct clk *clk, unsigned long rate)
{
+ unsigned long flags;
int ret;
if (IS_ERR(clk))
@@ -212,9 +159,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
if (clk->ops == NULL || clk->ops->set_rate == NULL)
return -EINVAL;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
ret = (clk->ops->set_rate)(clk, rate);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return ret;
}
@@ -226,23 +173,22 @@ struct clk *clk_get_parent(struct clk *clk)
int clk_set_parent(struct clk *clk, struct clk *parent)
{
+ unsigned long flags;
int ret = 0;
if (IS_ERR(clk))
return -EINVAL;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if (clk->ops && clk->ops->set_parent)
ret = (clk->ops->set_parent)(clk, parent);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return ret;
}
-EXPORT_SYMBOL(clk_get);
-EXPORT_SYMBOL(clk_put);
EXPORT_SYMBOL(clk_enable);
EXPORT_SYMBOL(clk_disable);
EXPORT_SYMBOL(clk_get_rate);
@@ -343,17 +289,20 @@ struct clk s3c24xx_uclk = {
*/
int s3c24xx_register_clock(struct clk *clk)
{
+ unsigned long flags;
+
if (clk->enable == NULL)
clk->enable = clk_null_enable;
- /* add to the list of available clocks */
+ /* fill up the clk_lookup structure and register it*/
+ clk->lookup.dev_id = clk->devname;
+ clk->lookup.con_id = clk->name;
+ clk->lookup.clk = clk;
+ clkdev_add(&clk->lookup);
- /* Quick check to see if this clock has already been registered. */
- BUG_ON(clk->list.prev != clk->list.next);
-
- spin_lock(&clocks_lock);
- list_add(&clk->list, &clocks);
- spin_unlock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
+ list_add_tail(&clk->list, &clocks);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
@@ -458,15 +407,12 @@ static struct dentry *clk_debugfs_root;
static int clk_debugfs_register_one(struct clk *c)
{
int err;
- struct dentry *d, *child, *child_tmp;
+ struct dentry *d;
struct clk *pa = c->parent;
char s[255];
char *p = s;
- p += sprintf(p, "%s", c->name);
-
- if (c->id >= 0)
- sprintf(p, ":%d", c->id);
+ p += sprintf(p, "%s", c->devname ?: c->name);
d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
if (!d)
@@ -488,10 +434,7 @@ static int clk_debugfs_register_one(struct clk *c)
return 0;
err_out:
- d = c->dent;
- list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
- debugfs_remove(child);
- debugfs_remove(c->dent);
+ debugfs_remove_recursive(c->dent);
return err;
}
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
new file mode 100644
index 0000000..81c06d4
--- /dev/null
+++ b/arch/arm/plat-samsung/cpu.c
@@ -0,0 +1,58 @@
+/* linux/arch/arm/plat-samsung/cpu.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CPU Support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+
+unsigned long samsung_cpu_id;
+static unsigned int samsung_cpu_rev;
+
+unsigned int samsung_rev(void)
+{
+ return samsung_cpu_rev;
+}
+EXPORT_SYMBOL(samsung_rev);
+
+void __init s3c24xx_init_cpu(void)
+{
+ /* nothing here yet */
+
+ samsung_cpu_rev = 0;
+}
+
+void __init s3c64xx_init_cpu(void)
+{
+ samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118);
+ if (!samsung_cpu_id) {
+ /*
+ * S3C6400 has the ID register in a different place,
+ * and needs a write before it can be read.
+ */
+ __raw_writel(0x0, S3C_VA_SYS + 0xA1C);
+ samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0xA1C);
+ }
+
+ samsung_cpu_rev = 0;
+}
+
+void __init s5p_init_cpu(void __iomem *cpuid_addr)
+{
+ samsung_cpu_id = __raw_readl(cpuid_addr);
+ samsung_cpu_rev = samsung_cpu_id & 0xFF;
+}
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c
index 9d903d4..d9d0357 100644
--- a/arch/arm/plat-samsung/dev-adc.c
+++ b/arch/arm/plat-samsung/dev-adc.c
@@ -23,12 +23,14 @@
static struct resource s3c_adc_resource[] = {
[0] = {
.start = SAMSUNG_PA_ADC,
- .end = SAMSUNG_PA_ADC + SZ_256 - 1,
+ .end = SAMSUNG_PA_ADC + SZ_8K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
+#if defined(CONFIG_TOUCHSCREEN_S3C2410)
.start = IRQ_TC,
.end = IRQ_TC,
+#endif
.flags = IORESOURCE_IRQ,
},
[2] = {
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
index a068c4f..aabee5e 100644
--- a/arch/arm/plat-samsung/dev-asocdma.c
+++ b/arch/arm/plat-samsung/dev-asocdma.c
@@ -23,3 +23,17 @@ struct platform_device samsung_asoc_dma = {
}
};
EXPORT_SYMBOL(samsung_asoc_dma);
+
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+static u64 audio_idmamask = DMA_BIT_MASK(32);
+
+struct platform_device samsung_asoc_idma = {
+ .name = "samsung-audio-idma",
+ .id = -1,
+ .dev = {
+ .dma_mask = &audio_idmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+EXPORT_SYMBOL(samsung_asoc_idma);
+#endif \ No newline at end of file
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
new file mode 100644
index 0000000..8ebb41c
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -0,0 +1,149 @@
+/* linux/arch/arm/plat-samsung/dev-backlight.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common infrastructure for PWM Backlight for Samsung boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/pwm_backlight.h>
+
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/backlight.h>
+
+static int samsung_bl_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_device *timer_dev =
+ container_of(dev->parent, struct platform_device, dev);
+ struct samsung_bl_gpio_info *bl_gpio_info =
+ timer_dev->dev.platform_data;
+
+ ret = gpio_request(bl_gpio_info->no, "Backlight");
+ if (ret) {
+ printk(KERN_ERR "failed to request GPIO for LCD Backlight\n");
+ return ret;
+ }
+
+ /* Configure GPIO pin with specific GPIO function for PWM timer */
+ s3c_gpio_cfgpin(bl_gpio_info->no, bl_gpio_info->func);
+
+ return 0;
+}
+
+static void samsung_bl_exit(struct device *dev)
+{
+ struct platform_device *timer_dev =
+ container_of(dev->parent, struct platform_device, dev);
+ struct samsung_bl_gpio_info *bl_gpio_info =
+ timer_dev->dev.platform_data;
+
+ s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT);
+ gpio_free(bl_gpio_info->no);
+}
+
+/* Initialize few important fields of platform_pwm_backlight_data
+ * structure with default values. These fields can be overridden by
+ * board-specific values sent from machine file.
+ * For ease of operation, these fields are initialized with values
+ * used by most samsung boards.
+ * Users has the option of sending info about other parameters
+ * for their specific boards
+ */
+
+static struct platform_pwm_backlight_data samsung_dfl_bl_data = {
+ .max_brightness = 255,
+ .dft_brightness = 255,
+ .pwm_period_ns = 78770,
+ .init = samsung_bl_init,
+ .exit = samsung_bl_exit,
+};
+
+static struct platform_device samsung_dfl_bl_device = {
+ .name = "pwm-backlight",
+};
+
+/* samsung_bl_set - Set board specific data (if any) provided by user for
+ * PWM Backlight control and register specific PWM and backlight device.
+ * @gpio_info: structure containing GPIO info for PWM timer
+ * @bl_data: structure containing Backlight control data
+ */
+void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+ struct platform_pwm_backlight_data *bl_data)
+{
+ int ret = 0;
+ struct platform_device *samsung_bl_device;
+ struct platform_pwm_backlight_data *samsung_bl_data;
+
+ samsung_bl_device = kmemdup(&samsung_dfl_bl_device,
+ sizeof(struct platform_device), GFP_KERNEL);
+ if (!samsung_bl_device) {
+ printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
+ return;
+ }
+
+ samsung_bl_data = s3c_set_platdata(&samsung_dfl_bl_data,
+ sizeof(struct platform_pwm_backlight_data), samsung_bl_device);
+ if (!samsung_bl_data) {
+ printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
+ goto err_data;
+ }
+
+ /* Copy board specific data provided by user */
+ samsung_bl_data->pwm_id = bl_data->pwm_id;
+ samsung_bl_device->dev.parent =
+ &s3c_device_timer[samsung_bl_data->pwm_id].dev;
+
+ if (bl_data->max_brightness)
+ samsung_bl_data->max_brightness = bl_data->max_brightness;
+ if (bl_data->dft_brightness)
+ samsung_bl_data->dft_brightness = bl_data->dft_brightness;
+ if (bl_data->lth_brightness)
+ samsung_bl_data->lth_brightness = bl_data->lth_brightness;
+ if (bl_data->pwm_period_ns)
+ samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns;
+ if (bl_data->init)
+ samsung_bl_data->init = bl_data->init;
+ if (bl_data->notify)
+ samsung_bl_data->notify = bl_data->notify;
+ if (bl_data->exit)
+ samsung_bl_data->exit = bl_data->exit;
+ if (bl_data->check_fb)
+ samsung_bl_data->check_fb = bl_data->check_fb;
+
+ /* Keep the GPIO info for future use */
+ s3c_device_timer[samsung_bl_data->pwm_id].dev.platform_data = gpio_info;
+
+ /* Register the specific PWM timer dev for Backlight control */
+ ret = platform_device_register(
+ &s3c_device_timer[samsung_bl_data->pwm_id]);
+ if (ret) {
+ printk(KERN_ERR "failed to register pwm timer for backlight: %d\n", ret);
+ goto err_plat_reg1;
+ }
+
+ /* Register the Backlight dev */
+ ret = platform_device_register(samsung_bl_device);
+ if (ret) {
+ printk(KERN_ERR "failed to register backlight device: %d\n", ret);
+ goto err_plat_reg2;
+ }
+
+ return;
+
+err_plat_reg2:
+ platform_device_unregister(&s3c_device_timer[samsung_bl_data->pwm_id]);
+err_plat_reg1:
+ kfree(samsung_bl_data);
+err_data:
+ kfree(samsung_bl_device);
+ return;
+}
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
index bf60204..49a1362 100644
--- a/arch/arm/plat-samsung/dev-fb.c
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -58,16 +58,6 @@ struct platform_device s3c_device_fb = {
void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
{
- struct s3c_fb_platdata *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_fb.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s3c_device_fb);
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index db7a65c..e5ee2df 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -65,7 +65,10 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index 2497321..40160c6 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -65,6 +65,7 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
if (pd->max_width)
set->max_width = pd->max_width;
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index f60aedb..27bd631 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -20,6 +20,7 @@
#include <mach/map.h>
#include <plat/sdhci.h>
#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
#define S3C_SZ_HSMMC (0x1000)
@@ -65,8 +66,15 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
+ /* if it uses eint as cd pin, pull up/down value of eint port
+ should be NONE */
+ if (pd->ext_cd_gpio)
+ s3c_gpio_setpull(pd->ext_cd_gpio, S3C_GPIO_PULL_NONE);
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
index ede776f..1973ef4 100644
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -69,6 +69,13 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
+#ifdef CONFIG_MACH_PX
+ set->ext_pdev = pd->ext_pdev;
+#endif
if (pd->max_width)
set->max_width = pd->max_width;
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
index b3ffb95..c91a79c 100644
--- a/arch/arm/plat-samsung/dev-hwmon.c
+++ b/arch/arm/plat-samsung/dev-hwmon.c
@@ -27,16 +27,6 @@ struct platform_device s3c_device_hwmon = {
void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
{
- struct s3c_hwmon_pdata *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_hwmon.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
+ &s3c_device_hwmon);
}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
index 3a601c1..1edd343 100644
--- a/arch/arm/plat-samsung/dev-i2c0.c
+++ b/arch/arm/plat-samsung/dev-i2c0.c
@@ -48,10 +48,10 @@ struct platform_device s3c_device_i2c0 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
+struct s3c2410_platform_i2c default_i2c_data __initdata = {
.flags = 0,
.slave_addr = 0x10,
- .frequency = 100*1000,
+ .frequency = 400*1000,
.sda_delay = 100,
};
@@ -60,13 +60,11 @@ void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
struct s3c2410_platform_i2c *npd;
if (!pd)
- pd = &default_i2c_data0;
+ pd = &default_i2c_data;
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c0_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c0);
- s3c_device_i2c0.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c0_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
index 858ee2a..3b7c7be 100644
--- a/arch/arm/plat-samsung/dev-i2c1.c
+++ b/arch/arm/plat-samsung/dev-i2c1.c
@@ -44,26 +44,18 @@ struct platform_device s3c_device_i2c1 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
- .flags = 0,
- .bus_num = 1,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data1;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 1;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c1);
- s3c_device_i2c1.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c1_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
index ff4ba69..07e9fd0 100644
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -45,26 +45,18 @@ struct platform_device s3c_device_i2c2 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data2 __initdata = {
- .flags = 0,
- .bus_num = 2,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data2;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 2;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c2_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c2);
- s3c_device_i2c2.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c2_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
index 8586a10..d48efa9 100644
--- a/arch/arm/plat-samsung/dev-i2c3.c
+++ b/arch/arm/plat-samsung/dev-i2c3.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c3 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
- .flags = 0,
- .bus_num = 3,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data3;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 3;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c3);
- s3c_device_i2c3.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c3_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
index df2159e..07e2644 100644
--- a/arch/arm/plat-samsung/dev-i2c4.c
+++ b/arch/arm/plat-samsung/dev-i2c4.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c4 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
- .flags = 0,
- .bus_num = 4,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data4;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 4;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c4);
- s3c_device_i2c4.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c4_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
index 0499c2c..f496557 100644
--- a/arch/arm/plat-samsung/dev-i2c5.c
+++ b/arch/arm/plat-samsung/dev-i2c5.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c5 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
- .flags = 0,
- .bus_num = 5,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data5;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 5;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c5);
- s3c_device_i2c5.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c5_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
index 4083108..141d799 100644
--- a/arch/arm/plat-samsung/dev-i2c6.c
+++ b/arch/arm/plat-samsung/dev-i2c6.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c6 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
- .flags = 0,
- .bus_num = 6,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data6;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 6;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c6);
- s3c_device_i2c6.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c6_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
index 1182451..9dddcd1 100644
--- a/arch/arm/plat-samsung/dev-i2c7.c
+++ b/arch/arm/plat-samsung/dev-i2c7.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c7 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
- .flags = 0,
- .bus_num = 7,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data7;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 7;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c7);
- s3c_device_i2c7.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c7_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-mshc.c b/arch/arm/plat-samsung/dev-mshc.c
new file mode 100644
index 0000000..ca2cbf8
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-mshc.c
@@ -0,0 +1,101 @@
+/* linux/arch/arm/plat-samsung/dev-mshc.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Based on arch/arm/plat-samsung/dev-hsmmc1.c
+ *
+ * Device definition for mshc devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/mshci.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/exynos4.h>
+
+#define S5P_SZ_MSHC (0x1000)
+
+static struct resource s3c_mshci_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_DWMCI,
+ .end = EXYNOS_PA_DWMCI + S5P_SZ_MSHC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DWMCI,
+ .end = IRQ_DWMCI,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
+
+struct s3c_mshci_platdata s3c_mshci_def_platdata = {
+ .max_width = 4,
+ .host_caps = (MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_mshci = {
+ .name = "dw_mmc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_mshci_resource),
+ .resource = s3c_mshci_resource,
+ .dev = {
+ .dma_mask = &s3c_device_hsmmc_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ .platform_data = &s3c_mshci_def_platdata,
+ },
+};
+
+
+void s3c_mshci_set_platdata(struct s3c_mshci_platdata *pd)
+{
+ struct s3c_mshci_platdata *set = &s3c_mshci_def_platdata;
+
+ set->cd_type = pd->cd_type;
+ set->ext_cd_init = pd->ext_cd_init;
+ set->ext_cd_cleanup = pd->ext_cd_cleanup;
+ set->ext_cd_gpio = pd->ext_cd_gpio;
+ set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->wp_gpio = pd->wp_gpio;
+ set->has_wp_gpio = pd->has_wp_gpio;
+ set->int_power_gpio = pd->int_power_gpio;
+ if(pd->fifo_depth)
+ set->fifo_depth = pd->fifo_depth;
+ else
+ set->fifo_depth = 0x20; /* exynos4210 size. */
+
+ if (pd->max_width)
+ set->max_width = pd->max_width;
+ if (pd->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->host_caps2)
+ set->host_caps2 |= pd->host_caps2;
+ if (soc_is_exynos4210()) {
+ if (pd->host_caps && samsung_rev() < EXYNOS4210_REV_1_1) {
+ printk(KERN_INFO "MSHC: This exynos4 is EVT1.0. "
+ "Disable DDR R/W for eMMC.\n");
+ set->host_caps &= ~(MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50);
+ }
+ }
+ if (pd->cfg_gpio)
+ set->cfg_gpio = pd->cfg_gpio;
+ if (pd->cfg_card)
+ set->cfg_card = pd->cfg_card;
+ if (pd->cfg_ddr)
+ set->cfg_ddr = pd->cfg_ddr;
+ if (pd->init_card)
+ set->init_card = pd->init_card;
+}
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
index 6927ae8..b8e30ec 100644
--- a/arch/arm/plat-samsung/dev-nand.c
+++ b/arch/arm/plat-samsung/dev-nand.c
@@ -91,11 +91,10 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
* time then there is little chance the system is going to run.
*/
- npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
- if (!npd) {
- printk(KERN_ERR "%s: failed copying platform data\n", __func__);
+ npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
+ &s3c_device_nand);
+ if (!npd)
return;
- }
/* now see if we need to copy any of the nand set data */
@@ -123,6 +122,4 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
to++;
}
}
-
- s3c_device_nand.dev.platform_data = npd;
}
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c
index dab47b0..cda8e47 100644
--- a/arch/arm/plat-samsung/dev-pwm.c
+++ b/arch/arm/plat-samsung/dev-pwm.c
@@ -20,6 +20,7 @@
#include <mach/irqs.h>
#include <plat/devs.h>
+#include <mach/gpio.h>
#define TIMER_RESOURCE_SIZE (1)
@@ -32,22 +33,88 @@
} \
}
-#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
- .name = "s3c24xx-pwm", \
- .id = _tmr_no, \
- .num_resources = TIMER_RESOURCE_SIZE, \
- .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+#define DEFINE_S3C_TIMER(_tmr_no, _irq, _plat_data) \
+ .name = "s3c24xx-pwm", \
+ .id = _tmr_no, \
+ .num_resources = TIMER_RESOURCE_SIZE, \
+ .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+ .dev = { \
+ .platform_data = _plat_data, \
+ }
+
+#define GPD0_0_TOUT (0x2 << 0)
+#ifdef CONFIG_FB_MDNIE_PWM
+#define GPD0_1_TOUT (0x3 << 4)
+#else
+#define GPD0_1_TOUT (0x2 << 4)
+#endif
+#define GPD0_2_TOUT (0x2 << 8)
+#define GPD0_3_TOUT (0x2 << 12)
-/*
- * since we already have an static mapping for the timer,
- * we do not bother setting any IO resource for the base.
+/* since we already have an static mapping for the timer, we do not
+ * bother setting any IO resource for the base.
*/
+struct s3c_pwm_pdata {
+ /* PWM output port */
+ int gpio_no;
+ const char *gpio_name;
+ int gpio_set_value;
+};
+
+struct s3c_pwm_pdata pwm_data[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+ {
+ .gpio_no = EXYNOS5_GPB2(0),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_0_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(1),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_1_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(2),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_2_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(3),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_3_TOUT,
+ }, {
+ .gpio_no = 0,
+ .gpio_name = NULL,
+ .gpio_set_value = 0,
+ }
+#else
+ {
+ .gpio_no = EXYNOS4_GPD0(0),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_0_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(1),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_1_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(2),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_2_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(3),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_3_TOUT,
+ }, {
+ .gpio_no = 0,
+ .gpio_name = NULL,
+ .gpio_set_value = 0,
+ }
+#endif
+};
+
struct platform_device s3c_device_timer[] = {
- [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
- [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
- [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
- [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
- [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+ [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0, &pwm_data[0]) },
+ [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1, &pwm_data[1]) },
+ [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2, &pwm_data[2]) },
+ [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3, &pwm_data[3]) },
+ [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4, &pwm_data[4]) },
};
EXPORT_SYMBOL(s3c_device_timer);
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c
index 3e4bd81..f9af090 100644
--- a/arch/arm/plat-samsung/dev-ts.c
+++ b/arch/arm/plat-samsung/dev-ts.c
@@ -38,23 +38,13 @@ static struct resource s3c_ts_resource[] = {
struct platform_device s3c_device_ts = {
.name = "s3c64xx-ts",
- .id = -1,
+ .id = 0,
.num_resources = ARRAY_SIZE(s3c_ts_resource),
.resource = s3c_ts_resource,
};
void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
{
- struct s3c2410_ts_mach_info *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_ts.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
+ &s3c_device_ts);
}
diff --git a/arch/arm/plat-samsung/dev-ts1.c b/arch/arm/plat-samsung/dev-ts1.c
new file mode 100644
index 0000000..99cc63f
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ts1.c
@@ -0,0 +1,60 @@
+/* linux/arch/arm/plat-samsung/dev-ts1.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * Adapted by Maurus Cuelenaere for s3c64xx
+ *
+ * S3C64XX series device definition for touchscreen device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/ts.h>
+
+static struct resource s3c_ts_resource[] = {
+ [0] = {
+ .start = SAMSUNG_PA_ADC1,
+ .end = SAMSUNG_PA_ADC1 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PEN1,
+ .end = IRQ_PEN1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_ts1 = {
+ .name = "s3c64xx-ts",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_ts_resource),
+ .resource = s3c_ts_resource,
+};
+
+void __init s3c24xx_ts1_set_platdata(struct s3c2410_ts_mach_info *pd)
+{
+ struct s3c2410_ts_mach_info *npd;
+
+ if (!pd) {
+ printk(KERN_ERR "%s: no platform data\n", __func__);
+ return;
+ }
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+ s3c_device_ts1.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c
index 0e0a3bf..33fbaa9 100644
--- a/arch/arm/plat-samsung/dev-usb.c
+++ b/arch/arm/plat-samsung/dev-usb.c
@@ -60,11 +60,6 @@ EXPORT_SYMBOL(s3c_device_ohci);
*/
void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
{
- struct s3c2410_hcd_info *npd;
-
- npd = kmemdup(info, sizeof(struct s3c2410_hcd_info), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_ohci.dev.platform_data = npd;
+ s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
+ &s3c_device_ohci);
}
diff --git a/arch/arm/plat-samsung/dev-usb3-exynos-drd.c b/arch/arm/plat-samsung/dev-usb3-exynos-drd.c
new file mode 100644
index 0000000..6ce72c4
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb3-exynos-drd.c
@@ -0,0 +1,103 @@
+/* arch/arm/plat-samsung/dev-usb3-dwc-drd.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co. Ltd
+ * Author: Anton Tikhomirov <av.tikhomirov@samsung.com>
+ *
+ * Device definition for EXYNOS SuperSpeed USB 3.0 DRD Controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/platform_data/exynos_usb3_drd.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/usb-phy.h>
+
+static struct resource exynos_ss_udc_resources[] = {
+ [0] = {
+ .start = EXYNOS5_PA_SS_DRD,
+ .end = EXYNOS5_PA_SS_DRD + 0x100000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB3_DRD,
+ .end = IRQ_USB3_DRD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource exynos_xhci_resources[] = {
+ [0] = {
+ .start = EXYNOS5_PA_SS_DRD,
+ .end = EXYNOS5_PA_SS_DRD + 0x100000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB3_DRD,
+ .end = IRQ_USB3_DRD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 exynos_ss_udc_dmamask = DMA_BIT_MASK(32);
+static u64 exynos_xhci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_ss_udc = {
+ .name = "exynos-ss-udc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_ss_udc_resources),
+ .resource = exynos_ss_udc_resources,
+ .dev = {
+ .dma_mask = &exynos_ss_udc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device exynos_device_xhci = {
+ .name = "exynos-xhci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_xhci_resources),
+ .resource = exynos_xhci_resources,
+ .dev = {
+ .dma_mask = &exynos_xhci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init exynos_ss_udc_set_platdata(struct exynos_usb3_drd_pdata *pd)
+{
+ struct exynos_usb3_drd_pdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct exynos_usb3_drd_pdata),
+ &exynos_device_ss_udc);
+
+ npd->phy_type = S5P_USB_PHY_DRD;
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+}
+
+void __init exynos_xhci_set_platdata(struct exynos_usb3_drd_pdata *pd)
+{
+ struct exynos_usb3_drd_pdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct exynos_usb3_drd_pdata),
+ &exynos_device_xhci);
+
+ npd->phy_type = S5P_USB_PHY_DRD;
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
index 019b5b8..c9d8f2c 100644
--- a/arch/arm/plat-samsung/dev-wdt.c
+++ b/arch/arm/plat-samsung/dev-wdt.c
@@ -21,7 +21,7 @@
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C_PA_WDT,
- .end = S3C_PA_WDT + SZ_1K,
+ .end = S3C_PA_WDT + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/plat-samsung/dma_m2m_test.c b/arch/arm/plat-samsung/dma_m2m_test.c
new file mode 100644
index 0000000..b1ca128
--- /dev/null
+++ b/arch/arm/plat-samsung/dma_m2m_test.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * MemToMem DMA Xfer Test Driver for S3C DMA API
+ *
+ */
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/dma.h>
+
+#define XFER_UNIT 1024
+
+static unsigned int xfer_size = 256;
+module_param(xfer_size, uint, S_IRUGO);
+MODULE_PARM_DESC(xfer_size, "Size of each DMA enqueue request in KB");
+
+#define DMATEST_BRSTSZ 1
+static unsigned short burst = 1;
+module_param(burst, ushort, S_IRUGO);
+MODULE_PARM_DESC(burst, "For which parts of API to calc performance");
+
+static unsigned short perf_test = 1;
+module_param(perf_test, ushort, S_IRUGO);
+MODULE_PARM_DESC(perf_test, "For which parts of API to calc performance");
+
+static unsigned int sec = 60 * 60; /* 1 hour by default */
+module_param(sec, uint, S_IRUGO);
+MODULE_PARM_DESC(sec, "Number of seconds to run the test (default: 24hr)");
+
+static unsigned int channels = 10000; /* Use all channels by default */
+module_param(channels, uint, S_IRUGO);
+MODULE_PARM_DESC(channels, "Number of channels to test (default: 8)");
+
+struct s3cdma_thread {
+ unsigned id; /* For Channel index */
+ struct task_struct *task;
+#define SRC 0
+#define DST 1
+ void *buff_cpu[2]; /* CPU address of the Source & Destination buffer */
+ dma_addr_t buff_phys[2]; /* Physical address of the Source & Destination buffer */
+ unsigned long jiffies;
+ int stopped;
+ enum s3c2410_dma_buffresult res;
+ int size;
+ unsigned done;
+ struct s3c2410_dma_client cl;
+ struct completion xfer_cmplt;
+ struct list_head node;
+};
+
+static unsigned int delta;
+static unsigned long cycles, maxtime;
+static LIST_HEAD(channel_list);
+
+void s3cdma_cb(struct s3c2410_dma_chan *chan, void *buf_id,
+ int size, enum s3c2410_dma_buffresult res)
+{
+ struct s3cdma_thread *thread = buf_id;
+
+ thread->res = res;
+ thread->size = size;
+
+ complete(&thread->xfer_cmplt);
+}
+
+static void dmatest_init_buf(u32 buf[], int clr, unsigned int bytes)
+{
+ unsigned int i;
+
+ for (i = 0; i < bytes / 4; i++)
+ buf[i] = clr ? 0 : i;
+}
+
+static bool dmatest_buf_same(u32 src[], u32 dst[], unsigned int bytes)
+{
+ unsigned int i;
+
+ for (i = 0; i < (bytes - delta) / 4; i++)
+ if (src[i] != dst[i])
+ return false;
+
+ for (; i < bytes / 4; i++)
+ if (dst[i])
+ return false;
+
+ return true;
+}
+
+static int dmatest_func(void *data)
+{
+ struct s3cdma_thread *thread = data;
+ enum dma_ch chan = DMACH_MTOM_0 + thread->id;
+ unsigned long tout = jiffies + msecs_to_jiffies(sec * 1000);
+ int src_idx = 0;
+ unsigned val;
+
+ thread->jiffies = jiffies;
+ thread->done = 0;
+
+ while (!kthread_should_stop() && time_before(jiffies, tout)) {
+
+ u32 *srcbuf = thread->buff_cpu[src_idx];
+ u32 *dstbuf = thread->buff_cpu[1 - src_idx];
+
+ if (!perf_test) {
+ dmatest_init_buf(srcbuf, 0, xfer_size);
+ dmatest_init_buf(dstbuf, 1, xfer_size);
+ delta = 1024;
+ }
+
+ s3c2410_dma_devconfig(chan, S3C_DMA_MEM2MEM,
+ thread->buff_phys[src_idx]);
+
+ s3c2410_dma_enqueue(chan, (void *)thread,
+ thread->buff_phys[1 - src_idx], xfer_size - delta);
+
+ s3c2410_dma_ctrl(chan, S3C2410_DMAOP_START);
+
+ val = wait_for_completion_timeout(&thread->xfer_cmplt, msecs_to_jiffies(5*1000));
+ if (!val) {
+ dma_addr_t src, dst;
+ s3c2410_dma_getposition(DMACH_MTOM_0 + thread->id,
+ &src, &dst);
+
+ printk("\n%s:%d Thrd-%u Done-%u <%x,%x>/<%x,%x>\n",
+ __func__, __LINE__, thread->id, thread->done,
+ src, dst, thread->buff_phys[src_idx], thread->buff_phys[1 - src_idx]);
+ break;
+ }
+
+ if (thread->res != S3C2410_RES_OK
+ || thread->size != xfer_size - delta) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u: Cycle-%u Res-%u Xfer_size-%d!\n",
+ thread->id, thread->done, thread->res, thread->size);
+ } else {
+ thread->done++;
+ }
+
+ if (!perf_test &&
+ !dmatest_buf_same(srcbuf, dstbuf, xfer_size)) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u: Cycle-%u Xfer_cmp failed!\n",
+ thread->id, thread->done);
+ break;
+ }
+
+ src_idx = 1 - src_idx;
+ }
+
+ thread->jiffies = jiffies - thread->jiffies;
+
+ thread->stopped = 1;
+
+ return 0;
+}
+
+static int __init dmatest_init(void)
+{
+ struct s3cdma_thread *thread;
+ int ret, i = 0;
+
+ xfer_size *= XFER_UNIT;
+
+ if (sec < 5) {
+ sec = 5;
+ printk(KERN_INFO "S3C DMA M2M Test: Using 5secs test time\n");
+ }
+
+ while (i < 10) {
+ if (burst == (1 << i))
+ break;
+ i++;
+ }
+ /* If invalid burst value provided */
+ if (i == 10) {
+ burst = 1;
+ printk(KERN_INFO "S3C DMA M2M Test: Using 1 burst size\n");
+ }
+
+ for (i = 0; i < channels; i++) {
+ thread = kzalloc(sizeof(struct s3cdma_thread), GFP_KERNEL);
+ if (!thread) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u No memory for channel\n", i);
+ goto thrd_alloc_err;
+ }
+
+ thread->buff_cpu[SRC] = dma_alloc_coherent(NULL, xfer_size,
+ &thread->buff_phys[SRC], GFP_KERNEL);
+ if (!thread->buff_cpu[SRC]) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u No memory for src buff\n", i);
+ goto src_alloc_err;
+ }
+
+ thread->buff_cpu[DST] = dma_alloc_coherent(NULL, xfer_size,
+ &thread->buff_phys[DST], GFP_KERNEL);
+ if (!thread->buff_cpu[DST]) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u No memory for dst buff\n", i);
+ goto dst_alloc_err;
+ }
+
+ dmatest_init_buf(thread->buff_cpu[SRC], 0, xfer_size);
+ dmatest_init_buf(thread->buff_cpu[DST], 1, xfer_size);
+
+ thread->id = i;
+ thread->cl.name = (char *) thread;
+ thread->stopped = 0;
+
+ init_completion(&thread->xfer_cmplt);
+
+ ret = s3c2410_dma_request(DMACH_MTOM_0 + thread->id,
+ &thread->cl, NULL);
+ if (ret) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%d acq(%d)\n", i, ret);
+ goto thrd_dma_acq_err;
+ }
+
+ s3c2410_dma_set_buffdone_fn(DMACH_MTOM_0 + thread->id, s3cdma_cb);
+
+ ret = s3c2410_dma_config(DMACH_MTOM_0 + thread->id, burst);
+ if (ret) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%d config(%d)\n", i, ret);
+ goto thrd_dma_cfg_err;
+ }
+
+ thread->task = kthread_run(dmatest_func, thread,
+ "dma-m2m-test%u", i);
+ if (IS_ERR(thread->task)) {
+ printk(KERN_INFO "S3C DMA M2M Test: Failed to run thread dma-m2m-test%u\n", i);
+ goto thrd_run_err;
+ }
+
+ list_add_tail(&thread->node, &channel_list);
+
+ continue;
+
+thrd_run_err:
+thrd_dma_cfg_err:
+ s3c2410_dma_free(DMACH_MTOM_0 + thread->id, &thread->cl);
+thrd_dma_acq_err:
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[DST], thread->buff_phys[DST]);
+dst_alloc_err:
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[SRC], thread->buff_phys[SRC]);
+src_alloc_err:
+ kfree(thread);
+thrd_alloc_err:
+ break;
+ }
+
+ printk(KERN_INFO "S3C DMA M2M Test: Testing with %u Channels\n", i);
+
+ return 0;
+}
+module_init(dmatest_init);
+
+static void __exit dmatest_exit(void)
+{
+ struct s3cdma_thread *thread;
+
+ while (!list_empty(&channel_list)) {
+ thread = list_entry(channel_list.next,
+ struct s3cdma_thread, node);
+
+ list_del(&thread->node);
+
+ if (perf_test && !dmatest_buf_same(thread->buff_cpu[SRC],
+ thread->buff_cpu[DST], xfer_size))
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u: Xfer_cmp failed!\n", thread->id);
+
+ if (!thread->stopped)
+ kthread_stop(thread->task);
+
+ if (jiffies_to_msecs(thread->jiffies) > maxtime)
+ maxtime = jiffies_to_msecs(thread->jiffies);
+
+ cycles += thread->done;
+
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u %ux%u Kb in %ums\n",
+ thread->id, thread->done, xfer_size / XFER_UNIT,
+ jiffies_to_msecs(thread->jiffies));
+
+ s3c2410_dma_free(DMACH_MTOM_0 + thread->id, &thread->cl);
+
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[DST], thread->buff_phys[DST]);
+
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[SRC], thread->buff_phys[SRC]);
+
+ kfree(thread);
+ }
+
+ printk(KERN_INFO "S3C DMA M2M Test: Overall %lux%u Kb in %lums\n",
+ cycles, xfer_size / XFER_UNIT, maxtime);
+ printk(KERN_INFO "S3C DMA M2M Test: %lu MB/Sec\n",
+ cycles * 1000 / maxtime * xfer_size / XFER_UNIT / 1024);
+}
+module_exit(dmatest_exit);
+
+MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("S3C DMA MemToMem Test Driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 1c0b040..712ec09 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -429,3 +429,99 @@ int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
}
EXPORT_SYMBOL(s5p_gpio_set_drvstr);
#endif /* CONFIG_S5P_GPIO_DRVSTR */
+
+s5p_gpio_pd_cfg_t s5p_gpio_get_pd_cfg(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 pd_cfg;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x10;
+
+ pd_cfg = __raw_readl(reg);
+ pd_cfg = pd_cfg >> shift;
+ pd_cfg &= 0x3;
+
+ return (__force s5p_gpio_pd_cfg_t)pd_cfg;
+}
+EXPORT_SYMBOL(s5p_gpio_get_pd_cfg);
+
+int s5p_gpio_set_pd_cfg(unsigned int pin, s5p_gpio_pd_cfg_t pd_cfg)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 tmp;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x10;
+
+ tmp = __raw_readl(reg);
+ tmp &= ~(0x3 << shift);
+ tmp |= pd_cfg << shift;
+
+ __raw_writel(tmp, reg);
+
+ return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_pd_cfg);
+
+s5p_gpio_pd_pull_t s5p_gpio_get_pd_pull(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 pd_pull;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x14;
+
+ pd_pull = __raw_readl(reg);
+ pd_pull = pd_pull >> shift;
+ pd_pull &= 0x3;
+
+ return (__force s5p_gpio_pd_pull_t)pd_pull;
+}
+EXPORT_SYMBOL(s5p_gpio_get_pd_pull);
+
+int s5p_gpio_set_pd_pull(unsigned int pin, s5p_gpio_pd_pull_t pd_pull)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 tmp;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x14;
+
+ tmp = __raw_readl(reg);
+ tmp &= ~(0x3 << shift);
+ tmp |= pd_pull << shift;
+
+ __raw_writel(tmp, reg);
+
+ return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_pd_pull);
diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h
index b258a08..449f409 100644
--- a/arch/arm/plat-samsung/include/plat/adc.h
+++ b/arch/arm/plat-samsung/include/plat/adc.h
@@ -17,7 +17,8 @@
struct s3c_adc_client;
extern int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples);
+ unsigned int channel, unsigned int nr_samples,
+ wait_queue_head_t *pwake);
extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
index a0826ed..bfee644 100644
--- a/arch/arm/plat-samsung/include/plat/audio.h
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -36,6 +36,10 @@ struct samsung_i2s {
*/
#define QUIRK_NO_MUXPSR (1 << 2)
#define QUIRK_NEED_RSTCLR (1 << 3)
+/* If the idma will be enabled */
+#define QUIRK_ENABLED_IDMA (1 << 4)
+/* If the srp will be enabled */
+#define QUIRK_ENABLED_SRP (1 << 5)
/* Quirks of the I2S controller */
u32 quirks;
@@ -56,3 +60,5 @@ struct s3c_audio_pdata {
struct samsung_i2s i2s;
} type;
};
+
+extern void __init exynos4_i2sv3_setup_resource(void);
diff --git a/arch/arm/plat-samsung/include/plat/backlight.h b/arch/arm/plat-samsung/include/plat/backlight.h
new file mode 100644
index 0000000..ad530c7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/backlight.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/plat-samsung/include/plat/backlight.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_BACKLIGHT_H
+#define __ASM_PLAT_BACKLIGHT_H __FILE__
+
+/* samsung_bl_gpio_info - GPIO info for PWM Backlight control
+ * @no: GPIO number for PWM timer out
+ * @func: Special function of GPIO line for PWM timer
+ */
+struct samsung_bl_gpio_info {
+ int no;
+ int func;
+};
+
+extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+ struct platform_pwm_backlight_data *bl_data);
+
+#endif /* __ASM_PLAT_BACKLIGHT_H */
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 983c578..76198a7 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -9,7 +9,11 @@
* published by the Free Software Foundation.
*/
+#ifndef __ASM_PLAT_CLOCK_H
+#define __ASM_PLAT_CLOCK_H __FILE__
+
#include <linux/spinlock.h>
+#include <linux/clkdev.h>
struct clk;
@@ -40,6 +44,7 @@ struct clk {
struct module *owner;
struct clk *parent;
const char *name;
+ const char *devname;
int id;
int usage;
unsigned long rate;
@@ -47,6 +52,7 @@ struct clk {
struct clk_ops *ops;
int (*enable)(struct clk *, int enable);
+ struct clk_lookup lookup;
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */
#endif
@@ -78,6 +84,7 @@ extern struct clk clk_h2;
extern struct clk clk_27m;
extern struct clk clk_48m;
extern struct clk clk_xusbxti;
+extern struct clk clk_xxti;
extern int clk_default_setrate(struct clk *clk, unsigned long rate);
extern struct clk_ops clk_ops_def_setrate;
@@ -118,3 +125,8 @@ extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
extern void s3c_pwmclk_init(void);
+/* Global watchdog clock used by arch_wtd_reset() callback */
+
+extern struct clk *s3c2410_wdtclk;
+
+#endif /* __ASM_PLAT_CLOCK_H */
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index c0a5741..f68c5a6 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -1,9 +1,12 @@
/* linux/arch/arm/plat-samsung/include/plat/cpu.h
*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
* Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * Header file for S3C24XX CPU support
+ * Header file for Samsung CPU support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,6 +18,139 @@
#ifndef __SAMSUNG_PLAT_CPU_H
#define __SAMSUNG_PLAT_CPU_H
+extern unsigned long samsung_cpu_id;
+
+#define S3C24XX_CPU_ID 0x32400000
+#define S3C24XX_CPU_MASK 0xFFF00000
+
+#define S3C6400_CPU_ID 0x36400000
+#define S3C6410_CPU_ID 0x36410000
+#define S3C64XX_CPU_ID (S3C6400_CPU_ID & S3C6410_CPU_ID)
+#define S3C64XX_CPU_MASK 0x1FF40000
+
+#define S5P6440_CPU_ID 0x56440000
+#define S5P6450_CPU_ID 0x36450000
+#define S5P64XX_CPU_MASK 0x1FF40000
+
+#define S5PC100_CPU_ID 0x43100000
+#define S5PC100_CPU_MASK 0xFFFFF000
+
+#define S5PV210_CPU_ID 0x43110000
+#define S5PV210_CPU_MASK 0xFFFFF000
+
+#define EXYNOS4210_CPU_ID 0x43210000
+#define EXYNOS4212_CPU_ID 0x43220000
+#define EXYNOS4412_CPU_ID 0xE4412200
+#define EXYNOS5210_CPU_ID 0x43510000
+#define EXYNOS5250_CPU_ID 0x43520000
+#define EXYNOS_CPU_MASK 0xFFFE0000
+
+#define IS_SAMSUNG_CPU(name, id, mask) \
+static inline int is_samsung_##name(void) \
+{ \
+ return ((samsung_cpu_id & mask) == (id & mask)); \
+}
+
+IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c64xx, S3C64XX_CPU_ID, S3C64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK)
+IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5210, EXYNOS5210_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_CPU_ID, EXYNOS_CPU_MASK)
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+ defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
+ defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
+ defined(CONFIG_CPU_S3C2443)
+# define soc_is_s3c24xx() is_samsung_s3c24xx()
+#else
+# define soc_is_s3c24xx() 0
+#endif
+
+#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
+# define soc_is_s3c64xx() is_samsung_s3c64xx()
+#else
+# define soc_is_s3c64xx() 0
+#endif
+
+#if defined(CONFIG_CPU_S5P6440)
+# define soc_is_s5p6440() is_samsung_s5p6440()
+#else
+# define soc_is_s5p6440() 0
+#endif
+
+#if defined(CONFIG_CPU_S5P6450)
+# define soc_is_s5p6450() is_samsung_s5p6450()
+#else
+# define soc_is_s5p6450() 0
+#endif
+
+#if defined(CONFIG_CPU_S5PC100)
+# define soc_is_s5pc100() is_samsung_s5pc100()
+#else
+# define soc_is_s5pc100() 0
+#endif
+
+#if defined(CONFIG_CPU_S5PV210)
+# define soc_is_s5pv210() is_samsung_s5pv210()
+#else
+# define soc_is_s5pv210() 0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+# define soc_is_exynos4210() is_samsung_exynos4210()
+#else
+# define soc_is_exynos4210() 0
+#endif
+
+#define EXYNOS4210_REV_0 (0x0)
+#define EXYNOS4210_REV_1_0 (0x10)
+#define EXYNOS4210_REV_1_1 (0x11)
+#define EXYNOS4210_REV_1_2 (0x12)
+
+#if defined(CONFIG_CPU_EXYNOS4212)
+# define soc_is_exynos4212() is_samsung_exynos4212()
+#else
+# define soc_is_exynos4212() 0
+#endif
+
+#define EXYNOS4212_REV_0 (0x0)
+#define EXYNOS4212_REV_1_0 (0x10)
+
+#if defined(CONFIG_CPU_EXYNOS4412)
+# define soc_is_exynos4412() is_samsung_exynos4412()
+#else
+# define soc_is_exynos4412() 0
+#endif
+
+#define EXYNOS4412_REV_0 (0x0)
+#define EXYNOS4412_REV_0_1 (0x01)
+#define EXYNOS4412_REV_1_0 (0x10)
+#define EXYNOS4412_REV_1_1 (0x11)
+
+#if defined(CONFIG_CPU_EXYNOS5210)
+# define soc_is_exynos5210() is_samsung_exynos5210()
+#else
+# define soc_is_exynos5210() 0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS5250)
+# define soc_is_exynos5250() is_samsung_exynos5250()
+# define soc_is_exynos5250_rev1 (soc_is_exynos5250() && \
+ samsung_rev() >= EXYNOS5250_REV_1_0)
+#else
+# define soc_is_exynos5250() 0
+# define soc_is_exynos5250_rev1 0
+#endif
+
+#define EXYNOS5250_REV_0 (0x0)
+#define EXYNOS5250_REV_1_0 (0x10)
+
#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
#ifndef MHZ
@@ -55,6 +191,12 @@ extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
extern void s5p_init_io(struct map_desc *mach_desc,
int size, void __iomem *cpuid_addr);
+extern void s3c24xx_init_cpu(void);
+extern void s3c64xx_init_cpu(void);
+extern void s5p_init_cpu(void __iomem *cpuid_addr);
+
+extern unsigned int samsung_rev(void);
+
extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c24xx_init_clocks(int xtal);
@@ -88,6 +230,7 @@ extern struct sysdev_class s3c64xx_sysclass;
extern struct sysdev_class s5p64x0_sysclass;
extern struct sysdev_class s5pv210_sysclass;
extern struct sysdev_class exynos4_sysclass;
+extern struct sysdev_class exynos5_sysclass;
extern void (*s5pc1xx_idle)(void);
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index e3b31c2..1321d7b 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -17,6 +17,7 @@
#define __PLAT_DEVS_H __FILE__
#include <linux/platform_device.h>
+#include <linux/platform_data/exynos_usb3_drd.h>
struct s3c24xx_uart_resources {
struct resource *resources;
@@ -40,6 +41,7 @@ extern struct platform_device s3c64xx_device_spi0;
extern struct platform_device s3c64xx_device_spi1;
extern struct platform_device samsung_asoc_dma;
+extern struct platform_device samsung_asoc_idma;
extern struct platform_device s3c64xx_device_pcm0;
extern struct platform_device s3c64xx_device_pcm1;
@@ -47,8 +49,16 @@ extern struct platform_device s3c64xx_device_pcm1;
extern struct platform_device s3c64xx_device_ac97;
extern struct platform_device s3c_device_ts;
+extern struct platform_device s3c_device_ts1;
extern struct platform_device s3c_device_fb;
+#ifdef CONFIG_FB_S5P_EXTDSP
+extern struct platform_device s3c_device_extdsp;
+#endif
+extern struct platform_device s5p_device_fimd0;
+extern struct platform_device s5p_device_fimd1;
+extern struct platform_device s5p_device_mipi_dsim0;
+extern struct platform_device s5p_device_mipi_dsim1;
extern struct platform_device s3c_device_ohci;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
@@ -60,6 +70,7 @@ extern struct platform_device s3c_device_i2c4;
extern struct platform_device s3c_device_i2c5;
extern struct platform_device s3c_device_i2c6;
extern struct platform_device s3c_device_i2c7;
+extern struct platform_device s5p_device_i2c_hdmiphy;
extern struct platform_device s3c_device_rtc;
extern struct platform_device s3c_device_adc;
extern struct platform_device s3c_device_sdi;
@@ -69,6 +80,7 @@ extern struct platform_device s3c_device_hsmmc0;
extern struct platform_device s3c_device_hsmmc1;
extern struct platform_device s3c_device_hsmmc2;
extern struct platform_device s3c_device_hsmmc3;
+extern struct platform_device s3c_device_mshci;
extern struct platform_device s3c_device_cfcon;
extern struct platform_device s3c_device_spi0;
@@ -81,6 +93,9 @@ extern struct platform_device s5pv210_device_spi0;
extern struct platform_device s5pv210_device_spi1;
extern struct platform_device s5p64x0_device_spi0;
extern struct platform_device s5p64x0_device_spi1;
+extern struct platform_device exynos_device_spi0;
+extern struct platform_device exynos_device_spi1;
+extern struct platform_device exynos_device_spi2;
extern struct platform_device s3c_device_hwmon;
@@ -92,6 +107,13 @@ extern struct platform_device s5p_device_onenand;
extern struct platform_device s3c_device_usbgadget;
extern struct platform_device s3c_device_usb_hsudc;
extern struct platform_device s3c_device_usb_hsotg;
+extern struct platform_device s3c_device_usb_hsudc;
+extern struct platform_device s3c_device_android_usb;
+extern struct platform_device s3c_device_usb_mass_storage;
+#ifdef CONFIG_USB_ANDROID_RNDIS
+extern struct platform_device s3c_device_rndis;
+#endif
+extern struct platform_device s5p_device_usbswitch;
extern struct platform_device s5pv210_device_ac97;
extern struct platform_device s5pv210_device_pcm0;
@@ -101,17 +123,45 @@ extern struct platform_device s5pv210_device_iis0;
extern struct platform_device s5pv210_device_iis1;
extern struct platform_device s5pv210_device_iis2;
extern struct platform_device s5pv210_device_spdif;
-
-extern struct platform_device exynos4_device_ac97;
-extern struct platform_device exynos4_device_pcm0;
-extern struct platform_device exynos4_device_pcm1;
-extern struct platform_device exynos4_device_pcm2;
-extern struct platform_device exynos4_device_i2s0;
-extern struct platform_device exynos4_device_i2s1;
-extern struct platform_device exynos4_device_i2s2;
-extern struct platform_device exynos4_device_spdif;
+extern struct platform_device s5pv210_device_cpufreq;
+extern struct platform_device s5pv210_device_pdma0;
+extern struct platform_device s5pv210_device_pdma1;
+extern struct platform_device s5pv210_device_mdma;
+
+extern struct platform_device exynos_device_ac97;
+extern struct platform_device exynos_device_pcm0;
+extern struct platform_device exynos_device_pcm1;
+extern struct platform_device exynos_device_pcm2;
+extern struct platform_device exynos_device_i2s0;
+extern struct platform_device exynos_device_i2s1;
+extern struct platform_device exynos_device_i2s2;
+extern struct platform_device exynos_device_spdif;
+extern struct platform_device exynos_device_srp;
extern struct platform_device exynos4_device_pd[];
extern struct platform_device exynos4_device_ahci;
+extern struct platform_device exynos_device_pdma0;
+extern struct platform_device exynos_device_pdma1;
+extern struct platform_device exynos_device_mdma;
+extern struct platform_device exynos_device_dwmci;
+extern struct platform_device exynos_device_dwmci0;
+extern struct platform_device exynos_device_dwmci1;
+extern struct platform_device exynos_device_dwmci2;
+extern struct platform_device exynos_device_dwmci3;
+extern struct platform_device exynos_device_flite0;
+extern struct platform_device exynos_device_flite1;
+extern struct platform_device exynos4_device_c2c;
+extern struct platform_device exynos_device_flite2;
+extern struct platform_device exynos4_device_fimc_is;
+extern struct platform_device exynos5_device_fimc_is;
+extern struct platform_device exynos5_device_pd[];
+extern struct platform_device exynos5_device_gsc0;
+extern struct platform_device exynos5_device_gsc1;
+extern struct platform_device exynos5_device_gsc2;
+extern struct platform_device exynos5_device_gsc3;
+extern struct platform_device exynos5_device_ahci;
+extern struct platform_device exynos_device_c2c;
+extern struct platform_device exynos_device_ss_udc;
+extern struct platform_device exynos_device_xhci;
extern struct platform_device s5p6440_device_pcm;
extern struct platform_device s5p6440_device_iis;
@@ -130,18 +180,57 @@ extern struct platform_device s5pc100_device_iis2;
extern struct platform_device s5pc100_device_spdif;
extern struct platform_device samsung_device_keypad;
-
+#ifndef CONFIG_VIDEO_FIMC
extern struct platform_device s5p_device_fimc0;
extern struct platform_device s5p_device_fimc1;
extern struct platform_device s5p_device_fimc2;
extern struct platform_device s5p_device_fimc3;
-
+#else
+extern struct platform_device s3c_device_fimc0;
+extern struct platform_device s3c_device_fimc1;
+extern struct platform_device s3c_device_fimc2;
+extern struct platform_device s3c_device_fimc3;
+#endif
+#ifndef CONFIG_VIDEO_FIMC_MIPI
extern struct platform_device s5p_device_mipi_csis0;
extern struct platform_device s5p_device_mipi_csis1;
+#else
+extern struct platform_device s3c_device_csis0;
+extern struct platform_device s3c_device_csis1;
+#endif
+extern struct platform_device s5p_device_dp;
+
+extern struct platform_device s5p_device_jpeg;
+extern struct platform_device s5p_device_tvout;
+extern struct platform_device s5p_device_cec;
+extern struct platform_device s5p_device_hpd;
+extern struct platform_device s5p_device_ace;
+extern struct platform_device s5p_device_fimg2d;
+extern struct platform_device exynos_device_rotator;
extern struct platform_device s5p_device_ehci;
+extern struct platform_device s5p_device_ohci;
+#ifdef CONFIG_USB_HOST_NOTIFY
+extern struct platform_device host_notifier_device;
+#endif
-extern struct platform_device exynos4_device_sysmmu;
+extern struct platform_device exynos_device_sysmmu[];
+
+extern struct platform_device s5p_device_mfc;
+extern struct platform_device s5p_device_mipi_dsim;
+extern struct platform_device s5p_device_dsim;
+
+extern struct platform_device s5p_device_hdmi;
+extern struct platform_device s5p_device_mixer;
+extern struct platform_device s5p_device_sdo;
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+extern struct platform_device s5p_device_dsim;
+#endif
+
+#ifdef CONFIG_SENSORS_EXYNOS4_TMU
+extern struct platform_device exynos4_device_tmu;
+#endif
/* s3c2440 specific devices */
@@ -152,6 +241,13 @@ extern struct platform_device s3c_device_ac97;
#endif
+#if defined(CONFIG_VIDEO_TSI)
+extern struct platform_device s3c_device_tsi;
+#endif
+
+extern void exynos_ss_udc_set_platdata(struct exynos_usb3_drd_pdata *pd);
+extern void exynos_xhci_set_platdata(struct exynos_usb3_drd_pdata *pd);
+
/**
* s3c_set_platdata() - helper for setting platform data
* @pd: The default platform data for this device.
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
index 8c273b7..816d505 100644
--- a/arch/arm/plat-samsung/include/plat/dma.h
+++ b/arch/arm/plat-samsung/include/plat/dma.h
@@ -18,7 +18,9 @@ enum s3c2410_dma_buffresult {
enum s3c2410_dmasrc {
S3C2410_DMASRC_HW, /* source is memory */
- S3C2410_DMASRC_MEM /* source is hardware */
+ S3C2410_DMASRC_MEM, /* source is hardware */
+ S3C_DMA_MEM2MEM,
+ S3C_DMA_MEM2MEM_SET,
};
/* enum s3c2410_chan_op
@@ -96,8 +98,18 @@ extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *);
* drained before the buffer is given to the DMA system.
*/
-extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
- dma_addr_t data, int size);
+#define s3c2410_dma_enqueue(id, token, addr, size) \
+ s3c2410_dma_enqueue_ring(id, token, addr, size, 0)
+
+/* s3c2410_dma_enqueue_ring
+ *
+ * place the given buffer onto the queue of operations for the channel.
+ * The buffer must be allocated from dma coherent memory, or the Dcache/WB
+ * drained before the buffer is given to the DMA system.
+*/
+
+extern int s3c2410_dma_enqueue_ring(enum dma_ch channel, void *id,
+ dma_addr_t data, int size, int numofblock);
/* s3c2410_dma_config
*
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..4335840 100644
--- a/arch/arm/plat-samsung/include/plat/fb-core.h
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,25 @@ static inline void s3c_fb_setname(char *name)
#endif
}
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+ switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+ case 0:
+ s5p_device_fimd0.name = name;
+ break;
+#endif
+
+#ifdef CONFIG_S5P_DEV_FIMD1
+ case 1:
+ s5p_device_fimd1.name = name;
+ break;
+#endif
+ default:
+ printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+ break;
+ }
+}
+
#endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..2e1813f 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -15,6 +15,8 @@
#ifndef __PLAT_S3C_FB_H
#define __PLAT_S3C_FB_H __FILE__
+#include <plat/gpio-cfg.h>
+
/* S3C_FB_MAX_WIN
* Set to the maximum number of windows that any of the supported hardware
* can use. Since the platform data uses this for an array size, having it
@@ -22,11 +24,28 @@
*/
#define S3C_FB_MAX_WIN (5)
+#if defined(CONFIG_MACH_P11) || defined(CONFIG_MACH_P10)
+/* IOCTL commands */
+#define S3CFB_WIN_POSITION _IOW('F', 203, \
+ struct s3c_fb_user_window)
+#define S3CFB_WIN_SET_PLANE_ALPHA _IOW('F', 204, \
+ struct s3c_fb_user_plane_alpha)
+#define S3CFB_WIN_SET_CHROMA _IOW('F', 205, \
+ struct s3c_fb_user_chroma)
+#define S3CFB_SET_VSYNC_INT _IOW('F', 206, u32)
+
+#define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208, \
+ struct s3c_fb_user_ion_client)
+#define S3CFB_PAN_DISPLAY_INDEX _IOW('F', 209, __u32)
+
+#endif
/**
* struct s3c_fb_pd_win - per window setup data
* @win_mode: The display parameters to initialise (not for window 0)
* @virtual_x: The virtual X size.
* @virtual_y: The virtual Y size.
+ * @width: The width of display in mm
+ * @height: The height of display in mm
*/
struct s3c_fb_pd_win {
struct fb_videomode win_mode;
@@ -35,6 +54,8 @@ struct s3c_fb_pd_win {
unsigned short max_bpp;
unsigned short virtual_x;
unsigned short virtual_y;
+ unsigned short width;
+ unsigned short height;
};
/**
@@ -74,6 +95,22 @@ struct s3c_fb_platdata {
extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
/**
+ * s5p_fimd0_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
+ * s5p_fimd1_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd1_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
* s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
*
* Initialise the GPIO for an 24bpp LCD display on the RGB interface.
@@ -94,4 +131,30 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
*/
extern void s5pv210_fb_gpio_setup_24bpp(void);
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
+/**
+ * exynos4_fimd_cfg_gpios() - Exynos4 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void exynos4_fimd_cfg_gpios(unsigned int base, unsigned int nr,
+ unsigned int cfg, s5p_gpio_drvstr_t drvstr);
+
+/**
+ * exynos4_fimd0_setup_clock() = Exynos4 setup function for parent clock.
+ * @dev: device pointer
+ * @parent: parent clock used for LCD pixel clock
+ * @clk_rate: clock rate for parent clock
+ */
+int __init exynos4_fimd0_setup_clock(struct device *dev, const char *parent,
+ unsigned long clk_rate);
+
+int __init exynos4_fimd_setup_clock(struct device *dev, const char *bus_clk,
+ const char *parent, unsigned long clk_rate);
#endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-samsung/include/plat/fimd_lite_ext.h b/arch/arm/plat-samsung/include/plat/fimd_lite_ext.h
new file mode 100644
index 0000000..b4e131a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fimd_lite_ext.h
@@ -0,0 +1,99 @@
+/* linux/arch/arm/plat/mdnie_ext.h
+ *
+ * Samsung SoC FIMD Extension Framework Header.
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct s5p_fimd_ext_device;
+
+#define fimd_ext_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
+#define fimd_ext_set_drvdata(_dev, data) dev_set_drvdata(&(_dev)->dev, (data))
+
+struct s5p_fimd_dynamic_refresh {
+ void __iomem *regs;
+ unsigned int dynamic_refresh;
+ unsigned int clkdiv;
+};
+
+/**
+ * driver structure for fimd extension based driver.
+ *
+ * this structure should be registered by any extension driver.
+ * fimd extension driveer seeks a driver registered through name field
+ * and calls these callback functions in appropriate time.
+ */
+struct s5p_fimd_ext_driver {
+ struct device_driver driver;
+
+ void (*change_clock)(struct s5p_fimd_dynamic_refresh *fimd_refresh,
+ struct s5p_fimd_ext_device *fx_dev);
+ void (*set_clock)(struct s5p_fimd_ext_device *fx_dev);
+ int (*setup)(struct s5p_fimd_ext_device *fx_dev,
+ unsigned int enable);
+ void (*power_on)(struct s5p_fimd_ext_device *fx_dev);
+ void (*power_off)(struct s5p_fimd_ext_device *fx_dev);
+ int (*start)(struct s5p_fimd_ext_device *fx_dev);
+ void (*stop)(struct s5p_fimd_ext_device *fx_dev);
+ int (*probe)(struct s5p_fimd_ext_device *fx_dev);
+ int (*remove)(struct s5p_fimd_ext_device *fx_dev);
+ int (*suspend)(struct s5p_fimd_ext_device *fx_dev);
+ int (*resume)(struct s5p_fimd_ext_device *fx_dev);
+};
+
+/**
+ * device structure for fimd extension based driver.
+ *
+ * @name: platform device name.
+ * @dev: driver model representation of the device.
+ * @id: id of device registered and when device is registered
+ * id would be counted.
+ * @num_resources: hardware resource count.
+ * @resource: a pointer to hardware resource definitions.
+ * @modalias: name of the driver to use with the device, or an
+ * alias for that name.
+ */
+struct s5p_fimd_ext_device {
+ char *name;
+ struct device dev;
+ int id;
+ unsigned int num_resources;
+ struct resource *resource;
+ bool mdnie_enabled;
+ bool enabled;
+};
+
+struct mdnie_platform_data {
+ unsigned int width;
+ unsigned int height;
+};
+
+/* workaround: fix it later */
+void s6e8aa0_panel_cond(int high_freq);
+
+#ifdef CONFIG_MDNIE_SUPPORT
+/**
+ * register extension driver to fimd extension framework.
+ */
+int s5p_fimd_ext_register(struct s5p_fimd_ext_driver *fx_drv);
+int s5p_fimd_ext_device_register(struct s5p_fimd_ext_device *fx_dev);
+
+/**
+ * find a driver object registered to fimd extension framework.
+ */
+struct s5p_fimd_ext_device *s5p_fimd_ext_find_device(const char *name);
+
+/**
+ * convert device driver object to fimd extension device.
+ */
+struct s5p_fimd_ext_driver *to_fimd_ext_driver(struct device_driver *drv);
+#else
+#define s5p_fimd_ext_register(dev) NULL
+#define s5p_fimd_ext_device_register(dev) NULL
+#define s5p_fimd_ext_find_device(name) NULL
+#define to_fimd_ext_driver(drv) NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1762dcb..943789c 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -26,6 +26,8 @@
typedef unsigned int __bitwise__ s3c_gpio_pull_t;
typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
+typedef unsigned int __bitwise__ s5p_gpio_pd_cfg_t;
+typedef unsigned int __bitwise__ s5p_gpio_pd_pull_t;
/* forward declaration if gpio-core.h hasn't been included */
struct s3c_gpio_chip;
@@ -125,12 +127,30 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
*
* These values control the state of the weak pull-{up,down} resistors
* available on most pins on the S3C series. Not all chips support both
- * up or down settings, and it may be dependent on the chip that is being
+ * up or down settings, and it may be dependant on the chip that is being
* used to whether the particular mode is available.
*/
+#if defined(CONFIG_ARCH_S5PV310) || defined(CONFIG_ARCH_EXYNOS)
+#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x03)
+#else
#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02)
+#endif
+
+#if defined(CONFIG_ARCH_S5PV310) || defined(CONFIG_ARCH_EXYNOS)
+/* need to move to mach/gpio.h */
+#define S3C_GPIO_SLP_OUT0 ((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_SLP_OUT1 ((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_SLP_INPUT ((__force s3c_gpio_pull_t)0x02)
+#define S3C_GPIO_SLP_PREV ((__force s3c_gpio_pull_t)0x03)
+
+#define S3C_GPIO_SETPIN_ZERO 0
+#define S3C_GPIO_SETPIN_ONE 1
+#define S3C_GPIO_SETPIN_NONE 2
+#endif
/**
* s3c_gpio_setpull() - set the state of a gpio pin pull resistor
@@ -207,6 +227,65 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
*/
extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
+/* Define values for the power down configuration available for each gpio pin.
+ *
+ * These values control the state of the power down configuration resistors
+ * available on most pins on the S5P series.
+ */
+#define S5P_GPIO_PD_OUTPUT0 ((__force s5p_gpio_pd_cfg_t)0x00)
+#define S5P_GPIO_PD_OUTPUT1 ((__force s5p_gpio_pd_cfg_t)0x01)
+#define S5P_GPIO_PD_INPUT ((__force s5p_gpio_pd_cfg_t)0x02)
+#define S5P_GPIO_PD_PREV_STATE ((__force s5p_gpio_pd_cfg_t)0x03)
+
+/**
+ * s5p_gpio_set_pd_cfg() - set the configuration of a gpio power down mode
+ * @pin: The pin number to configure the pull resistor.
+ * @pd_cfg: The configuration for the pwer down mode configuration register.
+ *
+ * This function sets the configuration of the power down mode resistor for the
+ * specified pin. It will return 0 if successful, or a negative error
+ * code if the pin cannot support the requested power down mode.
+ *
+*/
+extern int s5p_gpio_set_pd_cfg(unsigned int pin, s5p_gpio_pd_cfg_t pd_cfg);
+
+/**
+ * s5p_gpio_get_pd_cfg() - get the power down mode configuration of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the power down mode resistor value for the specified pin.
+*/
+extern s5p_gpio_pd_cfg_t s5p_gpio_get_pd_cfg(unsigned int pin);
+
+/* Define values for the power down pull-{up,down} available for each gpio pin.
+ *
+ * These values control the state of the power down mode pull-{up,down}
+ * resistors available on most pins on the S5P series.
+ */
+#define S5P_GPIO_PD_UPDOWN_DISABLE ((__force s5p_gpio_pd_pull_t)0x00)
+#define S5P_GPIO_PD_DOWN_ENABLE ((__force s5p_gpio_pd_pull_t)0x01)
+#define S5P_GPIO_PD_UP_ENABLE ((__force s5p_gpio_pd_pull_t)0x03)
+
+/**
+ * s5p_gpio_set_pd_pull() - set the pull-{up,down} of a gpio pin power down mode
+ * @pin: The pin number to configure the pull resistor.
+ * @pd_pull: The configuration for the power down mode pull resistor.
+ *
+ * This function sets the configuration of the pull-{up,down} resistor for the
+ * specified pin. It will return 0 if successful, or a negative error
+ * code if the pin cannot support the requested pull setting.
+ *
+*/
+extern int s5p_gpio_set_pd_pull(unsigned int pin, s5p_gpio_pd_pull_t pd_pull);
+
+/**
+ * s5p_gpio_get_pd_pull() - get the power down pull resistor config of gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the power mode pull resistor value for the specified pin.
+*/
+extern s5p_gpio_pd_pull_t s5p_gpio_get_pd_pull(unsigned int pin);
+
/**
* s5p_register_gpio_interrupt() - register interrupt support for a gpio group
* @pin: The pin number from the group to be registered
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 8cad4cf..792fdb0 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -67,7 +67,8 @@ struct s3c_gpio_chip {
void __iomem *base;
int irq_base;
int group;
- spinlock_t lock;
+ unsigned int eint_offset;
+ spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
#endif
@@ -116,6 +117,8 @@ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
*/
extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
int nr_chips);
+extern void samsung_gpiolib_add_4bit_chips_no_pm(struct s3c_gpio_chip *chip,
+ int nr_chips);
extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
int nr_chips);
extern void samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
@@ -141,9 +144,9 @@ extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
#ifdef CONFIG_S3C_GPIO_TRACK
extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
{
- return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
+ return (pin < S3C_GPIO_END) ? s3c_gpios[pin] : NULL;
}
#else
/* machine specific code should provide s3c_gpiolib_getchip */
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 1543da8..51d52e7 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -60,6 +60,7 @@ extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *i2c);
/* defined by architecture to configure gpio */
extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
@@ -71,4 +72,6 @@ extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
+extern struct s3c2410_platform_i2c default_i2c_data;
+
#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/iovmm.h b/arch/arm/plat-samsung/include/plat/iovmm.h
new file mode 100644
index 0000000..53d2e77
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/iovmm.h
@@ -0,0 +1,76 @@
+/* linux/arch/arm/plat-s5p/include/plat/iovmm.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_IOVMM_H
+#define __ASM_PLAT_IOVMM_H
+
+#ifdef CONFIG_EXYNOS_IOVMM
+
+struct scatterlist;
+
+int iovmm_setup(struct device *dev);
+void iovmm_cleanup(struct device *dev);
+int iovmm_activate(struct device *dev);
+void iovmm_deactivate(struct device *dev);
+
+/* iovmm_map() - Maps a list of physical memory chunks
+ * @dev: the owner of the IO address space where the mapping is created
+ * @sg: list of physical memory chunks to map
+ * @offset: length in bytes where the mapping starts
+ * @size: how much memory to map in bytes. @offset + @size must not exceed
+ * total size of @sg
+ *
+ * This function returns mapped IO address in the address space of @dev.
+ * Returns 0 if mapping fails.
+ *
+ * The caller of this function must ensure that iovmm_cleanup() is not called
+ * while this function is called.
+ *
+ */
+dma_addr_t iovmm_map(struct device *dev, struct scatterlist *sg, off_t offset,
+ size_t size);
+
+/* iovmm_map() - unmaps the given IO address
+ * @dev: the owner of the IO address space where @iova belongs
+ * @iova: IO address that needs to be unmapped and freed.
+ *
+ * The caller of this function must ensure that iovmm_cleanup() is not called
+ * while this function is called.
+ */
+void iovmm_unmap(struct device *dev, dma_addr_t iova);
+
+/* iovmm_map_oto - create one to one mapping for the given physical address
+ * @dev: the owner of the IO address space to map
+ * @phys: physical address to map
+ * @size: size of the mapping to create
+ *
+ * This function return 0 if mapping is successful. Otherwise, minus error
+ * value.
+ */
+int iovmm_map_oto(struct device *dev, phys_addr_t phys, size_t size);
+
+/* iovmm_unmap_oto - remove one to one mapping
+ * @dev: the owner ofthe IO address space
+ * @phys: physical address to remove mapping
+ */
+void iovmm_unmap_oto(struct device *dev, phys_addr_t phys);
+
+#else
+#define iovmm_setup(dev) (-ENOSYS)
+#define iovmm_cleanup(dev) do { } while (0)
+#define iovmm_activate(dev) (-ENOSYS)
+#define iovmm_deactivate(dev) do { } while (0)
+#define iovmm_map(dev, sg) (0)
+#define iovmm_unmap(dev, iova) do { } while (0)
+#define iovmm_map_oto(dev, phys, size) (0)
+#define iovmm_unmap_oto(dev, phys) do { } while (0)
+#endif /* CONFIG_EXYNOS_IOVMM */
+
+#endif /*__ASM_PLAT_IOVMM_H*/
diff --git a/arch/arm/plat-samsung/include/plat/map-base.h b/arch/arm/plat-samsung/include/plat/map-base.h
index 3ffac4d..ec28c99 100644
--- a/arch/arm/plat-samsung/include/plat/map-base.h
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
@@ -14,15 +14,15 @@
#ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__
-/* Fit all our registers in at 0xF6000000 upwards, trying to use as
- * little of the VA space as possible so vmalloc and friends have a
- * better chance of getting memory.
+/* Fit all our registers in at CONFIG_S3C_BASE_ADDR upwards, trying to
+ * use as little of the VA space as possible so vmalloc and friends
+ * have a better chance of getting memory.
*
* we try to ensure stuff like the IRQ registers are available for
* an single MOVS instruction (ie, only 8 bits of set data)
*/
-#define S3C_ADDR_BASE 0xF6000000
+#define S3C_ADDR_BASE CONFIG_S3C_ADDR_BASE
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
@@ -35,8 +35,14 @@
#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */
#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
+#define S3C_VA_HSOTG S3C_ADDR(0x00E00000) /* OTG */
+#define S3C_VA_HSPHY S3C_ADDR(0x00F00000) /* OTG PHY */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
+#define S3C_VA_KLOG_BUF S3C_ADDR(0x01100000) /* non-cached log buf */
+#define S3C_VA_SLOG_BUF S3C_ADDR(0x01400000) /* non-cached sched log buf */
+#define S3C_VA_AUXLOG_BUF S3C_ADDR(0x01600000) /* auxiliary log buf */
+
/* This is used for the CPU specific mappings that may be needed, so that
* they do not need to directly used S3C_ADDR() and thus make it easier to
* modify the space for mapping.
diff --git a/arch/arm/plat-samsung/include/plat/mshci.h b/arch/arm/plat-samsung/include/plat/mshci.h
new file mode 100644
index 0000000..0333500
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/mshci.h
@@ -0,0 +1,161 @@
+/* linux/arch/arm/plat-samsung/include/plat/mshci.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * EXYNOS4 - MSHCI (HSMMC) platform data definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C_MSHCI_H
+#define __PLAT_S3C_MSHCI_H __FILE__
+
+struct platform_device;
+struct mmc_host;
+struct mmc_card;
+struct mmc_ios;
+
+enum ms_cd_types {
+ S3C_MSHCI_CD_INTERNAL, /* use mmc internal CD line */
+ S3C_MSHCI_CD_EXTERNAL, /* use external callback */
+ S3C_MSHCI_CD_GPIO, /* use external gpio pin for CD line */
+ S3C_MSHCI_CD_NONE, /* no CD line, use polling to detect card */
+ S3C_MSHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
+};
+
+/**
+ * struct s3c_mshci_platdata() - Platform device data for Samsung MSHCI
+ * @max_width: The maximum number of data bits supported.
+ * @host_caps: Standard MMC host capabilities bit field.
+ * @cd_type: Type of Card Detection method (see cd_types enum above)
+ * @wp_gpio: The gpio number using for WP.
+ * @has_wp_gpio: Check using wp_gpio or not.
+ * @ext_cd_init: Initialize external card detect subsystem. Called on
+ * mshci-s3c driver probe when cd_type == S3C_MSHCI_CD_EXTERNAL.
+ * notify_func argument is a callback to the mshci-s3c driver
+ * that triggers the card detection event. Callback arguments:
+ * dev is pointer to platform device of the host controller,
+ * state is new state of the card (0 - removed, 1 - inserted).
+ * @ext_cd_cleanup: Cleanup external card detect subsystem. Called on
+ * mshci-s3c driver remove when cd_type == S3C_MSHCI_CD_EXTERNAL.
+ * notify_func argument is the same callback as for ext_cd_init.
+ * @ext_cd_gpio: gpio pin used for external CD line, valid only if
+ * cd_type == S3C_MSHCI_CD_GPIO
+ * @ext_cd_gpio_invert: invert values for external CD gpio line
+ * @cfg_gpio: Configure the GPIO for a specific card bit-width
+ * @cfg_card: Configure the interface for a specific card and speed. This
+ * is necessary the controllers and/or GPIO blocks require the
+ * changing of driver-strength and other controls dependant on
+ * the card and speed of operation.
+ *
+ * Initialisation data specific to either the machine or the platform
+ * for the device driver to use or call-back when configuring gpio or
+ * card speed information.
+*/
+struct s3c_mshci_platdata {
+ unsigned int max_width;
+ unsigned int host_caps;
+ unsigned int host_caps2;
+ enum ms_cd_types cd_type;
+
+ char **clocks; /* set of clock sources */
+
+ int wp_gpio;
+ int ext_cd_gpio;
+ int int_power_gpio;
+ int fifo_depth;
+ bool ext_cd_gpio_invert;
+ bool has_wp_gpio;
+ int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
+ int state));
+ int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
+ int state));
+
+ void (*cfg_gpio)(struct platform_device *dev, int width);
+ void (*cfg_ddr)(struct platform_device *dev, int ddr);
+ void (*init_card)(struct platform_device *dev);
+ void (*set_power)(struct platform_device *dev, int en);
+ void (*cfg_card)(struct platform_device *dev,
+ void __iomem *regbase,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+ void (*shutdown)(void);
+};
+
+/**
+ * s3c_mshci_set_platdata - Set platform data for S3C MSHCI device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use withe S3C MSHCI device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void s3c_mshci_set_platdata(struct s3c_mshci_platdata *pd);
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+extern struct s3c_mshci_platdata s3c_mshci_def_platdata;
+
+/* Helper function availablity */
+
+extern void s5p6450_setup_mshci_cfg_gpio(struct platform_device *, int w);
+
+/* S5P6450 MSHCI setup */
+extern char *s5p6450_mshc_clksrcs[1];
+
+extern void s5p6450_setup_mshci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s5p6450_default_mshci(void)
+{
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ s3c_mshci_def_platdata.clocks = s5p6450_mshc_clksrcs;
+ s3c_mshci_def_platdata.cfg_gpio = s5p6450_setup_mshci_cfg_gpio;
+ s3c_mshci_def_platdata.cfg_card = s5p6450_setup_mshci_cfg_card;
+#endif /* CONFIG_EXYNOS4_DEV_MSHC */
+}
+
+extern void exynos4_setup_mshci_cfg_gpio(struct platform_device *, int w);
+
+/* EXYNOS4 MSHCI setup */
+#ifdef CONFIG_EXYNOS4_SETUP_MSHCI
+extern char *exynos4_mshci_clksrcs[1];
+#endif
+
+extern void exynos4_setup_mshci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+extern void exynos4_setup_mshci_cfg_ddr(struct platform_device *dev,
+ int ddr);
+extern void exynos4_setup_mshci_init_card(struct platform_device *dev);
+extern void exynos4_setup_mshci_shutdown(void);
+
+extern void exynos4_setup_mshci_set_power(struct platform_device *dev, int en);
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+static inline void exynos4_default_mshci(void)
+{
+ s3c_mshci_def_platdata.clocks = exynos4_mshci_clksrcs;
+ s3c_mshci_def_platdata.cfg_gpio = exynos4_setup_mshci_cfg_gpio;
+ s3c_mshci_def_platdata.cfg_card = exynos4_setup_mshci_cfg_card;
+ s3c_mshci_def_platdata.cfg_ddr = exynos4_setup_mshci_cfg_ddr;
+ s3c_mshci_def_platdata.init_card = exynos4_setup_mshci_init_card;
+ s3c_mshci_def_platdata.set_power = exynos4_setup_mshci_set_power;
+ s3c_mshci_def_platdata.shutdown = exynos4_setup_mshci_shutdown;
+}
+#else
+static inline void exynos4_default_mshci(void) { }
+#endif /* CONFIG_EXYNOS4_DEV_MSHC */
+
+#endif /* __PLAT_S3C_MSHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h
index abb4bc3..832a403 100644
--- a/arch/arm/plat-samsung/include/plat/pd.h
+++ b/arch/arm/plat-samsung/include/plat/pd.h
@@ -11,20 +11,41 @@
#ifndef __ASM_PLAT_SAMSUNG_PD_H
#define __ASM_PLAT_SAMSUNG_PD_H __FILE__
-struct samsung_pd_info {
- int (*enable)(struct device *dev);
- int (*disable)(struct device *dev);
- void __iomem *base;
-};
-
-enum exynos4_pd_block {
+enum exynos_pd_block {
PD_MFC,
PD_G3D,
PD_LCD0,
PD_LCD1,
PD_TV,
PD_CAM,
- PD_GPS
+ PD_GPS,
+ PD_GPS_ALIVE,
+ PD_ISP,
+ PD_MAUDIO,
+ PD_GSCL,
+ PD_DISP1,
+ PD_TOP,
+};
+
+struct samsung_pd_info {
+ int (*init)(struct device *dev);
+ int (*enable)(struct device *dev);
+ int (*disable)(struct device *dev);
+ int (*save)(struct device *dev);
+ int (*restore)(struct device *dev);
+ void __iomem *base;
+ void *data;
+ enum exynos_pd_block id;
+};
+
+struct exynos_pd_data {
+ void __iomem *clk_base;
+ void __iomem *clksrc_base;
+ void __iomem *read_base;
+ unsigned long read_phy_addr;
};
+int exynos_pd_init(struct device *dev);
+int exynos_pd_enable(struct device *dev);
+int exynos_pd_disable(struct device *dev);
#endif /* __ASM_PLAT_SAMSUNG_PD_H */
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 7fb6f6b..c306634 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -43,6 +43,9 @@ extern unsigned long s3c_irqwake_eintallow;
extern void (*pm_cpu_prep)(void);
extern void (*pm_cpu_sleep)(void);
+extern void (*pm_cpu_restore)(void);
+extern int (*pm_prepare)(void);
+extern void (*pm_finish)(void);
/* Flags for PM Control */
@@ -102,10 +105,12 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
#ifdef CONFIG_PM
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
extern int s3c24xx_irq_suspend(void);
extern void s3c24xx_irq_resume(void);
#else
+#define s3c_irq_wake NULL
#define s3c_irqext_wake NULL
#define s3c24xx_irq_suspend NULL
#define s3c24xx_irq_resume NULL
@@ -128,7 +133,7 @@ extern void s3c_pm_dbg(const char *msg, ...);
#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
#else
-#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
+#define S3C_PMDBG(fmt...) pr_debug(fmt)
#endif
#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
@@ -151,10 +156,10 @@ extern void s3c_pm_check_restore(void);
extern void s3c_pm_check_cleanup(void);
extern void s3c_pm_check_store(void);
#else
-#define s3c_pm_check_prepare() do { } while(0)
-#define s3c_pm_check_restore() do { } while(0)
-#define s3c_pm_check_cleanup() do { } while(0)
-#define s3c_pm_check_store() do { } while(0)
+#define s3c_pm_check_prepare() do { } while (0)
+#define s3c_pm_check_restore() do { } while (0)
+#define s3c_pm_check_cleanup() do { } while (0)
+#define s3c_pm_check_store() do { } while (0)
#endif
/**
@@ -183,3 +188,5 @@ extern void s3c_pm_save_gpios(void);
extern void s3c_pm_save_core(void);
extern void s3c_pm_restore_core(void);
+
+extern unsigned long s3c_suspend_wakeup_stat;
diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h
index 7554c4f..b0759b1 100644
--- a/arch/arm/plat-samsung/include/plat/regs-adc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-adc.h
@@ -21,16 +21,19 @@
#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14)
#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18)
+#define S5P_ADCMUX S3C2410_ADCREG(0x1C)
#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20)
/* ADCCON Register Bits */
+#define S3C64XX_ADCCON_TSSEL (1<<17)
#define S3C64XX_ADCCON_RESSEL (1<<16)
#define S3C2410_ADCCON_ECFLG (1<<15)
#define S3C2410_ADCCON_PRSCEN (1<<14)
#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
+#define S5PV210_ADCCON_SELMUX(x) (((x)&0xF)<<0)
#define S3C2410_ADCCON_MUXMASK (0x7<<3)
#define S3C2410_ADCCON_STDBM (1<<2)
#define S3C2410_ADCCON_READ_START (1<<1)
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
index 4c3647f..9c5534e 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+++ b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
@@ -30,9 +30,17 @@
#define VIDCON1_FSTATUS_EVEN (1 << 15)
/* Video timing controls */
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDTCON0 (0x20010)
+#define VIDTCON1 (0x20014)
+#define VIDTCON2 (0x20018)
+#define VIDTCON3 (0x2001C)
+#else
#define VIDTCON0 (0x10)
#define VIDTCON1 (0x14)
#define VIDTCON2 (0x18)
+#define VIDTCON3 (0x1C)
+#endif
/* Window position controls */
@@ -43,9 +51,12 @@
#define VIDOSD_BASE (0x40)
#define VIDINTCON0 (0x130)
+#define VIDINTCON1 (0x134)
/* WINCONx */
+#define WINCONx_CSC_CON_EQ709 (1 << 28)
+#define WINCONx_CSC_CON_EQ601 (0 << 28)
#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
#define WINCONx_CSCWIDTH_SHIFT (26)
#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h
index 8f39aa5..f6c450b 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb.h
+++ b/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -32,12 +32,27 @@
#define VIDCON0 (0x00)
#define VIDCON0_INTERLACE (1 << 29)
-#define VIDCON0_VIDOUT_MASK (0x3 << 26)
+
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDOUT_CON_VIDOUT_UP_MASK (0x1 << 16)
+#define VIDOUT_CON_VIDOUT_UP_SHIFT (16)
+#define VIDOUT_CON_VIDOUT_UP_ALWAYS (0x0 << 16)
+#define VIDOUT_CON_VIDOUT_UP_START_FRAME (0x1 << 16)
+#define VIDOUT_CON_VIDOUT_F_MASK (0x7 << 8)
+#define VIDOUT_CON_VIDOUT_F_SHIFT (8)
+#define VIDOUT_CON_VIDOUT_F_RGB (0x0 << 8)
+#define VIDOUT_CON_VIDOUT_F_I80_LDI0 (0x2 << 8)
+#define VIDOUT_CON_VIDOUT_F_I80_LDI1 (0x3 << 8)
+#define VIDOUT_CON_VIDOUT_F_WB (0x4 << 8)
+#endif
+
+#define VIDCON0_VIDOUT_MASK (0x7 << 26)
#define VIDCON0_VIDOUT_SHIFT (26)
#define VIDCON0_VIDOUT_RGB (0x0 << 26)
#define VIDCON0_VIDOUT_TV (0x1 << 26)
#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26)
#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26)
+#define VIDCON0_VIDOUT_WB (0x4 << 26)
#define VIDCON0_L1_DATA_MASK (0x7 << 23)
#define VIDCON0_L1_DATA_SHIFT (23)
@@ -81,7 +96,17 @@
#define VIDCON0_ENVID (1 << 1)
#define VIDCON0_ENVID_F (1 << 0)
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDOUT_CON (0x20000)
+#define VIDCON1 (0x20004)
+#define REG_TIME2INIT (0x01b4)
+#define REG_TIME2SNP (0x01b8)
+#define DP_MIE_CLKCON (0x027c)
+#define FREERUNCON (0x005c)
+#else
#define VIDCON1 (0x04)
+#endif
+
#define VIDCON1_LINECNT_MASK (0x7ff << 16)
#define VIDCON1_LINECNT_SHIFT (16)
#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
@@ -90,7 +115,11 @@
#define VIDCON1_VSTATUS_VSYNC (0x0 << 13)
#define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13)
#define VIDCON1_VSTATUS_ACTIVE (0x2 << 13)
-#define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13)
+#define VIDCON1_VSTATUS_FRONTPORCH (0x3 << 13)
+#define VIDCON1_VSTATUS_MASK (0x3 << 13)
+#define VIDCON1_VCLK_MASK (0x3 << 9)
+#define VIDCON1_VCLK_HOLD (0x0 << 9)
+#define VIDCON1_VCLK_RUN (0x1 << 9)
#define VIDCON1_INV_VCLK (1 << 7)
#define VIDCON1_INV_HSYNC (1 << 6)
@@ -99,18 +128,27 @@
/* VIDCON2 */
-#define VIDCON2 (0x08)
-#define VIDCON2_EN601 (1 << 23)
-#define VIDCON2_TVFMTSEL_SW (1 << 14)
-
-#define VIDCON2_TVFMTSEL1_MASK (0x3 << 12)
-#define VIDCON2_TVFMTSEL1_SHIFT (12)
-#define VIDCON2_TVFMTSEL1_RGB (0x0 << 12)
-#define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12)
-#define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12)
-
-#define VIDCON2_ORGYCbCr (1 << 8)
-#define VIDCON2_YUVORDCrCb (1 << 7)
+#define VIDCON2 (0x08)
+#define VIDCON2_WB_SKIP_1_2 (1 << 0)
+#define VIDCON2_WB_SKIP_1_3 (1 << 1)
+#define VIDCON2_WB_SKIP_1_4 (3 << 0)
+#define VIDCON2_WB_SKIP_1_5 (1 << 2)
+#define VIDCON2_WB_SKIP_MASK (0x1f << 0)
+#define VIDCON2_EN601 (1 << 23)
+#define VIDCON2_WB_DISABLE (0 << 15)
+#define VIDCON2_WB_ENABLE (1 << 15)
+#define VIDCON2_WB_MASK (1 << 15)
+#define VIDCON2_TVFORMATSEL_HW (0 << 14)
+#define VIDCON2_TVFORMATSEL_SW (1 << 14)
+#define VIDCON2_TVFORMATSEL_HW_SW_MASK (1 << 14)
+#define VIDCON2_TVFORMATSEL_MASK (0x3 << 12)
+#define VIDCON2_TVFORMATSEL_SHIFT (12)
+#define VIDCON2_TVFORMATSEL_RGB (0x0 << 12)
+#define VIDCON2_TVFORMATSEL_YUV422 (0x1 << 12)
+#define VIDCON2_TVFORMATSEL_YUV444 (0x2 << 12)
+
+#define VIDCON2_ORGYCbCr (1 << 8)
+#define VIDCON2_YUVORDCrCb (1 << 7)
/* PRTCON (S3C6410, S5PC100)
* Might not be present in the S3C6410 documentation,
@@ -163,24 +201,29 @@
#define VIDTCON1_HSPW_LIMIT (0xff)
#define VIDTCON1_HSPW(_x) ((_x) << 0)
-#define VIDTCON2 (0x18)
+/* VIDTCON2 */
+
+#define VIDTCON2_LINEVAL_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
#define VIDTCON2_LINEVAL_SHIFT (11)
#define VIDTCON2_LINEVAL_LIMIT (0x7ff)
-#define VIDTCON2_LINEVAL(_x) ((_x) << 11)
+#define VIDTCON2_LINEVAL(_x) (((_x) & 0x7ff) << 11)
+#define VIDTCON2_HOZVAL_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDTCON2_HOZVAL_MASK (0x7ff << 0)
#define VIDTCON2_HOZVAL_SHIFT (0)
#define VIDTCON2_HOZVAL_LIMIT (0x7ff)
-#define VIDTCON2_HOZVAL(_x) ((_x) << 0)
+#define VIDTCON2_HOZVAL(_x) (((_x) & 0x7ff) << 0)
/* WINCONx */
-
#define WINCONx_BITSWP (1 << 18)
#define WINCONx_BYTSWP (1 << 17)
#define WINCONx_HAWSWP (1 << 16)
#define WINCONx_WSWP (1 << 15)
+#define WINCONx_ENLOCAL_MASK (0xf << 15)
+#define WINCONx_INRGB_RGB (0 << 13)
+#define WINCONx_INRGB_YCBCR (1 << 13)
#define WINCONx_BURSTLEN_MASK (0x3 << 9)
#define WINCONx_BURSTLEN_SHIFT (9)
#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
@@ -200,6 +243,7 @@
#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
#define WINCON1_BLD_PIX (1 << 6)
+#define WINCON1_BLD_PLANE (0 << 6)
#define WINCON1_ALPHA_SEL (1 << 1)
#define WINCON1_BPPMODE_MASK (0xf << 2)
@@ -228,25 +272,29 @@
/* Local input channels (windows 0-2) */
#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win)))
+#define VIDOSDxA_TOPLEFT_X_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11)
#define VIDOSDxA_TOPLEFT_X_SHIFT (11)
#define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11)
+#define VIDOSDxA_TOPLEFT_X(_x) (((_x) & 0x7ff) << 11)
+#define VIDOSDxA_TOPLEFT_Y_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0)
#define VIDOSDxA_TOPLEFT_Y_SHIFT (0)
#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0)
+#define VIDOSDxA_TOPLEFT_Y(_x) (((_x) & 0x7ff) << 0)
+#define VIDOSDxB_BOTRIGHT_X_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11)
#define VIDOSDxB_BOTRIGHT_X_SHIFT (11)
#define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11)
+#define VIDOSDxB_BOTRIGHT_X(_x) (((_x) & 0x7ff) << 11)
+#define VIDOSDxB_BOTRIGHT_Y_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0)
#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0)
#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0)
+#define VIDOSDxB_BOTRIGHT_Y(_x) (((_x) & 0x7ff) << 0)
/* For VIDOSD[1..4]C */
#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20)
@@ -278,15 +326,17 @@
#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8))
#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4))
+#define VIDW_BUF_SIZE_OFFSET_E(_x) ((((_x) & 0x2000) >> 13) << 27)
#define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13)
#define VIDW_BUF_SIZE_OFFSET_SHIFT (13)
#define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13)
+#define VIDW_BUF_SIZE_OFFSET(_x) (((_x) & 0x1fff) << 13)
+#define VIDW_BUF_SIZE_PAGEWIDTH_E(_x) ((((_x) & 0x2000) >> 13) << 26)
#define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0)
#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0)
#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0)
+#define VIDW_BUF_SIZE_PAGEWIDTH(_x) (((_x) & 0x1fff) << 0)
/* Interrupt controls and status */
@@ -384,3 +434,22 @@
#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0)
#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
+/* Clock gate mode control */
+#define REG_CLKGATE_MODE (0x1b0)
+#define REG_CLKGATE_MODE_AUTO_CLOCK_GATE (0 << 0)
+#define REG_CLKGATE_MODE_NON_CLOCK_GATE (1 << 0)
+
+/* Blending equation control */
+#define BLENDCON (0x260)
+#define BLENDCON_NEW_MASK (1 << 0)
+#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
+#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0)
+
+/* DP clock control */
+#define DPCLKCON (0x27c)
+#define DPCLKCON_ENABLE (1 << 1)
+
+/* Window alpha control */
+#define VIDW0ALPHA0 (0x200)
+#define VIDW0ALPHA1 (0x204)
+#define DUALRGB (0x27c)
diff --git a/arch/arm/plat-samsung/include/plat/regs-otg.h b/arch/arm/plat-samsung/include/plat/regs-otg.h
new file mode 100644
index 0000000..baeda10
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-otg.h
@@ -0,0 +1,260 @@
+/* linux/arch/arm/plat-samsung/include/plat/regs-otg.h
+ *
+ * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
+ *
+ * This include file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+*/
+
+#ifndef __ASM_ARCH_REGS_USB_OTG_HS_H
+#define __ASM_ARCH_REGS_USB_OTG_HS_H
+
+/* USB2.0 OTG Controller register */
+#define S3C_USBOTG_PHYREG(x) ((x) + S3C_VA_HSPHY)
+#define S3C_USBOTG_PHYPWR S3C_USBOTG_PHYREG(0x0)
+#define S3C_USBOTG_PHYCLK S3C_USBOTG_PHYREG(0x4)
+#define S3C_USBOTG_RSTCON S3C_USBOTG_PHYREG(0x8)
+#define S3C_USBOTG_PHYTUNE S3C_USBOTG_PHYREG(0x24)
+#define S3C_USBOTG_PHY1CON S3C_USBOTG_PHYREG(0x34)
+
+/* USB2.0 OTG Controller register */
+#define S3C_USBOTGREG(x) (x)
+/*============================================================================================== */
+ /* Core Global Registers */
+#define S3C_UDC_OTG_GOTGCTL S3C_USBOTGREG(0x000) /* OTG Control & Status */
+#define S3C_UDC_OTG_GOTGINT S3C_USBOTGREG(0x004) /* OTG Interrupt */
+#define S3C_UDC_OTG_GAHBCFG S3C_USBOTGREG(0x008) /* Core AHB Configuration */
+#define S3C_UDC_OTG_GUSBCFG S3C_USBOTGREG(0x00C) /* Core USB Configuration */
+#define S3C_UDC_OTG_GRSTCTL S3C_USBOTGREG(0x010) /* Core Reset */
+#define S3C_UDC_OTG_GINTSTS S3C_USBOTGREG(0x014) /* Core Interrupt */
+#define S3C_UDC_OTG_GINTMSK S3C_USBOTGREG(0x018) /* Core Interrupt Mask */
+#define S3C_UDC_OTG_GRXSTSR S3C_USBOTGREG(0x01C) /* Receive Status Debug Read/Status Read */
+#define S3C_UDC_OTG_GRXSTSP S3C_USBOTGREG(0x020) /* Receive Status Debug Pop/Status Pop */
+#define S3C_UDC_OTG_GRXFSIZ S3C_USBOTGREG(0x024) /* Receive FIFO Size */
+#define S3C_UDC_OTG_GNPTXFSIZ S3C_USBOTGREG(0x028) /* Non-Periodic Transmit FIFO Size */
+#define S3C_UDC_OTG_GNPTXSTS S3C_USBOTGREG(0x02C) /* Non-Periodic Transmit FIFO/Queue Status */
+
+#define S3C_UDC_OTG_HPTXFSIZ S3C_USBOTGREG(0x100) /* Host Periodic Transmit FIFO Size */
+#define S3C_UDC_OTG_DIEPTXF(n) S3C_USBOTGREG(0x104 + (n-1)*0x4)/* Device IN EP Transmit FIFO Size Register */
+
+/*============================================================================================== */
+/* Host Mode Registers */
+/*------------------------------------------------ */
+/* Host Global Registers */
+#define S3C_UDC_OTG_HCFG S3C_USBOTGREG(0x400) /* Host Configuration */
+#define S3C_UDC_OTG_HFIR S3C_USBOTGREG(0x404) /* Host Frame Interval */
+#define S3C_UDC_OTG_HFNUM S3C_USBOTGREG(0x408) /* Host Frame Number/Frame Time Remaining */
+#define S3C_UDC_OTG_HPTXSTS S3C_USBOTGREG(0x410) /* Host Periodic Transmit FIFO/Queue Status */
+#define S3C_UDC_OTG_HAINT S3C_USBOTGREG(0x414) /* Host All Channels Interrupt */
+#define S3C_UDC_OTG_HAINTMSK S3C_USBOTGREG(0x418) /* Host All Channels Interrupt Mask */
+
+/*------------------------------------------------ */
+/* Host Port Control & Status Registers */
+#define S3C_UDC_OTG_HPRT S3C_USBOTGREG(0x440) /* Host Port Control & Status */
+
+/*------------------------------------------------ */
+/* Host Channel-Specific Registers */
+#define S3C_UDC_OTG_HCCHAR0 S3C_USBOTGREG(0x500) /* Host Channel-0 Characteristics */
+#define S3C_UDC_OTG_HCSPLT0 S3C_USBOTGREG(0x504) /* Host Channel-0 Split Control */
+#define S3C_UDC_OTG_HCINT0 S3C_USBOTGREG(0x508) /* Host Channel-0 Interrupt */
+#define S3C_UDC_OTG_HCINTMSK0 S3C_USBOTGREG(0x50C) /* Host Channel-0 Interrupt Mask */
+#define S3C_UDC_OTG_HCTSIZ0 S3C_USBOTGREG(0x510) /* Host Channel-0 Transfer Size */
+#define S3C_UDC_OTG_HCDMA0 S3C_USBOTGREG(0x514) /* Host Channel-0 DMA Address */
+
+/*============================================================================================== */
+/* Device Mode Registers */
+/*------------------------------------------------ */
+/* Device Global Registers */
+#define S3C_UDC_OTG_DCFG S3C_USBOTGREG(0x800) /* Device Configuration */
+#define S3C_UDC_OTG_DCTL S3C_USBOTGREG(0x804) /* Device Control */
+#define S3C_UDC_OTG_DSTS S3C_USBOTGREG(0x808) /* Device Status */
+#define S3C_UDC_OTG_DIEPMSK S3C_USBOTGREG(0x810) /* Device IN Endpoint Common Interrupt Mask */
+#define S3C_UDC_OTG_DOEPMSK S3C_USBOTGREG(0x814) /* Device OUT Endpoint Common Interrupt Mask */
+#define S3C_UDC_OTG_DAINT S3C_USBOTGREG(0x818) /* Device All Endpoints Interrupt */
+#define S3C_UDC_OTG_DAINTMSK S3C_USBOTGREG(0x81C) /* Device All Endpoints Interrupt Mask */
+#define S3C_UDC_OTG_DTKNQR1 S3C_USBOTGREG(0x820) /* Device IN Token Sequence Learning Queue Read 1 */
+#define S3C_UDC_OTG_DTKNQR2 S3C_USBOTGREG(0x824) /* Device IN Token Sequence Learning Queue Read 2 */
+#define S3C_UDC_OTG_DVBUSDIS S3C_USBOTGREG(0x828) /* Device VBUS Discharge Time */
+#define S3C_UDC_OTG_DVBUSPULSE S3C_USBOTGREG(0x82C) /* Device VBUS Pulsing Time */
+#define S3C_UDC_OTG_DTKNQR3 S3C_USBOTGREG(0x830) /* Device IN Token Sequence Learning Queue Read 3 */
+#define S3C_UDC_OTG_DTKNQR4 S3C_USBOTGREG(0x834) /* Device IN Token Sequence Learning Queue Read 4 */
+
+/*------------------------------------------------ */
+/* Device Logical IN Endpoint-Specific Registers */
+#define S3C_UDC_OTG_DIEPCTL(n) S3C_USBOTGREG(0x900 + n*0x20) /* Device IN Endpoint n Control */
+#define S3C_UDC_OTG_DIEPINT(n) S3C_USBOTGREG(0x908 + n*0x20) /* Device IN Endpoint n Interrupt */
+#define S3C_UDC_OTG_DIEPTSIZ(n) S3C_USBOTGREG(0x910 + n*0x20) /* Device IN Endpoint n Transfer Size */
+#define S3C_UDC_OTG_DIEPDMA(n) S3C_USBOTGREG(0x914 + n*0x20) /* Device IN Endpoint n DMA Address */
+
+/*------------------------------------------------ */
+/* Device Logical OUT Endpoint-Specific Registers */
+#define S3C_UDC_OTG_DOEPCTL(n) S3C_USBOTGREG(0xB00 + n*0x20) /* Device OUT Endpoint n Control */
+#define S3C_UDC_OTG_DOEPINT(n) S3C_USBOTGREG(0xB08 + n*0x20) /* Device OUT Endpoint n Interrupt */
+#define S3C_UDC_OTG_DOEPTSIZ(n) S3C_USBOTGREG(0xB10 + n*0x20) /* Device OUT Endpoint n Transfer Size */
+#define S3C_UDC_OTG_DOEPDMA(n) S3C_USBOTGREG(0xB14 + n*0x20) /* Device OUT Endpoint n DMA Address */
+
+/*------------------------------------------------ */
+/* Endpoint FIFO address */
+#define S3C_UDC_OTG_EP0_FIFO S3C_USBOTGREG(0x1000)
+#define S3C_UDC_OTG_EP1_FIFO S3C_USBOTGREG(0x2000)
+#define S3C_UDC_OTG_EP2_FIFO S3C_USBOTGREG(0x3000)
+#define S3C_UDC_OTG_EP3_FIFO S3C_USBOTGREG(0x4000)
+#define S3C_UDC_OTG_EP4_FIFO S3C_USBOTGREG(0x5000)
+#define S3C_UDC_OTG_EP5_FIFO S3C_USBOTGREG(0x6000)
+#define S3C_UDC_OTG_EP6_FIFO S3C_USBOTGREG(0x7000)
+#define S3C_UDC_OTG_EP7_FIFO S3C_USBOTGREG(0x8000)
+#define S3C_UDC_OTG_EP8_FIFO S3C_USBOTGREG(0x9000)
+#define S3C_UDC_OTG_EP9_FIFO S3C_USBOTGREG(0xA000)
+#define S3C_UDC_OTG_EP10_FIFO S3C_USBOTGREG(0xB000)
+#define S3C_UDC_OTG_EP11_FIFO S3C_USBOTGREG(0xC000)
+#define S3C_UDC_OTG_EP12_FIFO S3C_USBOTGREG(0xD000)
+#define S3C_UDC_OTG_EP13_FIFO S3C_USBOTGREG(0xE000)
+#define S3C_UDC_OTG_EP14_FIFO S3C_USBOTGREG(0xF000)
+#define S3C_UDC_OTG_EP15_FIFO S3C_USBOTGREG(0x10000)
+
+/*===================================================================== */
+/*definitions related to CSR setting */
+
+/* S3C_UDC_OTG_GOTGCTL */
+#define B_SESSION_VALID (0x1<<19)
+#define A_SESSION_VALID (0x1<<18)
+
+/* S3C_UDC_OTG_GAHBCFG */
+#define PTXFE_HALF (0<<8)
+#define PTXFE_ZERO (1<<8)
+#define NPTXFE_HALF (0<<7)
+#define NPTXFE_ZERO (1<<7)
+#define MODE_SLAVE (0<<5)
+#define MODE_DMA (1<<5)
+#define BURST_SINGLE (0<<1)
+#define BURST_INCR (1<<1)
+#define BURST_INCR4 (3<<1)
+#define BURST_INCR8 (5<<1)
+#define BURST_INCR16 (7<<1)
+#define GBL_INT_UNMASK (1<<0)
+#define GBL_INT_MASK (0<<0)
+
+/* S3C_UDC_OTG_GRSTCTL */
+#define AHB_MASTER_IDLE (1u<<31)
+#define CORE_SOFT_RESET (0x1<<0)
+
+/* S3C_UDC_OTG_GINTSTS/S3C_UDC_OTG_GINTMSK core interrupt register */
+#define INT_RESUME (1u<<31)
+#define INT_DISCONN (0x1<<29)
+#define INT_CONN_ID_STS_CNG (0x1<<28)
+#define INT_OUT_EP (0x1<<19)
+#define INT_IN_EP (0x1<<18)
+#define INT_ENUMDONE (0x1<<13)
+#define INT_RESET (0x1<<12)
+#define INT_SUSPEND (0x1<<11)
+#define INT_EARLY_SUSPEND (0x1<<10)
+#define INT_NP_TX_FIFO_EMPTY (0x1<<5)
+#define INT_RX_FIFO_NOT_EMPTY (0x1<<4)
+#define INT_SOF (0x1<<3)
+#define INT_DEV_MODE (0x0<<0)
+#define INT_HOST_MODE (0x1<<1)
+#define INT_GOUTNakEff (0x01<<7)
+#define INT_GINNakEff (0x01<<6)
+
+#define FULL_SPEED_CONTROL_PKT_SIZE 8
+#define FULL_SPEED_BULK_PKT_SIZE 64
+
+#define HIGH_SPEED_CONTROL_PKT_SIZE 64
+#define HIGH_SPEED_BULK_PKT_SIZE 512
+
+#ifdef CONFIG_CPU_S5P6450
+#define RX_FIFO_SIZE (4096>>2)
+#define NPTX_FIFO_START_ADDR RX_FIFO_SIZE
+#define NPTX_FIFO_SIZE (4096>>2)
+#define PTX_FIFO_SIZE (1520>>2)
+#else
+#define RX_FIFO_SIZE (4096>>2)
+#define NPTX_FIFO_START_ADDR RX_FIFO_SIZE
+#define NPTX_FIFO_SIZE (4096>>2)
+#define PTX_FIFO_SIZE (1024>>2)
+#endif
+
+/* Enumeration speed */
+#define USB_HIGH_30_60MHZ (0x0<<1)
+#define USB_FULL_30_60MHZ (0x1<<1)
+#define USB_LOW_6MHZ (0x2<<1)
+#define USB_FULL_48MHZ (0x3<<1)
+
+/* S3C_UDC_OTG_GRXSTSP STATUS */
+#define OUT_PKT_RECEIVED (0x2<<17)
+#define OUT_TRANSFER_COMPLELTED (0x3<<17)
+#define SETUP_TRANSACTION_COMPLETED (0x4<<17)
+#define SETUP_PKT_RECEIVED (0x6<<17)
+#define GLOBAL_OUT_NAK (0x1<<17)
+
+/* S3C_UDC_OTG_DCTL device control register */
+#define NORMAL_OPERATION (0x1<<0)
+#define SOFT_DISCONNECT (0x1<<1)
+#define TEST_CONTROL_MASK (0x7<<4)
+#define TEST_J_MODE (0x1<<4)
+#define TEST_K_MODE (0x2<<4)
+#define TEST_SE0_NAK_MODE (0x3<<4)
+#define TEST_PACKET_MODE (0x4<<4)
+#define TEST_FORCE_ENABLE_MODE (0x5<<4)
+
+/* S3C_UDC_OTG_DAINT device all endpoint interrupt register */
+#define DAINT_OUT_BIT (16)
+#define DAINT_MASK (0xFFFF)
+
+/* S3C_UDC_OTG_DIEPCTL0/DOEPCTL0 device control IN/OUT endpoint 0 control register */
+#define DEPCTL_EPENA (0x1<<31)
+#define DEPCTL_EPDIS (0x1<<30)
+#define DEPCTL_SETD1PID (0x1<<29)
+#define DEPCTL_SETD0PID (0x1<<28)
+#define DEPCTL_SNAK (0x1<<27)
+#define DEPCTL_CNAK (0x1<<26)
+#define DEPCTL_STALL (0x1<<21)
+#define DEPCTL_TYPE_BIT (18)
+#define DEPCTL_TXFNUM_BIT (22)
+#define DEPCTL_TXFNUM_MASK (0xF<<22)
+#define DEPCTL_TYPE_MASK (0x3<<18)
+#define DEPCTL_CTRL_TYPE (0x0<<18)
+#define DEPCTL_ISO_TYPE (0x1<<18)
+#define DEPCTL_BULK_TYPE (0x2<<18)
+#define DEPCTL_INTR_TYPE (0x3<<18)
+#define DEPCTL_NAKSTS (0x1<<17)
+#define DEPCTL_USBACTEP (0x1<<15)
+#define DEPCTL_NEXT_EP_BIT (11)
+#define DEPCTL_MPS_BIT (0)
+#define DEPCTL_MPS_MASK (0x7FF)
+
+#define DEPCTL0_MPS_64 (0x0<<0)
+#define DEPCTL0_MPS_32 (0x1<<0)
+#define DEPCTL0_MPS_16 (0x2<<0)
+#define DEPCTL0_MPS_8 (0x3<<0)
+#define DEPCTL_MPS_BULK_512 (512<<0)
+#define DEPCTL_MPS_INT_MPS_16 (16<<0)
+
+#define DIEPCTL0_NEXT_EP_BIT (11)
+
+/* S3C_UDC_OTG_DIEPCTLn/DOEPCTLn device control IN/OUT endpoint n control register */
+
+/* S3C_UDC_OTG_DIEPMSK/DOEPMSK device IN/OUT endpoint common interrupt mask register */
+/* S3C_UDC_OTG_DIEPINTn/DOEPINTn device IN/OUT endpoint interrupt register */
+#define BACK2BACK_SETUP_RECEIVED (0x1<<6)
+#define INTKNEPMIS (0x1<<5)
+#define INTKN_TXFEMP (0x1<<4)
+#define NON_ISO_IN_EP_TIMEOUT (0x1<<3)
+#define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3)
+#define AHB_ERROR (0x1<<2)
+#define EPDISBLD (0x1<<1)
+#define TRANSFER_DONE (0x1<<0)
+
+/*DIEPTSIZ0 / DOEPTSIZ0 */
+
+/* DEPTSIZ common bit */
+#define DEPTSIZ_PKT_CNT_BIT (19)
+#define DEPTSIZ_XFER_SIZE_BIT (0)
+
+#define DEPTSIZ_SETUP_PKCNT_1 (1<<29)
+#define DEPTSIZ_SETUP_PKCNT_2 (2<<29)
+#define DEPTSIZ_SETUP_PKCNT_3 (3<<29)
+
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 116edfe..5adf78f 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -255,6 +255,8 @@ struct s3c24xx_uart_clksrc {
* arch/arm/mach-s3c2410/ directory.
*/
+struct uart_port;
+
struct s3c2410_uartcfg {
unsigned char hwport; /* hardware port number */
unsigned char unused;
@@ -269,6 +271,9 @@ struct s3c2410_uartcfg {
struct s3c24xx_uart_clksrc *clocks;
unsigned int clocks_size;
+
+ void (*wake_peer)(struct uart_port *);
+ void (*set_runstate)(int onoff);
};
/* s3c24xx_uart_devs
@@ -282,4 +287,3 @@ extern struct platform_device *s3c24xx_uart_devs[4];
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARM_REGS_SERIAL_H */
-
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h
new file mode 100644
index 0000000..50d2954
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h
@@ -0,0 +1,75 @@
+/* arch/arm/plat-samsung/include/plat/regs-usb3-exynos-udc-drd.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co. Ltd
+ * Author: Anton Tikhomirov <av.tikhomirov@samsung.com>
+ *
+ * Exynos SuperSpeed USB 3.0 DRD Controller PHY registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_SAMSUNG_REGS_USB3_EXYNOS_DRD_PHY_H
+#define __PLAT_SAMSUNG_REGS_USB3_EXYNOS_DRD_PHY_H __FILE__
+
+#define EXYNOS_USB3_PHYREG(x) ((x) + S5P_VA_SS_PHY)
+
+
+#define EXYNOS_USB3_LINKSYSTEM EXYNOS_USB3_PHYREG(0x04)
+#define EXYNOS_USB3_PHYUTMI EXYNOS_USB3_PHYREG(0x08)
+
+#define EXYNOS_USB3_PHYUTMI_OTGDISABLE (1 << 6)
+#define EXYNOS_USB3_PHYUTMI_FORCESUSPEND (1 << 1)
+#define EXYNOS_USB3_PHYUTMI_FORCESLEEP (1 << 0)
+
+#define EXYNOS_USB3_PHYPIPE EXYNOS_USB3_PHYREG(0x0C)
+
+
+#define EXYNOS_USB3_PHYCLKRST EXYNOS_USB3_PHYREG(0x10)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_MASK (0xff << 23)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_SHIFT (23)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_LIMIT (0xff)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(_x) ((_x) << 23)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_MASK (0x03 << 21)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_SHIFT (21)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_LIMIT (0x03)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE(_x) ((_x) << 21)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_EN (1 << 20)
+#define EXYNOS_USB3_PHYCLKRST_REF_SSP_EN (1 << 19)
+#define EXYNOS_USB3_PHYCLKRST_REF_CLKDIV2 (1 << 18)
+
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_SHIFT (11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_LIMIT (0x7f)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(_x) ((_x) << 11)
+
+#define EXYNOS_USB3_PHYCLKRST_FSEL_MASK (0x3f << 5)
+#define EXYNOS_USB3_PHYCLKRST_FSEL_SHIFT (5)
+#define EXYNOS_USB3_PHYCLKRST_FSEL_LIMIT (0x3f)
+#define EXYNOS_USB3_PHYCLKRST_FSEL(_x) ((_x) << 5)
+
+#define EXYNOS_USB3_PHYCLKRST_RETENABLEN (1 << 4)
+
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_MASK (0x03 << 2)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_SHIFT (2)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_LIMIT (0x03)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL(_x) ((_x) << 2)
+
+#define EXYNOS_USB3_PHYCLKRST_PORTRESET (1 << 1)
+#define EXYNOS_USB3_PHYCLKRST_COMMONONN (1 << 0)
+
+#define EXYNOS_USB3_PHYREG0 EXYNOS_USB3_PHYREG(0x14)
+#define EXYNOS_USB3_PHYREG1 EXYNOS_USB3_PHYREG(0x18)
+#define EXYNOS_USB3_PHYPARAM0 EXYNOS_USB3_PHYREG(0x1C)
+#define EXYNOS_USB3_PHYPARAM1 EXYNOS_USB3_PHYREG(0x20)
+#define EXYNOS_USB3_PHYTERM EXYNOS_USB3_PHYREG(0x24)
+#define EXYNOS_USB3_PHYTEST EXYNOS_USB3_PHYREG(0x28)
+#define EXYNOS_USB3_PHYADP EXYNOS_USB3_PHYREG(0x2C)
+#define EXYNOS_USB3_PHYBATCHG EXYNOS_USB3_PHYREG(0x30)
+#define EXYNOS_USB3_PHYRESUME EXYNOS_USB3_PHYREG(0x34)
+#define EXYNOS_USB3_LINKPORT EXYNOS_USB3_PHYREG(0x44)
+#endif /* __PLAT_SAMSUNG_REGS_USB3_EXYNOS_DRD_PHY_H */
diff --git a/arch/arm/plat-samsung/include/plat/rtc-core.h b/arch/arm/plat-samsung/include/plat/rtc-core.h
new file mode 100644
index 0000000..65967ca
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/rtc-core.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-samsung/include/plat/rtc-core.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung RTC Device core function
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the term of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_RTC_CORE_H
+#define __ASM_PLAT_RTC_CORE_H __FILE__
+
+/* These function are only for use with the core support code, such as
+ * the cpu specific initialization code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_RTC
+ s3c_device_rtc.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_RTC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
index 8107442..ee155ad 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -84,6 +84,23 @@ enum dma_ch {
DMACH_SLIMBUS4_TX,
DMACH_SLIMBUS5_RX,
DMACH_SLIMBUS5_TX,
+ DMACH_MIPI_HSI0,
+ DMACH_MIPI_HSI1,
+ DMACH_MIPI_HSI2,
+ DMACH_MIPI_HSI3,
+ DMACH_MIPI_HSI4,
+ DMACH_MIPI_HSI5,
+ DMACH_MIPI_HSI6,
+ DMACH_MIPI_HSI7,
+ DMACH_DISP1,
+ DMACH_MTOM_0,
+ DMACH_MTOM_1,
+ DMACH_MTOM_2,
+ DMACH_MTOM_3,
+ DMACH_MTOM_4,
+ DMACH_MTOM_5,
+ DMACH_MTOM_6,
+ DMACH_MTOM_7,
/* END Marker, also used to denote a reserved channel */
DMACH_MAX,
};
@@ -93,6 +110,11 @@ static inline bool s3c_dma_has_circular(void)
return true;
}
+static inline bool s3c_dma_has_infiniteloop(void)
+{
+ return true;
+}
+
#include <plat/dma.h>
#endif /* __S3C_DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index 4c16fa3..353ceb6 100644
--- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -71,5 +71,6 @@ extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
+extern void exynos_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
#endif /* __S3C64XX_PLAT_SPI_H */
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 058e096..c0e3799 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -18,6 +18,8 @@
#ifndef __PLAT_S3C_SDHCI_H
#define __PLAT_S3C_SDHCI_H __FILE__
+/* ignore mmc suspend/resume for BCM WIFI */
+#define S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME (1 << 30)
struct platform_device;
struct mmc_host;
struct mmc_card;
@@ -72,8 +74,11 @@ struct s3c_sdhci_platdata {
char **clocks; /* set of clock sources */
+ char *vmmc_name; /* name for regulator */
int ext_cd_gpio;
bool ext_cd_gpio_invert;
+ unsigned int pm_flags;
+
int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
int state));
int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
@@ -84,6 +89,10 @@ struct s3c_sdhci_platdata {
void __iomem *regbase,
struct mmc_ios *ios,
struct mmc_card *card);
+#ifdef CONFIG_MACH_PX
+ int (*ext_pdev)(struct platform_device *dev_id);
+#endif
+
};
/**
@@ -126,6 +135,10 @@ extern void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
/* S3C2416 SDHCI setup */
@@ -390,4 +403,58 @@ static inline void exynos4_default_sdhci3(void) { }
#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
+extern void mmc_force_presence_change(struct platform_device *pdev);
+
+/* EXYNOS5 SDHCI setup */
+#ifdef CONFIG_EXYNOS4_SETUP_SDHCI
+extern char *exynos4_hsmmc_clksrcs[4];
+
+extern void exynos4_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void exynos5_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = exynos5_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = exynos5_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = exynos5_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci3(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc3_def_platdata.cfg_gpio = exynos5_setup_sdhci3_cfg_gpio;
+ s3c_hsmmc3_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void exynos5_default_sdhci0(void) { }
+static inline void exynos5_default_sdhci1(void) { }
+static inline void exynos5_default_sdhci2(void) { }
+static inline void exynos5_default_sdhci3(void) { }
+
+#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/sysmmu.h b/arch/arm/plat-samsung/include/plat/sysmmu.h
new file mode 100644
index 0000000..bbe2091
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/sysmmu.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung System MMU driver for Exynos platforms
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM__PLAT_SYSMMU_H
+#define __ASM__PLAT_SYSMMU_H __FILE__
+
+#include <linux/list.h>
+#include <linux/atomic.h>
+#include <linux/spinlock.h>
+
+enum exynos_sysmmu_inttype {
+ SYSMMU_PAGEFAULT,
+ SYSMMU_AR_MULTIHIT,
+ SYSMMU_AW_MULTIHIT,
+ SYSMMU_BUSERROR,
+ SYSMMU_AR_SECURITY,
+ SYSMMU_AR_ACCESS,
+ SYSMMU_AW_SECURITY,
+ SYSMMU_AW_PROTECTION, /* 7 */
+ SYSMMU_FAULT_UNKNOWN,
+ SYSMMU_FAULTS_NUM
+};
+
+/*
+ * @itype: type of fault.
+ * @pgtable_base: the physical address of page table base. This is 0 if @itype
+ * is SYSMMU_BUSERROR.
+ * @fault_addr: the device (virtual) address that the System MMU tried to
+ * translated. This is 0 if @itype is SYSMMU_BUSERROR.
+ */
+typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype,
+ unsigned long pgtable_base, unsigned long fault_addr);
+
+#ifdef CONFIG_EXYNOS_IOMMU
+/**
+ * exynos_sysmmu_enable() - enable system mmu
+ * @owner: The device whose System MMU is about to be enabled.
+ * @pgd: Base physical address of the 1st level page table
+ *
+ * This function enable system mmu to transfer address
+ * from virtual address to physical address.
+ * Return non-zero if it fails to enable System MMU.
+ */
+int exynos_sysmmu_enable(struct device *owner, unsigned long pgd);
+
+/**
+ * exynos_sysmmu_disable() - disable sysmmu mmu of ip
+ * @owner: The device whose System MMU is about to be disabled.
+ *
+ * This function disable system mmu to transfer address
+ * from virtual address to physical address
+ */
+bool exynos_sysmmu_disable(struct device *owner);
+
+/**
+ * exynos_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
+ * @owner: The device whose System MMU.
+ *
+ * This function flush all TLB entry in system mmu
+ */
+void exynos_sysmmu_tlb_invalidate(struct device *owner);
+
+/** exynos_sysmmu_set_fault_handler() - Fault handler for System MMUs
+ * Called when interrupt occurred by the System MMUs
+ * The device drivers of peripheral devices that has a System MMU can implement
+ * a fault handler to resolve address translation fault by System MMU.
+ * The meanings of return value and parameters are described below.
+ *
+ * return value: non-zero if the fault is correctly resolved.
+ * zero if the fault is not handled.
+ */
+void exynos_sysmmu_set_fault_handler(struct device *sysmmu,
+ sysmmu_fault_handler_t handler);
+
+/** exynos_sysmmu_set_prefbuf() - Initialize prefetch buffers of System MMU v3
+ * @owner: The device which need to set the prefetch buffers
+ * @base0: The start virtual address of the area of the @owner device that the
+ * first prefetch buffer loads translation descriptors
+ * @size0: The last virtual address of the area of the @owner device that the
+ * first prefetch buffer loads translation descriptors.
+ * @base1: The start virtual address of the area of the @owner device that the
+ * second prefetch buffer loads translation descriptors. This will be
+ * ignored if @size1 is 0 and this function assigns the 2 prefetch
+ * buffers with each half of the area specified by @base0 and @size0
+ * @size1: The last virtual address of the area of the @owner device that the
+ * prefetch buffer loads translation descriptors. This can be 0. See
+ * the description of @base1 for more information with @size1 = 0
+ */
+void exynos_sysmmu_set_prefbuf(struct device *owner,
+ unsigned long base0, unsigned long size0,
+ unsigned long base1, unsigned long size1);
+#else /* CONFIG_EXYNOS_IOMMU */
+#define exynos_sysmmu_enable(owner, pgd) do { } while (0)
+#define exynos_sysmmu_disable(owner) do { } while (0)
+#define exynos_sysmmu_tlb_invalidate(owner) do { } while (0)
+#define exynos_sysmmu_set_fault_handler(sysmmu, handler) do { } while (0)
+#define exynos_sysmmu_set_prefbuf(owner, b0, s0, b1, s1) do { } while (0)
+#endif
+#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h
index 26fdb22..3fb52b9 100644
--- a/arch/arm/plat-samsung/include/plat/ts.h
+++ b/arch/arm/plat-samsung/include/plat/ts.h
@@ -14,10 +14,16 @@ struct s3c2410_ts_mach_info {
int delay;
int presc;
int oversampling_shift;
+
+ int cal_x_max;
+ int cal_y_max;
+ int cal_param[7];
+
void (*cfg_gpio)(struct platform_device *dev);
};
extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
+extern void s3c24xx_ts1_set_platdata(struct s3c2410_ts_mach_info *);
/* defined by architecture to configure gpio */
extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
diff --git a/arch/arm/plat-samsung/include/plat/tv-core.h b/arch/arm/plat-samsung/include/plat/tv-core.h
new file mode 100644
index 0000000..d647eec
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/tv-core.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/plat-samsung/include/plat/tv.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * Tomasz Stanislawski <t.stanislaws@samsung.com>
+ *
+ * Samsung TV driver core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SAMSUNG_PLAT_TV_H
+#define __SAMSUNG_PLAT_TV_H __FILE__
+
+/*
+ * These functions are only for use with the core support code, such as
+ * the CPU-specific initialization code.
+ */
+
+/* Re-define device name to differentiate the subsystem in various SoCs. */
+static inline void s5p_hdmi_setname(char *name)
+{
+#ifdef CONFIG_S5P_DEV_TV
+ s5p_device_hdmi.name = name;
+#endif
+}
+
+static inline void s5p_mixer_setname(char *name)
+{
+#ifdef CONFIG_S5P_DEV_TV
+ s5p_device_mixer.name = name;
+#endif
+}
+
+#endif /* __SAMSUNG_PLAT_TV_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h
index a22a4f2..9b90b08 100644
--- a/arch/arm/plat-samsung/include/plat/udc-hs.h
+++ b/arch/arm/plat-samsung/include/plat/udc-hs.h
@@ -27,3 +27,14 @@ struct s3c_hsotg_plat {
enum s3c_hsotg_dmamode dma;
unsigned int is_osc : 1;
};
+
+typedef enum usb_cable_status {
+ USB_CABLE_DETACHED = 0,
+ USB_CABLE_ATTACHED,
+ USB_OTGHOST_DETACHED,
+ USB_OTGHOST_ATTACHED,
+ USB_POWERED_HOST_DETACHED,
+ USB_POWERED_HOST_ATTACHED,
+ USB_CABLE_DETACHED_WITHOUT_NOTI,
+} usb_cable_status;
+
diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
index 54b762a..4dc5adf 100644
--- a/arch/arm/plat-samsung/include/plat/watchdog-reset.h
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -10,26 +10,24 @@
* published by the Free Software Foundation.
*/
+#include <plat/clock.h>
#include <plat/regs-watchdog.h>
#include <mach/map.h>
+#include <linux/kernel.h>
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
static inline void arch_wdt_reset(void)
{
- struct clk *wdtclk;
-
printk("arch_reset: attempting watchdog reset\n");
__raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */
- wdtclk = clk_get(NULL, "watchdog");
- if (!IS_ERR(wdtclk)) {
- clk_enable(wdtclk);
- } else
- printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
+ if (s3c2410_wdtclk)
+ clk_enable(s3c2410_wdtclk);
/* put initial values into count and data */
__raw_writel(0x80, S3C2410_WTCNT);
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
index 657405c..384f131 100644
--- a/arch/arm/plat-samsung/irq-uart.c
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -23,6 +23,7 @@
#include <plat/irq-uart.h>
#include <plat/regs-serial.h>
#include <plat/cpu.h>
+#include <asm/mach/irq.h>
/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
* are consecutive when looking up the interrupt in the demux routines.
@@ -32,6 +33,12 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
struct s3c_uart_irq *uirq = desc->irq_data.handler_data;
u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
int base = uirq->base_irq;
+ struct irq_chip *chip = irq_get_chip(irq);
+
+ chained_irq_enter(chip, desc);
+
+ if (!(pend & 0xf))
+ do_bad_IRQ(irq, desc);
if (pend & (1 << 0))
generic_handle_irq(base);
@@ -41,6 +48,8 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(base + 2);
if (pend & (1 << 3))
generic_handle_irq(base + 3);
+
+ chained_irq_exit(chip, desc);
}
static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
@@ -65,6 +74,8 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+ ct->chip.irq_mask_ack = irq_gc_mask_and_ack_set;
+ ct->chip.irq_disable = irq_gc_mask_and_ack_set;
ct->regs.ack = S3C64XX_UINTP;
ct->regs.mask = S3C64XX_UINTM;
irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE,
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
index f714d06..7837f48 100644
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -21,10 +21,15 @@
#include <mach/map.h>
#include <plat/irq-vic-timer.h>
#include <plat/regs-timer.h>
+#include <asm/mach/irq.h>
static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
{
+ struct irq_chip *chip = irq_get_chip(irq);
+
+ chained_irq_enter(chip, desc);
generic_handle_irq((int)desc->irq_data.handler_data);
+ chained_irq_exit(chip, desc);
}
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c
index efe1d56..2d40889 100644
--- a/arch/arm/plat-samsung/pd.c
+++ b/arch/arm/plat-samsung/pd.c
@@ -22,12 +22,22 @@ static int samsung_pd_probe(struct platform_device *pdev)
{
struct samsung_pd_info *pdata = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
+ int ret = 0;
if (!pdata) {
dev_err(dev, "no device data specified\n");
return -ENOENT;
}
+ pdata->id = pdev->id;
+ if (pdata->init) {
+ ret = pdata->init(dev);
+ if (ret) {
+ dev_err(dev, "init fails");
+ return ret;
+ }
+ }
+
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -43,6 +53,32 @@ static int __devexit samsung_pd_remove(struct platform_device *pdev)
return 0;
}
+static int samsung_pd_suspend(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->save)
+ ret = pdata->save(dev);
+
+ dev_dbg(dev, "suspended\n");
+
+ return ret;
+}
+
+static int samsung_pd_resume(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->restore)
+ ret = pdata->restore(dev);
+
+ dev_dbg(dev, "resumed\n");
+
+ return ret;
+}
+
static int samsung_pd_runtime_suspend(struct device *dev)
{
struct samsung_pd_info *pdata = dev->platform_data;
@@ -51,7 +87,7 @@ static int samsung_pd_runtime_suspend(struct device *dev)
if (pdata->disable)
ret = pdata->disable(dev);
- dev_dbg(dev, "suspended\n");
+ dev_dbg(dev, "runtime suspended\n");
return ret;
}
@@ -63,11 +99,13 @@ static int samsung_pd_runtime_resume(struct device *dev)
if (pdata->enable)
ret = pdata->enable(dev);
- dev_dbg(dev, "resumed\n");
+ dev_dbg(dev, "runtime resumed\n");
return ret;
}
static const struct dev_pm_ops samsung_pd_pm_ops = {
+ .suspend = samsung_pd_suspend,
+ .resume = samsung_pd_resume,
.runtime_suspend = samsung_pd_runtime_suspend,
.runtime_resume = samsung_pd_runtime_resume,
};
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 9652820..c365b40 100644
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -21,6 +21,7 @@
#include <plat/gpio-core.h>
#include <plat/pm.h>
+#include <plat/cpu.h>
/* PM GPIO helpers */
@@ -318,6 +319,26 @@ static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
pm->save(ourchip);
}
+static int s3c_get_gpio_max_nr (void)
+{
+ static int gpio_max_nr = 0;
+
+ if (unlikely(!gpio_max_nr)) {
+ if (soc_is_exynos4210())
+ gpio_max_nr = EXYNOS4210_GPIO_END;
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ gpio_max_nr = EXYNOS4212_GPIO_END;
+ else if (soc_is_exynos5210())
+ gpio_max_nr = EXYNOS5210_GPIO_END;
+ else if (soc_is_exynos5250())
+ gpio_max_nr = EXYNOS5250_GPIO_END;
+ else
+ gpio_max_nr = S3C_GPIO_END;
+ }
+
+ return gpio_max_nr;
+}
+
/**
* s3c_pm_save_gpios() - Save the state of the GPIO banks.
*
@@ -328,9 +349,12 @@ void s3c_pm_save_gpios(void)
{
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
+ unsigned int gpio_max_nr;
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
- ourchip = s3c_gpiolib_getchip(gpio_nr);
+ gpio_max_nr = s3c_get_gpio_max_nr();
+
+ for (gpio_nr = 0; gpio_nr < gpio_max_nr;) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip) {
gpio_nr++;
continue;
@@ -368,8 +392,11 @@ void s3c_pm_restore_gpios(void)
{
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
+ unsigned int gpio_max_nr;
+
+ gpio_max_nr = s3c_get_gpio_max_nr();
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
+ for (gpio_nr = 0; gpio_nr < gpio_max_nr;) {
ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip) {
gpio_nr++;
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 5c0a440..e46ecce 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/serial_core.h>
#include <linux/io.h>
+#include <linux/power/charger-manager.h>
#include <asm/cacheflush.h>
#include <mach/hardware.h>
@@ -32,6 +33,7 @@
#include <mach/pm-core.h>
/* for external use */
+unsigned long s3c_suspend_wakeup_stat;
unsigned long s3c_pm_flags;
@@ -53,7 +55,9 @@ void s3c_pm_dbg(const char *fmt, ...)
vsprintf(buff, fmt, va);
va_end(va);
+#ifdef CONFIG_DEBUG_LL
printascii(buff);
+#endif
}
static inline void s3c_pm_debug_init(void)
@@ -63,7 +67,7 @@ static inline void s3c_pm_debug_init(void)
}
#else
-#define s3c_pm_debug_init() do { } while(0)
+#define s3c_pm_debug_init() do { } while (0)
#endif /* CONFIG_SAMSUNG_PM_DEBUG */
@@ -186,8 +190,13 @@ void s3c_pm_do_save(struct sleep_save *ptr, int count)
void s3c_pm_do_restore(struct sleep_save *ptr, int count)
{
for (; count > 0; count--, ptr++) {
- printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
+#if defined(CONFIG_CPU_EXYNOS4210)
+ S3C_PMDBG("restore %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#else
+ S3C_PMDBG("restore %p (restore %08lx, was %08x)\n",
ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#endif
__raw_writel(ptr->val, ptr->reg);
}
@@ -206,8 +215,13 @@ void s3c_pm_do_restore(struct sleep_save *ptr, int count)
void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
{
- for (; count > 0; count--, ptr++)
+ for (; count > 0; count--, ptr++) {
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("restore_core %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#endif
__raw_writel(ptr->val, ptr->reg);
+ }
}
/* s3c2410_pm_show_resume_irqs
@@ -223,15 +237,16 @@ static void __maybe_unused s3c_pm_show_resume_irqs(int start,
which &= ~mask;
for (i = 0; i <= 31; i++) {
- if (which & (1L<<i)) {
+ if (which & (1L<<i))
S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
- }
}
}
-
void (*pm_cpu_prep)(void);
void (*pm_cpu_sleep)(void);
+void (*pm_cpu_restore)(void);
+int (*pm_prepare)(void);
+void (*pm_finish)(void);
#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
@@ -268,6 +283,7 @@ static int s3c_pm_enter(suspend_state_t state)
/* save all necessary core registers not covered by the drivers */
s3c_pm_save_gpios();
+ s3c_pm_saved_gpios();
s3c_pm_save_uarts();
s3c_pm_save_core();
@@ -294,24 +310,35 @@ static int s3c_pm_enter(suspend_state_t state)
s3c_pm_arch_stop_clocks();
+ printk(KERN_ALERT "PM: SLEEP\n");
+
/* s3c_cpu_save will also act as our return point from when
* we resume as it saves its own register state and restores it
* during the resume. */
+ printk(KERN_ALERT "ARM_COREx_STATUS CORE1[0x%08x], CORE2[0x%08x], CORE3[0x%08x]\n",
+ __raw_readl(S5P_VA_PMU + 0x2084),
+ __raw_readl(S5P_VA_PMU + 0x2104),
+ __raw_readl(S5P_VA_PMU + 0x2184));
+
s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
/* restore the cpu state using the kernel's cpu init code. */
cpu_init();
- /* restore the system state */
-
s3c_pm_restore_core();
s3c_pm_restore_uarts();
s3c_pm_restore_gpios();
+ s3c_pm_restored_gpios();
s3c_pm_debug_init();
+ /* restore the system state */
+
+ if (pm_cpu_restore)
+ pm_cpu_restore();
+
/* check what irq (if any) restored the system */
s3c_pm_arch_show_resume_irqs();
@@ -334,19 +361,43 @@ static int s3c_pm_prepare(void)
/* prepare check area if configured */
s3c_pm_check_prepare();
+
+ if (pm_prepare)
+ pm_prepare();
+
return 0;
}
static void s3c_pm_finish(void)
{
+ if (pm_finish)
+ pm_finish();
+
s3c_pm_check_cleanup();
}
+#if defined(CONFIG_CHARGER_MANAGER)
+static bool s3c_cm_suspend_again(void)
+{
+ bool ret;
+
+ if (!is_charger_manager_active())
+ return false;
+
+ ret = cm_suspend_again();
+
+ return ret;
+}
+#endif
+
static const struct platform_suspend_ops s3c_pm_ops = {
.enter = s3c_pm_enter,
.prepare = s3c_pm_prepare,
.finish = s3c_pm_finish,
.valid = suspend_valid_only_mem,
+#if defined(CONFIG_CHARGER_MANAGER)
+ .suspend_again = s3c_cm_suspend_again,
+#endif
};
/* s3c_pm_init
@@ -358,7 +409,7 @@ static const struct platform_suspend_ops s3c_pm_ops = {
int __init s3c_pm_init(void)
{
- printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
+ printk(KERN_INFO "S3C Power Management, Copyright 2004 Simtec Electronics\n");
suspend_set_ops(&s3c_pm_ops);
return 0;
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
index f37457c..bdc892a 100644
--- a/arch/arm/plat-samsung/pwm.c
+++ b/arch/arm/plat-samsung/pwm.c
@@ -19,10 +19,12 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pwm.h>
+#include <linux/gpio.h>
#include <mach/map.h>
#include <plat/regs-timer.h>
+#include <plat/gpio-cfg.h>
struct pwm_device {
struct list_head list;
@@ -39,11 +41,28 @@ struct pwm_device {
unsigned char running;
unsigned char use_count;
unsigned char pwm_id;
+
+ unsigned long tcfg0;
+};
+
+struct s3c_pwm_pdata {
+ /* PWM output port */
+ unsigned int gpio_no;
+ const char *gpio_name;
+ unsigned int gpio_set_value;
};
+struct s3c_pwm_pdata *to_pwm_pdata(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return (struct s3c_pwm_pdata *)pdev->dev.platform_data;
+}
+
#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
static struct clk *clk_scaler[2];
+static DEFINE_SPINLOCK(pwm_spin_lock);
static inline int pwm_is_tdiv(struct pwm_device *pwm)
{
@@ -108,15 +127,21 @@ int pwm_enable(struct pwm_device *pwm)
unsigned long flags;
unsigned long tcon;
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ if (!pwm->running) {
+ clk_enable(pwm->clk);
+ clk_enable(pwm->clk_div);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ pwm->running = 1;
+ }
+
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
- pwm->running = 1;
return 0;
}
@@ -127,15 +152,19 @@ void pwm_disable(struct pwm_device *pwm)
unsigned long flags;
unsigned long tcon;
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
- tcon = __raw_readl(S3C2410_TCON);
- tcon &= ~pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ if (pwm->running) {
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon &= ~pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ clk_disable(pwm->clk);
+ clk_disable(pwm->clk_div);
+ pwm->running = 0;
+ }
- pwm->running = 0;
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
}
EXPORT_SYMBOL(pwm_disable);
@@ -185,6 +214,9 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
/* The TCMP and TCNT can be read without a lock, they're not
* shared between the timers. */
+ clk_enable(pwm->clk);
+ clk_enable(pwm->clk_div);
+
tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
@@ -227,12 +259,13 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
/* Update the PWM register block. */
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
__raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
__raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_invert(pwm);
tcon |= pwm_tcon_manulupdate(pwm);
tcon |= pwm_tcon_autoreload(pwm);
__raw_writel(tcon, S3C2410_TCON);
@@ -240,7 +273,10 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
tcon &= ~pwm_tcon_manulupdate(pwm);
__raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
+
+ clk_disable(pwm->clk);
+ clk_disable(pwm->clk_div);
return 0;
}
@@ -263,11 +299,21 @@ static int s3c_pwm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pwm_device *pwm;
- unsigned long flags;
- unsigned long tcon;
+ struct s3c_pwm_pdata *pdata = to_pwm_pdata(dev);
unsigned int id = pdev->id;
int ret;
+ if (gpio_is_valid(pdata->gpio_no)) {
+ ret = gpio_request(pdata->gpio_no, pdata->gpio_name);
+ if (ret)
+ printk(KERN_ERR "failed to get GPIO for PWM0\n");
+ s3c_gpio_cfgpin(pdata->gpio_no, pdata->gpio_set_value);
+
+ /* Inserting the following for commit 2010.02.26: [BACKLIGHT] Fix PWM
+ driver handling GPIO routine (request but not free)*/
+ gpio_free(pdata->gpio_no);
+ }
+
if (id == 4) {
dev_err(dev, "TIMER4 is currently not supported\n");
return -ENXIO;
@@ -299,15 +345,6 @@ static int s3c_pwm_probe(struct platform_device *pdev)
goto err_clk_tin;
}
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
-
ret = pwm_register(pwm);
if (ret) {
dev_err(dev, "failed to register pwm\n");
@@ -359,18 +396,24 @@ static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
pwm->period_ns = 0;
pwm->duty_ns = 0;
+ clk_enable(pwm->clk);
+
+ pwm->tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ clk_disable(pwm->clk);
+
return 0;
}
static int s3c_pwm_resume(struct platform_device *pdev)
{
struct pwm_device *pwm = platform_get_drvdata(pdev);
- unsigned long tcon;
- /* Restore invertion */
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ clk_enable(pwm->clk);
+
+ __raw_writel(pwm->tcfg0, S3C2410_TCFG0);
+
+ clk_disable(pwm->clk);
return 0;
}
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
index f85638c..92f30f7 100644
--- a/arch/arm/plat-samsung/s3c-pl330.c
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -17,6 +17,9 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+#include <linux/pm_runtime.h>
+#endif
#include <asm/hardware/pl330.h>
@@ -498,9 +501,11 @@ static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
spin_lock_irqsave(&res_lock, flags);
- r->x = NULL;
+ if (!r->infiniteloop) {
+ r->x = NULL;
- s3c_pl330_submit(ch, r);
+ s3c_pl330_submit(ch, r);
+ }
spin_unlock_irqrestore(&res_lock, flags);
@@ -513,12 +518,20 @@ static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
res = S3C2410_RES_ERR;
/* If last request had some xfer */
- if (xl) {
- xfer = container_of(xl, struct s3c_pl330_xfer, px);
- _finish_off(xfer, res, 0);
+ if (!r->infiniteloop) {
+ if (xl) {
+ xfer = container_of(xl, struct s3c_pl330_xfer, px);
+ _finish_off(xfer, res, 0);
+ } else {
+ dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
+ __func__, __LINE__);
+ }
} else {
- dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
- __func__, __LINE__);
+ /* Do callback */
+
+ xfer = container_of(xl, struct s3c_pl330_xfer, px);
+ if (ch->callback_fn)
+ ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
}
}
@@ -660,8 +673,8 @@ ctrl_exit:
}
EXPORT_SYMBOL(s3c2410_dma_ctrl);
-int s3c2410_dma_enqueue(enum dma_ch id, void *token,
- dma_addr_t addr, int size)
+int s3c2410_dma_enqueue_ring(enum dma_ch id, void *token,
+ dma_addr_t addr, int size, int numofblock)
{
struct s3c_pl330_chan *ch;
struct s3c_pl330_xfer *xfer;
@@ -669,7 +682,6 @@ int s3c2410_dma_enqueue(enum dma_ch id, void *token,
int idx, ret = 0;
spin_lock_irqsave(&res_lock, flags);
-
ch = id_to_chan(id);
/* Error if invalid or free channel */
@@ -709,11 +721,13 @@ int s3c2410_dma_enqueue(enum dma_ch id, void *token,
/* Try submitting on either request */
idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
- if (!ch->req[idx].x)
+ if (!ch->req[idx].x) {
+ ch->req[idx].infiniteloop = numofblock;
s3c_pl330_submit(ch, &ch->req[idx]);
- else
+ } else {
+ ch->req[1 - idx].infiniteloop = numofblock;
s3c_pl330_submit(ch, &ch->req[1 - idx]);
-
+ }
spin_unlock_irqrestore(&res_lock, flags);
if (ch->options & S3C2410_DMAF_AUTOSTART)
@@ -726,7 +740,7 @@ enq_exit:
return ret;
}
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
+EXPORT_SYMBOL(s3c2410_dma_enqueue_ring);
int s3c2410_dma_request(enum dma_ch id,
struct s3c2410_dma_client *client,
@@ -747,9 +761,24 @@ int s3c2410_dma_request(enum dma_ch id,
dmac = ch->dmac;
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* enable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_get_sync(dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
+ clk_enable(dmac->clk);
+
ch->pl330_chan_id = pl330_request_channel(dmac->pi);
if (!ch->pl330_chan_id) {
chan_release(ch);
+ clk_disable(dmac->clk);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_put(dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
ret = -EBUSY;
goto req_exit;
}
@@ -860,7 +889,14 @@ int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
pl330_release_channel(ch->pl330_chan_id);
ch->pl330_chan_id = NULL;
+ clk_disable(ch->dmac->clk);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_put(ch->dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
chan_release(ch);
free_exit:
@@ -986,6 +1022,18 @@ int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
ch->rqcfg.src_inc = 1;
ch->rqcfg.dst_inc = 0;
break;
+ case S3C_DMA_MEM2MEM:
+ ch->req[0].rqtype = MEMTOMEM;
+ ch->req[1].rqtype = MEMTOMEM;
+ ch->rqcfg.src_inc = 1;
+ ch->rqcfg.dst_inc = 1;
+ break;
+ case S3C_DMA_MEM2MEM_SET:
+ ch->req[0].rqtype = MEMTOMEM;
+ ch->req[1].rqtype = MEMTOMEM;
+ ch->rqcfg.src_inc = 0;
+ ch->rqcfg.dst_inc = 1;
+ break;
default:
ret = -EINVAL;
goto devcfg_exit;
@@ -1057,6 +1105,16 @@ static int pl330_probe(struct platform_device *pdev)
goto probe_err1;
}
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* to use the runtime PM helper functions */
+ pm_runtime_enable(&pdev->dev);
+ /* enable the power domain */
+ if (pm_runtime_get_sync(&pdev->dev)) {
+ dev_err(&pdev->dev, "failed to get runtime pm\n");
+ ret = -ENODEV;
+ goto probe_err1;
+ }
+#endif
request_mem_region(res->start, resource_size(res), pdev->name);
pl330_info->base = ioremap(res->start, resource_size(res));
@@ -1131,6 +1189,11 @@ static int pl330_probe(struct platform_device *pdev)
pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
+ clk_disable(s3c_pl330_dmac->clk);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ pm_runtime_put(&pdev->dev);
+#endif
return 0;
probe_err8:
@@ -1147,6 +1210,11 @@ probe_err3:
iounmap(pl330_info->base);
probe_err2:
release_mem_region(res->start, resource_size(res));
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+#endif
probe_err1:
kfree(pl330_info);
@@ -1156,7 +1224,7 @@ probe_err1:
static int pl330_remove(struct platform_device *pdev)
{
struct s3c_pl330_dmac *dmac, *d;
- struct s3c_pl330_chan *ch;
+ struct s3c_pl330_chan *ch, *ch_tmp;
unsigned long flags;
int del, found;
@@ -1180,7 +1248,7 @@ static int pl330_remove(struct platform_device *pdev)
dmac = d;
/* Remove all Channels that are managed only by this DMAC */
- list_for_each_entry(ch, &chan_list, node) {
+ list_for_each_entry_safe(ch, ch_tmp, &chan_list, node) {
/* Only channels that are handled by this DMAC */
if (iface_of_dmac(dmac, ch->id))
@@ -1205,15 +1273,20 @@ static int pl330_remove(struct platform_device *pdev)
}
/* Disable operation clock */
- clk_disable(dmac->clk);
clk_put(dmac->clk);
/* Remove the DMAC */
list_del(&dmac->node);
kfree(dmac);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
spin_unlock_irqrestore(&res_lock, flags);
-
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+#else
+ spin_unlock_irqrestore(&res_lock, flags);
+#endif
return 0;
}