diff options
Diffstat (limited to 'arch/arm/plat-s3c')
-rw-r--r-- | arch/arm/plat-s3c/include/plat/devs.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-s3c/include/plat/nand.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c/include/plat/uncompress.h | 19 | ||||
-rw-r--r-- | arch/arm/plat-s3c/pwm.c | 72 |
4 files changed, 90 insertions, 4 deletions
diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h index 0f540ea1e99..50d50a2f086 100644 --- a/arch/arm/plat-s3c/include/plat/devs.h +++ b/arch/arm/plat-s3c/include/plat/devs.h @@ -53,6 +53,8 @@ extern struct platform_device s3c_device_nand; extern struct platform_device s3c_device_usbgadget; extern struct platform_device s3c_device_usb_hsotg; +extern struct platform_device s3c_device_ts; + /* s3c2440 specific devices */ #ifdef CONFIG_CPU_S3C2440 diff --git a/arch/arm/plat-s3c/include/plat/nand.h b/arch/arm/plat-s3c/include/plat/nand.h index 18f958801e6..723ab032059 100644 --- a/arch/arm/plat-s3c/include/plat/nand.h +++ b/arch/arm/plat-s3c/include/plat/nand.h @@ -47,6 +47,7 @@ struct s3c2410_platform_nand { int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */ unsigned int ignore_unset_ecc:1; + unsigned int software_ecc:1; /* force software ecc at runtime */ int nr_sets; struct s3c2410_nand_set *sets; diff --git a/arch/arm/plat-s3c/include/plat/uncompress.h b/arch/arm/plat-s3c/include/plat/uncompress.h index dc66a477f62..8e02073e307 100644 --- a/arch/arm/plat-s3c/include/plat/uncompress.h +++ b/arch/arm/plat-s3c/include/plat/uncompress.h @@ -37,6 +37,8 @@ static void arch_detect_cpu(void); /* how many bytes we allow into the FIFO at a time in FIFO mode */ #define FIFO_MAX (14) +#if CONFIG_S3C_LOWLEVEL_UART_PORT >= 0 + #define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT) static __inline__ void @@ -86,10 +88,6 @@ static void putc(int ch) uart_wr(S3C2410_UTXH, ch); } -static inline void flush(void) -{ -} - #define __raw_writel(d, ad) \ do { \ *((volatile unsigned int __force *)(ad)) = (d); \ @@ -163,6 +161,19 @@ static inline void arch_enable_uart_fifo(void) #define arch_enable_uart_fifo() do { } while(0) #endif +#else +static inline void putc(int ch) +{ +} + +#define arch_enable_uart_fifo() do { } while(0) +#define arch_decomp_wdog_start() +#define arch_decomp_wdog() +#endif + +static inline void flush(void) +{ +} static void arch_decomp_setup(void) diff --git a/arch/arm/plat-s3c/pwm.c b/arch/arm/plat-s3c/pwm.c index 4fdc5b307fd..2a5275d98ca 100644 --- a/arch/arm/plat-s3c/pwm.c +++ b/arch/arm/plat-s3c/pwm.c @@ -21,6 +21,8 @@ #include <mach/irqs.h> #include <mach/map.h> +#include <mach/gpio.h> +#include <mach/regs-gpio.h> #include <plat/devs.h> #include <plat/regs-timer.h> @@ -40,6 +42,10 @@ struct pwm_device { unsigned char running; unsigned char use_count; unsigned char pwm_id; + + /* Used for saving state during suspend */ + unsigned long tcon; + unsigned char routed_to_gpio:1; }; #define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg) @@ -130,6 +136,7 @@ void pwm_free(struct pwm_device *pwm) EXPORT_SYMBOL(pwm_free); +#define pwm_tcon_mask(pwm) (0xf << (pwm->tcon_base)) #define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0)) #define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2)) #define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3)) @@ -379,10 +386,75 @@ static int s3c_pwm_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM + +static int s3c_pwm_suspend(struct device *dev) +{ + struct pwm_device *pwm = dev_get_drvdata(dev); + unsigned int gpio_cfg = s3c2410_gpio_getcfg(S3C2410_GPB(pwm->pwm_id)); + + /* During suspend the pwm registers are reseted. If the invert bit is not + * set the output of TOUTn is high when the pwm is not active. In order to + * prevent spurious high output on the gpio at resume time, we stop routing + * the pwm signal to the gpio until tcon has been restored. */ + if (gpio_cfg == S3C2410_GPIO_SFN2) { + s3c2410_gpio_cfgpin(S3C2410_GPB(pwm->pwm_id), S3C2410_GPIO_INPUT); + pwm->routed_to_gpio = 1; + } else { + pwm->routed_to_gpio = 0; + } + + pwm->tcon = __raw_readl(S3C2410_TCON); + + return 0; +} + +static int s3c_pwm_resume(struct device *dev) +{ + struct pwm_device *pwm = dev_get_drvdata(dev); + unsigned long flags; + unsigned long tcon; + int duty_ns, period_ns; + + duty_ns = pwm->duty_ns; + period_ns = pwm->period_ns; + pwm->duty_ns = -1; + pwm->period_ns = -1; + pwm_config(pwm, duty_ns, period_ns); + + local_irq_save(flags); + tcon = __raw_readl(S3C2410_TCON); + tcon = __raw_readl(S3C2410_TCON); + tcon &= ~pwm_tcon_mask(pwm); + tcon |= pwm->tcon; + __raw_writel(tcon, S3C2410_TCON); + local_irq_restore(flags); + + if (pwm->routed_to_gpio) + s3c2410_gpio_cfgpin(S3C2410_GPB(pwm->pwm_id), S3C2410_GPIO_SFN2); + + return 0; +} + +struct dev_pm_ops s3c_pwm_pm_ops = { + .suspend = s3c_pwm_suspend, + .resume = s3c_pwm_resume, + .freeze = s3c_pwm_suspend, + .thaw = s3c_pwm_resume, +}; + +#define S3C_PWM_PM_OPS (&s3c_pwm_pm_ops) + +#else +#define S3C_PWM_PM_OPS NULL +#endif + + static struct platform_driver s3c_pwm_driver = { .driver = { .name = "s3c24xx-pwm", .owner = THIS_MODULE, + .pm = S3C_PWM_PM_OPS, }, .probe = s3c_pwm_probe, .remove = __devexit_p(s3c_pwm_remove), |