diff options
Diffstat (limited to 'arch/arm/plat-samsung')
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; } |