aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-samsung
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-samsung')
-rw-r--r--arch/arm/plat-samsung/Makefile2
-rw-r--r--arch/arm/plat-samsung/clock.c152
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c6
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c6
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c6
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c6
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c40
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c37
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c43
-rw-r--r--arch/arm/plat-samsung/dev-uart.c8
-rw-r--r--arch/arm/plat-samsung/gpio-config.c21
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h34
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h6
-rwxr-xr-x[-rw-r--r--]arch/arm/plat-samsung/include/plat/gpio-cfg.h6
-rwxr-xr-x[-rw-r--r--]arch/arm/plat-samsung/include/plat/gpio-core.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h5
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-otg.h262
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-rtc.h18
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-sdhci.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h13
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h8
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h23
-rw-r--r--arch/arm/plat-samsung/include/plat/watchdog-reset.h10
-rwxr-xr-x[-rw-r--r--]arch/arm/plat-samsung/pm-gpio.c9
-rw-r--r--arch/arm/plat-samsung/pm.c98
-rw-r--r--arch/arm/plat-samsung/pwm.c52
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c23
-rw-r--r--arch/arm/plat-samsung/time.c2
33 files changed, 818 insertions, 101 deletions
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 53eb15b..c4bc9cb 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -12,7 +12,9 @@ obj- :=
# Objects we always build independent of SoC choice
obj-y += init.o
+ifndef CONFIG_S5P_HIGH_RES_TIMERS
obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
+endif
obj-y += clock.o
obj-y += pwm-clock.o
obj-y += gpio.o
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 7728928..a3101e5 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -95,10 +95,19 @@ static int dev_is_platform_device(struct device *dev)
/* Clock API calls */
+static int nullstrcmp(const char *a, const char *b)
+{
+ if (!a)
+ return b ? -1 : 0;
+ if (!b)
+ return 1;
+
+ return strcmp(a, b);
+}
+
struct clk *clk_get(struct device *dev, const char *id)
{
- struct clk *p;
- struct clk *clk = ERR_PTR(-ENOENT);
+ struct clk *clk;
int idno;
if (dev == NULL || !dev_is_platform_device(dev))
@@ -108,65 +117,96 @@ struct clk *clk_get(struct device *dev, const char *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;
- }
- }
+ list_for_each_entry(clk, &clocks, list)
+ if (!nullstrcmp(id, clk->name) && clk->dev == dev)
+ goto found_it;
- /* check for the case where a device was supplied, but the
- * clock that was being searched for is not device specific */
+ list_for_each_entry(clk, &clocks, list)
+ if (clk->id == idno && nullstrcmp(id, clk->name) == 0)
+ goto found_it;
- 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;
- }
- }
- }
+ list_for_each_entry(clk, &clocks, list)
+ if (clk->id == -1 && !nullstrcmp(id, clk->name) &&
+ clk->dev == NULL)
+ goto found_it;
+ clk = ERR_PTR(-ENOENT);
+ pr_warning("%s: could not find clock %s for dev %pS (%s)\n",
+ __func__, id, dev, dev ? dev_name(dev) : "");
+ spin_unlock(&clocks_lock);
+ return clk;
+found_it:
+ pr_debug("%s(%p, %s) found %s %d %pS\n",
+ __func__, dev, id, clk->name, clk->id, clk->dev);
+ if (!try_module_get(clk->owner))
+ clk = ERR_PTR(-ENOENT);
spin_unlock(&clocks_lock);
return clk;
}
void clk_put(struct clk *clk)
{
+ pr_debug("%s on %s %d %pS", __func__, clk->name, clk->id, clk->dev);
module_put(clk->owner);
}
-int clk_enable(struct clk *clk)
+void _clk_enable(struct clk *clk)
{
- if (IS_ERR(clk) || clk == NULL)
- return -EINVAL;
+ if (!clk || IS_ERR(clk))
+ return;
- clk_enable(clk->parent);
+ if ((clk->usage++) > 0)
+ return;
- spin_lock(&clocks_lock);
+ _clk_enable(clk->parent);
+ pr_debug("%s update hardware clock %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+ (clk->enable)(clk, 1);
+}
- if ((clk->usage++) == 0)
- (clk->enable)(clk, 1);
+int clk_enable(struct clk *clk)
+{
+ if (WARN_ON_ONCE(IS_ERR(clk) || clk == NULL)) {
+ pr_debug("%s request on invalid clock\n", __func__);
+ return -EINVAL;
+ }
+ pr_debug("%s request on %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+ spin_lock(&clocks_lock);
+ _clk_enable(clk);
spin_unlock(&clocks_lock);
+
return 0;
}
-void clk_disable(struct clk *clk)
+void _clk_disable(struct clk *clk)
{
- if (IS_ERR(clk) || clk == NULL)
+ if (!clk || IS_ERR(clk))
+ return;
+
+ if ((--clk->usage) > 0)
return;
- spin_lock(&clocks_lock);
+ pr_debug("%s update hardware clock %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+ (clk->enable)(clk, 0);
+ _clk_disable(clk->parent);
+}
- if ((--clk->usage) == 0)
- (clk->enable)(clk, 0);
+void clk_disable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL) {
+ pr_debug("%s request on invalid clock\n", __func__);
+ return;
+ }
+ pr_debug("%s request on %s %d %pS\n",
+ __func__, clk->name, clk->id, clk->dev);
+
+ spin_lock(&clocks_lock);
+ _clk_disable(clk);
spin_unlock(&clocks_lock);
- clk_disable(clk->parent);
}
@@ -352,6 +392,25 @@ int s3c24xx_register_clock(struct clk *clk)
BUG_ON(clk->list.prev != clk->list.next);
spin_lock(&clocks_lock);
+ if (clk->enable != clk_null_enable) {
+ struct clk *c;
+ list_for_each_entry(c, &clocks, list) {
+ if (c->enable == clk->enable &&
+ c->ctrlbit & clk->ctrlbit) {
+ pr_warning("%s: new clock %s, id %d, dev %p "
+ "uses same enable bit as "
+ "%s, id %d, dev %p\n", __func__,
+ clk->name, clk->id, clk->dev,
+ c->name, c->id, c->dev);
+ }
+ if (!nullstrcmp(c->name, clk->name) &&
+ c->id == clk->id && c->dev == clk->dev) {
+ pr_warning("%s: duplicate clock id: "
+ "%s, id %d, dev %p\n", __func__,
+ clk->name, clk->id, clk->dev);
+ }
+ }
+ }
list_add(&clk->list, &clocks);
spin_unlock(&clocks_lock);
@@ -462,18 +521,35 @@ static int clk_debugfs_register_one(struct clk *c)
struct clk *pa = c->parent;
char s[255];
char *p = s;
+ int i;
p += sprintf(p, "%s", c->name);
if (c->id >= 0)
- sprintf(p, ":%d", c->id);
+ p += sprintf(p, ":%d", c->id);
- d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
- if (!d)
- return -ENOMEM;
+ for (i = 1; i < 16; i++) {
+ d = debugfs_create_dir(s, clk_debugfs_root);
+ if (d)
+ break;
+ sprintf(p, " copy %d", i);
+ }
+ if (!d) {
+ pr_warning("%s: failed to register %s\n", __func__, s);
+ return 0;
+ }
c->dent = d;
+ if (pa) {
+ d = debugfs_create_symlink("parent",
+ c->dent, pa->dent->d_name.name);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ }
+
d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usage);
if (!d) {
err = -ENOMEM;
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index db7a65c..9296bd8 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -76,4 +76,10 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index 2497321..4e7b100 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -76,4 +76,10 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index f60aedb..ef2e8c6 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -77,4 +77,10 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
index ede776f..da729c5 100644
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -80,4 +80,10 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
+ if (pd->built_in)
+ set->built_in = pd->built_in;
+ if (pd->must_maintain_clock)
+ set->must_maintain_clock = pd->must_maintain_clock;
+ if (pd->enable_intr_on_resume)
+ set->enable_intr_on_resume = pd->enable_intr_on_resume;
}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
index 3a601c1..0aa46b1 100644
--- a/arch/arm/plat-samsung/dev-i2c0.c
+++ b/arch/arm/plat-samsung/dev-i2c0.c
@@ -15,6 +15,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/irqs.h>
#include <mach/map.h>
@@ -24,6 +26,8 @@
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <asm/io.h>
+
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC,
@@ -39,11 +43,7 @@ static struct resource s3c_i2c_resource[] = {
struct platform_device s3c_device_i2c0 = {
.name = "s3c2410-i2c",
-#ifdef CONFIG_S3C_DEV_I2C1
.id = 0,
-#else
- .id = -1,
-#endif
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
@@ -51,8 +51,8 @@ struct platform_device s3c_device_i2c0 = {
static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
.flags = 0,
.slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
+ .frequency = 400*1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY15 | S3C2410_IICLC_FILTER_ON,
};
void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
@@ -70,3 +70,31 @@ void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
s3c_device_i2c0.dev.platform_data = npd;
}
+
+void s3c_i2c0_force_stop()
+{
+ void __iomem *regs;
+ struct clk *clk;
+ unsigned long iicstat;
+
+ regs = ioremap(S3C_PA_IIC, SZ_4K);
+ if(regs == NULL) {
+ printk(KERN_ERR "%s, cannot request IO\n", __func__);
+ return;
+ }
+
+ clk = clk_get(&s3c_device_i2c0.dev, "i2c");
+ if(clk == NULL || IS_ERR(clk)) {
+ printk(KERN_ERR "%s, cannot get cloock\n", __func__);
+ return;
+ }
+
+ clk_enable(clk);
+ iicstat = readl(regs + S3C2410_IICSTAT);
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, regs + S3C2410_IICSTAT);
+ clk_disable(clk);
+
+ iounmap(regs);
+}
+EXPORT_SYMBOL(s3c_i2c0_force_stop);
+
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
index 858ee2a..3a1a85f 100644
--- a/arch/arm/plat-samsung/dev-i2c1.c
+++ b/arch/arm/plat-samsung/dev-i2c1.c
@@ -15,6 +15,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/irqs.h>
#include <mach/map.h>
@@ -24,6 +26,8 @@
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <asm/io.h>
+
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC1,
@@ -48,8 +52,8 @@ static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
.flags = 0,
.bus_num = 1,
.slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
+ .frequency = 400*1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
};
void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
@@ -67,3 +71,32 @@ void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
s3c_device_i2c1.dev.platform_data = npd;
}
+
+void s3c_i2c1_force_stop()
+{
+ struct resource *ioarea;
+ void __iomem *regs;
+ struct clk *clk;
+ unsigned long iicstat;
+
+ regs = ioremap(S3C_PA_IIC1, SZ_4K);
+ if(regs == NULL) {
+ printk(KERN_ERR "%s, cannot request IO\n", __func__);
+ return;
+ }
+
+ clk = clk_get(&s3c_device_i2c1.dev, "i2c");
+ if(clk == NULL || IS_ERR(clk)) {
+ printk(KERN_ERR "%s, cannot get cloock\n", __func__);
+ return;
+ }
+
+ clk_enable(clk);
+ iicstat = readl(regs + S3C2410_IICSTAT);
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, regs + S3C2410_IICSTAT);
+ clk_disable(clk);
+
+ iounmap(regs);
+}
+EXPORT_SYMBOL(s3c_i2c1_force_stop);
+
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
index ff4ba69..d9b5fb6 100644
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -1,12 +1,11 @@
/* linux/arch/arm/plat-s3c/dev-i2c2.c
*
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Copyright 2008-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
*
* S3C series device definition for i2c device 2
*
- * Based on plat-samsung/dev-i2c0.c
- *
* 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.
@@ -16,6 +15,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/irqs.h>
#include <mach/map.h>
@@ -25,6 +26,8 @@
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <asm/io.h>
+
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC2,
@@ -49,8 +52,8 @@ static struct s3c2410_platform_i2c default_i2c_data2 __initdata = {
.flags = 0,
.bus_num = 2,
.slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
+ .frequency = 400*1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
};
void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
@@ -68,3 +71,31 @@ void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
s3c_device_i2c2.dev.platform_data = npd;
}
+
+void s3c_i2c2_force_stop()
+{
+ void __iomem *regs;
+ struct clk *clk;
+ unsigned long iicstat;
+
+ regs = ioremap(S3C_PA_IIC2, SZ_4K);
+ if(regs == NULL) {
+ printk(KERN_ERR "%s, cannot request IO\n", __func__);
+ return;
+ }
+
+ clk = clk_get(&s3c_device_i2c2.dev, "i2c");
+ if(clk == NULL || IS_ERR(clk)) {
+ printk(KERN_ERR "%s, cannot get cloock\n", __func__);
+ return;
+ }
+
+ clk_enable(clk);
+ iicstat = readl(regs + S3C2410_IICSTAT);
+ writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, regs + S3C2410_IICSTAT);
+ clk_disable(clk);
+
+ iounmap(regs);
+}
+EXPORT_SYMBOL(s3c_i2c2_force_stop);
+
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
index 5928105..6db1f63 100644
--- a/arch/arm/plat-samsung/dev-uart.c
+++ b/arch/arm/plat-samsung/dev-uart.c
@@ -19,19 +19,19 @@
/* uart devices */
-static struct platform_device s3c24xx_uart_device0 = {
+struct platform_device s3c24xx_uart_device0 = {
.id = 0,
};
-static struct platform_device s3c24xx_uart_device1 = {
+struct platform_device s3c24xx_uart_device1 = {
.id = 1,
};
-static struct platform_device s3c24xx_uart_device2 = {
+struct platform_device s3c24xx_uart_device2 = {
.id = 2,
};
-static struct platform_device s3c24xx_uart_device3 = {
+struct platform_device s3c24xx_uart_device3 = {
.id = 3,
};
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 1c0b040..a899173 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -130,6 +130,27 @@ s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
}
EXPORT_SYMBOL(s3c_gpio_getpull);
+int s3c_gpio_setpin(unsigned int pin, s3c_gpio_pull_t level)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset, ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ local_irq_save(flags);
+ //ret = s3c_gpio_do_setpin(chip, offset, level);
+ ret = (chip->config->set_pin)(chip, offset, level);
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+EXPORT_SYMBOL(s3c_gpio_setpin);
+
#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 983c578..0533827 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -46,6 +46,7 @@ struct clk {
unsigned long ctrlbit;
struct clk_ops *ops;
+ struct device *dev;
int (*enable)(struct clk *, int enable);
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index c0a5741..8865194 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -66,7 +66,11 @@ extern void s3c24xx_init_uartdevs(char *name,
/* timer for 2410/2440 */
struct sys_timer;
+#if defined(CONFIG_S5P_HIGH_RES_TIMERS)
+extern struct sys_timer s5p_systimer;
+#else
extern struct sys_timer s3c24xx_timer;
+#endif
extern struct syscore_ops s3c2410_pm_syscore_ops;
extern struct syscore_ops s3c2412_pm_syscore_ops;
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index e3b31c2..54e0b6e 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -30,6 +30,16 @@ extern struct s3c24xx_uart_resources s5p_uart_resources[];
extern struct platform_device *s3c24xx_uart_devs[];
extern struct platform_device *s3c24xx_uart_src[];
+extern struct platform_device s3c24xx_uart_device0;
+extern struct platform_device s3c24xx_uart_device1;
+extern struct platform_device s3c24xx_uart_device2;
+extern struct platform_device s3c24xx_uart_device3;
+
+extern struct platform_device s5pv210_device_fiqdbg_uart0;
+extern struct platform_device s5pv210_device_fiqdbg_uart1;
+extern struct platform_device s5pv210_device_fiqdbg_uart2;
+extern struct platform_device s5pv210_device_fiqdbg_uart3;
+
extern struct platform_device s3c_device_timer[];
extern struct platform_device s3c64xx_device_iis0;
@@ -49,6 +59,15 @@ extern struct platform_device s3c64xx_device_ac97;
extern struct platform_device s3c_device_ts;
extern struct platform_device s3c_device_fb;
+
+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_ipc;
+extern struct platform_device s3c_device_mfc;
+extern struct platform_device s3c_device_jpeg;
+extern struct platform_device s3c_device_g3d;
+
extern struct platform_device s3c_device_ohci;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
@@ -91,8 +110,15 @@ 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_android_usb;
+extern struct platform_device s3c_device_usb_mass_storage;
+extern struct platform_device s3c_device_rndis;
extern struct platform_device s3c_device_usb_hsotg;
+extern struct platform_device s5p_device_rotator;
+extern struct platform_device s5p_device_tvout;
+extern struct platform_device s5p_device_g3d;
+
extern struct platform_device s5pv210_device_ac97;
extern struct platform_device s5pv210_device_pcm0;
extern struct platform_device s5pv210_device_pcm1;
@@ -142,9 +168,17 @@ extern struct platform_device s5p_device_mipi_csis1;
extern struct platform_device s5p_device_ehci;
extern struct platform_device exynos4_device_sysmmu;
+extern struct platform_device s5p_device_rtc;
+extern struct platform_device s3c_device_adc;
/* s3c2440 specific devices */
+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 s5pv210_device_cpufreq;
+
#ifdef CONFIG_CPU_S3C2440
extern struct platform_device s3c_device_camif;
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
index 8c273b7..459bdc8 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
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 3ad8386..33cc2ca 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -48,6 +48,12 @@ static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
return chip->config->get_pull(chip, off);
}
+static inline int s3c_gpio_do_setpin(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t level)
+{
+ return (chip->config->set_pin)(chip, off, level);
+}
+
/**
* s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
* @chip: The gpio chip that is being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1762dcb..214a125 100644..100755
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -56,11 +56,16 @@ struct s3c_gpio_cfg {
int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
s3c_gpio_pull_t pull);
+ int (*set_pin)(struct s3c_gpio_chip *chip, unsigned offs,
+ s3c_gpio_pull_t level);
+
unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
unsigned config);
};
+extern int s3c_gpio_setpin(unsigned int pin, s3c_gpio_pull_t level);
+
#define S3C_GPIO_SPECIAL_MARK (0xfffffff0)
#define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x))
@@ -68,6 +73,7 @@ struct s3c_gpio_cfg {
#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0))
#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1))
#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x))
+#define S3C_GPIO_EINT (S3C_GPIO_SPECIAL(0xF))
#define s3c_gpio_is_cfg_special(_cfg) \
(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 8cad4cf..0ce5225 100644..100755
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -69,7 +69,7 @@ struct s3c_gpio_chip {
int group;
spinlock_t lock;
#ifdef CONFIG_PM
- u32 pm_save[4];
+ u32 pm_save[7];
#endif
};
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 1543da8..aec3471 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -71,4 +71,8 @@ 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 void s3c_i2c0_force_stop(void);
+extern void s3c_i2c1_force_stop(void);
+extern void s3c_i2c2_force_stop(void);
+
#endif /* __ASM_ARCH_IIC_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..da2414c 100644
--- a/arch/arm/plat-samsung/include/plat/map-base.h
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
@@ -14,7 +14,7 @@
#ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__
-/* Fit all our registers in at 0xF6000000 upwards, trying to use as
+/* Fit all our registers in at 0xFC000000 upwards, trying to use as
* little of the VA space as possible so vmalloc and friends have a
* better chance of getting memory.
*
@@ -22,7 +22,7 @@
* an single MOVS instruction (ie, only 8 bits of set data)
*/
-#define S3C_ADDR_BASE 0xF6000000
+#define S3C_ADDR_BASE (0xFC000000)
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
@@ -35,6 +35,8 @@
#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_OTG S3C_ADDR(0x00E00000) /* OTG */
+#define S3C_VA_OTGSFR S3C_ADDR(0x00F00000) /* OTG PHY */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
/* This is used for the CPU specific mappings that may be needed, so that
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 7fb6f6b..824ad59 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -43,6 +43,7 @@ extern unsigned long s3c_irqwake_eintallow;
extern void (*pm_cpu_prep)(void);
extern void (*pm_cpu_sleep)(void);
+extern void (*pm_cpu_restore)(void);
/* Flags for PM Control */
@@ -128,7 +129,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
@@ -183,3 +184,5 @@ extern void s3c_pm_save_gpios(void);
extern void s3c_pm_save_core(void);
extern void s3c_pm_restore_core(void);
+
+extern void s3c_config_sleep_gpio(void); \ No newline at end of file
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..dccdb26
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-otg.h
@@ -0,0 +1,262 @@
+/* arch/arm/plat-samsung/include/plat/regs-otg.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * Kyoungil Kim <ki0351.kim@samsung.com>
+ *
+ * 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_OTGSFR)
+#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)
+
+/* USB2.0 OTG Controller register */
+#define S3C_USBOTGREG(x) ((x) + S3C_VA_OTG)
+/*============================================================================================== */
+ /* 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)
+#define SESSION_REQ (0x1<<1)
+/* 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 HCLK_SOFT_RESET (0x1<<1)
+#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
+
+#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>>1)
+
+/* 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)
+#define REMOTE_WAKEUP (0x1<<0)
+
+/* S3C_UDC_OTG_DSTS device status register */
+#define SOFFN_MASK (0x3fff << 8)
+#define SOFFN_SHIFT (8)
+#define USB_SUSPEND (0x1<<0)
+
+/* 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_SET_ODD_FRM (0x1<<29)
+#define DEPCTL_SETD0PID (0x1<<28)
+#define DEPCTL_SET_EVEN_FRM (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_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-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h
index 30b7cc1..b8daf4b 100644
--- a/arch/arm/plat-samsung/include/plat/regs-rtc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h
@@ -28,6 +28,22 @@
#define S3C64XX_RTCCON_TICMSK (0xF<<7)
#define S3C64XX_RTCCON_TICSHT (7)
+#if defined(CONFIG_CPU_S5PC100) || defined(CONFIG_CPU_S5PV210)
+#define S3C_MAX_CNT 32768
+#define S3C_RTCCON_TICEN (1<<8)
+#define S3C_RTC_TICNT S3C2410_RTCREG(0x40)
+#else
+#define S3C_INTP_ALM (1<<1)
+#define S3C_MAX_CNT 128
+#define S3C_RTCCON_TICEN (1<<7)
+#define S3C_RTC_TICNT S3C2410_RTCREG(0x44)
+#endif
+
+/* Common Reg for samsung AP*/
+#define S3C_INTP S3C2410_RTCREG(0x30)
+#define S3C_INTP_ALM (1<<1)
+#define S3C_INTP_TIC (1<<0)
+
#define S3C2410_TICNT S3C2410_RTCREG(0x44)
#define S3C2410_TICNT_ENABLE (1<<7)
@@ -63,6 +79,6 @@
#define S3C2410_RTCDAY S3C2410_RTCREG(0x80)
#define S3C2410_RTCMON S3C2410_RTCREG(0x84)
#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88)
-
+#define S3C2410_CURTICCNT S3C2410_RTCREG(0x90)
#endif /* __ASM_ARCH_REGS_RTC_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-sdhci.h b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
index e34049a..a9d956d 100644
--- a/arch/arm/plat-samsung/include/plat/regs-sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
@@ -83,5 +83,5 @@
#define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16)
#define S3C64XX_SDHCI_CONTROL4_BUSY (1)
-
+#define SDHCI_S3C_CTRL_8BITBUS (1 << 5)
#endif /* __PLAT_S3C_SDHCI_REGS_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 116edfe..48a91dd 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -53,6 +53,8 @@
#define S3C2410_UERSTAT (0x14)
#define S3C2410_UFSTAT (0x18)
#define S3C2410_UMSTAT (0x1C)
+#define S3C2410_UDIVSLOT (0x2C)
+#define S3C2410_UINTMSK (0x38)
#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3))
@@ -194,6 +196,11 @@
#define S3C64XX_UINTSP 0x34
#define S3C64XX_UINTM 0x38
+/* S5V210 interrupt registers. */
+#define S5P_UINTP 0x30
+#define S5P_UINTSP 0x34
+#define S5P_UINTM 0x38
+
/* Following are specific to S5PV210 */
#define S5PV210_UCON_CLKMASK (1<<10)
#define S5PV210_UCON_PCLK (0<<10)
@@ -259,7 +266,11 @@ struct s3c2410_uartcfg {
unsigned char hwport; /* hardware port number */
unsigned char unused;
unsigned short flags;
+#if !defined(CONFIG_CPU_S5PV210)
upf_t uart_flags; /* default uart flags */
+#else
+ unsigned long uart_flags; /* default uart flags */
+#endif
unsigned int has_fracval;
@@ -269,6 +280,8 @@ struct s3c2410_uartcfg {
struct s3c24xx_uart_clksrc *clocks;
unsigned int clocks_size;
+
+ void (*wake_peer)(struct uart_port *);
};
/* s3c24xx_uart_devs
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..333e381 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,14 @@ enum dma_ch {
DMACH_SLIMBUS4_TX,
DMACH_SLIMBUS5_RX,
DMACH_SLIMBUS5_TX,
+ 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,
};
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 058e096..0c386fc 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -84,6 +84,15 @@ struct s3c_sdhci_platdata {
void __iomem *regbase,
struct mmc_ios *ios,
struct mmc_card *card);
+ void (*adjust_cfg_card)(struct s3c_sdhci_platdata *pdata, void __iomem *regbase, int rw);
+ int rx_cfg;
+ int tx_cfg;
+
+ /* add to deal with non-removable device */
+ int built_in;
+
+ int must_maintain_clock;
+ int enable_intr_on_resume;
};
/**
@@ -94,6 +103,7 @@ struct s3c_sdhci_platdata {
* The call will copy the platform data, so the board definitions can
* make the structure itself __initdata.
*/
+extern void s3c_sdhci_set_platdata(void);
extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
@@ -289,9 +299,10 @@ static inline void s5pc100_default_sdhci2(void) { }
extern char *s5pv210_hsmmc_clksrcs[4];
extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
- void __iomem *r,
- struct mmc_ios *ios,
- struct mmc_card *card);
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+extern void s5pv210_adjust_sdhci_cfg_card(struct s3c_sdhci_platdata *pdata, void __iomem *r, int rw);
static inline void s5pv210_default_sdhci0(void)
{
@@ -299,6 +310,7 @@ static inline void s5pv210_default_sdhci0(void)
s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc0_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -308,6 +320,7 @@ static inline void s5pv210_default_sdhci1(void)
s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc1_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -317,6 +330,7 @@ static inline void s5pv210_default_sdhci2(void)
s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc2_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -326,6 +340,7 @@ static inline void s5pv210_default_sdhci3(void)
s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+ s3c_hsmmc3_def_platdata.adjust_cfg_card = s5pv210_adjust_sdhci_cfg_card;
#endif
}
@@ -390,4 +405,6 @@ static inline void exynos4_default_sdhci3(void) { }
#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
+extern void sdhci_s3c_force_presence_change(struct platform_device *pdev);
+
#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
index 54b762a..632e1ed 100644
--- a/arch/arm/plat-samsung/include/plat/watchdog-reset.h
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -13,24 +13,18 @@
#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__);
-
/* put initial values into count and data */
__raw_writel(0x80, S3C2410_WTCNT);
__raw_writel(0x80, S3C2410_WTDAT);
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 9652820..f7dccb0 100644..100755
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -27,6 +27,9 @@
#define OFFS_CON (0x00)
#define OFFS_DAT (0x04)
#define OFFS_UP (0x08)
+#define OFFS_DRV (0x0C)
+#define OFFS_CONPDN (0x10)
+#define OFFS_PUDPDN (0x14)
static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
{
@@ -198,6 +201,9 @@ static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
+ chip->pm_save[4] = __raw_readl(chip->base + OFFS_DRV);
+ chip->pm_save[5] = __raw_readl(chip->base + OFFS_CONPDN);
+ chip->pm_save[6] = __raw_readl(chip->base + OFFS_PUDPDN);
if (chip->chip.ngpio > 8)
chip->pm_save[0] = __raw_readl(chip->base - 4);
@@ -284,6 +290,9 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
__raw_writel(chip->pm_save[2], base + OFFS_DAT);
__raw_writel(chip->pm_save[3], base + OFFS_UP);
+ __raw_writel(chip->pm_save[4], base + OFFS_DRV);
+ __raw_writel(chip->pm_save[5], base + OFFS_CONPDN);
+ __raw_writel(chip->pm_save[6], base + OFFS_PUDPDN);
if (chip->chip.ngpio > 8) {
S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 5c0a440..8494c87 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -26,15 +26,87 @@
#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
#include <mach/regs-irq.h>
+#include <asm/fiq_glue.h>
#include <asm/irq.h>
#include <plat/pm.h>
+#include <plat/irq-eint-group.h>
#include <mach/pm-core.h>
/* for external use */
unsigned long s3c_pm_flags;
+/* ---------------------------------------------- */
+extern unsigned int pm_debug_scratchpad;
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+
+#define PMSTATS_MAGIC "*PM*DEBUG*STATS*"
+
+struct pmstats {
+ char magic[16];
+ unsigned sleep_count;
+ unsigned wake_count;
+ unsigned sleep_freq;
+ unsigned wake_freq;
+};
+
+static struct pmstats *pmstats;
+static struct pmstats *pmstats_last;
+
+static ssize_t pmstats_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ if (*offset != 0)
+ return 0;
+ if (len > 4096)
+ len = 4096;
+
+ if (copy_to_user(buf, file->private_data, len))
+ return -EFAULT;
+
+ *offset += len;
+ return len;
+}
+
+static int pmstats_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static const struct file_operations pmstats_ops = {
+ .owner = THIS_MODULE,
+ .read = pmstats_read,
+ .open = pmstats_open,
+};
+
+void __init pmstats_init(void)
+{
+ pr_info("pmstats at %08x\n", pm_debug_scratchpad);
+ if (pm_debug_scratchpad)
+ pmstats = ioremap(pm_debug_scratchpad, 4096);
+ else
+ pmstats = kzalloc(4096, GFP_ATOMIC);
+
+ if (!memcmp(pmstats->magic, PMSTATS_MAGIC, 16)) {
+ pmstats_last = kzalloc(4096, GFP_ATOMIC);
+ if (pmstats_last)
+ memcpy(pmstats_last, pmstats, 4096);
+ }
+
+ memset(pmstats, 0, 4096);
+ memcpy(pmstats->magic, PMSTATS_MAGIC, 16);
+
+ debugfs_create_file("pmstats", 0444, NULL, pmstats, &pmstats_ops);
+ if (pmstats_last)
+ debugfs_create_file("pmstats_last", 0444, NULL, pmstats_last, &pmstats_ops);
+}
+/* ---------------------------------------------- */
+
/* Debug code:
*
* This code supports debug output to the low level UARTs for use on
@@ -185,12 +257,8 @@ 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",
- ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
+ for (; count > 0; count--, ptr++)
__raw_writel(ptr->val, ptr->reg);
- }
}
/**
@@ -232,6 +300,7 @@ static void __maybe_unused s3c_pm_show_resume_irqs(int start,
void (*pm_cpu_prep)(void);
void (*pm_cpu_sleep)(void);
+void (*pm_cpu_restore)(void);
#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
@@ -271,6 +340,8 @@ static int s3c_pm_enter(suspend_state_t state)
s3c_pm_save_uarts();
s3c_pm_save_core();
+ s3c_config_sleep_gpio();
+
/* set the irq configuration for wake */
s3c_pm_configure_extint();
@@ -290,6 +361,9 @@ static int s3c_pm_enter(suspend_state_t state)
s3c_pm_check_store();
+ /* clear wakeup_stat register for next wakeup reason */
+ __raw_writel(__raw_readl(S5P_WAKEUP_STAT), S5P_WAKEUP_STAT);
+
/* send the cpu to sleep... */
s3c_pm_arch_stop_clocks();
@@ -298,20 +372,31 @@ static int s3c_pm_enter(suspend_state_t state)
* we resume as it saves its own register state and restores it
* during the resume. */
+ pmstats->sleep_count++;
+ pmstats->sleep_freq = __raw_readl(S5P_CLK_DIV0);
s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
+ pmstats->wake_count++;
+ pmstats->wake_freq = __raw_readl(S5P_CLK_DIV0);
/* restore the cpu state using the kernel's cpu init code. */
cpu_init();
- /* restore the system state */
+ fiq_glue_resume();
+ local_fiq_enable();
s3c_pm_restore_core();
s3c_pm_restore_uarts();
s3c_pm_restore_gpios();
+ s5pv210_restore_eint_group();
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();
@@ -359,6 +444,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");
+ pmstats_init();
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..84723bd 100644
--- a/arch/arm/plat-samsung/pwm.c
+++ b/arch/arm/plat-samsung/pwm.c
@@ -44,6 +44,7 @@ struct pwm_device {
#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 +109,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);
- local_irq_restore(flags);
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ pwm->running = 1;
+ }
+
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
- pwm->running = 1;
return 0;
}
@@ -127,15 +134,20 @@ 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 +197,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,7 +242,7 @@ 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));
@@ -240,9 +255,13 @@ 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;
+
}
EXPORT_SYMBOL(pwm_config);
@@ -299,14 +318,13 @@ static int s3c_pwm_probe(struct platform_device *pdev)
goto err_clk_tin;
}
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
tcon = __raw_readl(S3C2410_TCON);
tcon |= pwm_tcon_invert(pwm);
__raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
-
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
ret = pwm_register(pwm);
if (ret) {
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
index f85638c..3b88d8f 100644
--- a/arch/arm/plat-samsung/s3c-pl330.c
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -747,8 +747,11 @@ int s3c2410_dma_request(enum dma_ch id,
dmac = ch->dmac;
+ clk_enable(dmac->clk);
+
ch->pl330_chan_id = pl330_request_channel(dmac->pi);
if (!ch->pl330_chan_id) {
+ clk_disable(dmac->clk);
chan_release(ch);
ret = -EBUSY;
goto req_exit;
@@ -860,7 +863,7 @@ 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);
chan_release(ch);
free_exit:
@@ -986,6 +989,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;
@@ -1131,6 +1146,7 @@ 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);
return 0;
probe_err8:
@@ -1156,7 +1172,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, *cht;
unsigned long flags;
int del, found;
@@ -1180,7 +1196,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, cht, &chan_list, node) {
/* Only channels that are handled by this DMAC */
if (iface_of_dmac(dmac, ch->id))
@@ -1205,7 +1221,6 @@ static int pl330_remove(struct platform_device *pdev)
}
/* Disable operation clock */
- clk_disable(dmac->clk);
clk_put(dmac->clk);
/* Remove the DMAC */
diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c
index 2231d80..a16a57b 100644
--- a/arch/arm/plat-samsung/time.c
+++ b/arch/arm/plat-samsung/time.c
@@ -132,7 +132,9 @@ static unsigned long s3c2410_gettimeoffset (void)
static irqreturn_t
s3c2410_timer_interrupt(int irq, void *dev_id)
{
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
timer_tick();
+#endif
return IRQ_HANDLED;
}