aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/plat-s3c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-s3c')
-rw-r--r--arch/arm/plat-s3c/include/plat/devs.h2
-rw-r--r--arch/arm/plat-s3c/include/plat/nand.h1
-rw-r--r--arch/arm/plat-s3c/include/plat/uncompress.h19
-rw-r--r--arch/arm/plat-s3c/pwm.c72
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),