summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-s3c/include/plat/pm.h19
-rw-r--r--arch/arm/plat-s3c/pm.c61
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/map.h2
3 files changed, 60 insertions, 22 deletions
diff --git a/arch/arm/plat-s3c/include/plat/pm.h b/arch/arm/plat-s3c/include/plat/pm.h
index f121a5ac7420..c27b8cf5d891 100644
--- a/arch/arm/plat-s3c/include/plat/pm.h
+++ b/arch/arm/plat-s3c/include/plat/pm.h
@@ -71,6 +71,25 @@ struct sleep_save {
 #define SAVE_ITEM(x) \
 	{ .reg = (x) }
 
+/**
+ * struct pm_uart_save - save block for core UART
+ * @ulcon: Save value for S3C2410_ULCON
+ * @ucon: Save value for S3C2410_UCON
+ * @ufcon: Save value for S3C2410_UFCON
+ * @umcon: Save value for S3C2410_UMCON
+ * @ubrdiv: Save value for S3C2410_UBRDIV
+ *
+ * Save block for UART registers to be held over sleep and restored if they
+ * are needed (say by debug).
+*/
+struct pm_uart_save {
+	u32	ulcon;
+	u32	ucon;
+	u32	ufcon;
+	u32	umcon;
+	u32	ubrdiv;
+};
+
 /* helper functions to save/restore lists of registers. */
 
 extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c
index e320b0ff3852..78bf50a14027 100644
--- a/arch/arm/plat-s3c/pm.c
+++ b/arch/arm/plat-s3c/pm.c
@@ -72,33 +72,50 @@ static inline void s3c_pm_debug_init(void)
 
 #ifdef CONFIG_S3C2410_PM_DEBUG
 
-#define SAVE_UART(va) \
-	SAVE_ITEM((va) + S3C2410_ULCON), \
-	SAVE_ITEM((va) + S3C2410_UCON), \
-	SAVE_ITEM((va) + S3C2410_UFCON), \
-	SAVE_ITEM((va) + S3C2410_UMCON), \
-	SAVE_ITEM((va) + S3C2410_UBRDIV)
-
-static struct sleep_save uart_save[] = {
-	SAVE_UART(S3C_VA_UART0),
-	SAVE_UART(S3C_VA_UART1),
-#ifndef CONFIG_CPU_S3C2400
-	SAVE_UART(S3C_VA_UART2),
-#endif
-};
+struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
+{
+	void __iomem *regs = S3C_VA_UARTx(uart);
+
+	save->ulcon = __raw_readl(regs + S3C2410_ULCON);
+	save->ucon = __raw_readl(regs + S3C2410_UCON);
+	save->ufcon = __raw_readl(regs + S3C2410_UFCON);
+	save->umcon = __raw_readl(regs + S3C2410_UMCON);
+	save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
+}
 
-static void s3c_pm_save_uart(void)
+static void s3c_pm_save_uarts(void)
 {
-	s3c_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
+	struct pm_uart_save *save = uart_save;
+	unsigned int uart;
+
+	for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+		s3c_pm_save_uart(uart, save);
+}
+
+static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
+{
+	void __iomem *regs = S3C_VA_UARTx(uart);
+
+	__raw_writel(save->ulcon, regs + S3C2410_ULCON);
+	__raw_writel(save->ucon,  regs + S3C2410_UCON);
+	__raw_writel(save->ufcon, regs + S3C2410_UFCON);
+	__raw_writel(save->umcon, regs + S3C2410_UMCON);
+	__raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
 }
 
-static void s3c_pm_restore_uart(void)
+static void s3c_pm_restore_uarts(void)
 {
-	s3c_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
+	struct pm_uart_save *save = uart_save;
+	unsigned int uart;
+
+	for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+		s3c_pm_restore_uart(uart, save);
 }
 #else
-static void s3c_pm_save_uart(void) { }
-static void s3c_pm_restore_uart(void) { }
+static void s3c_pm_save_uarts(void) { }
+static void s3c_pm_restore_uarts(void) { }
 #endif
 
 /* The IRQ ext-int code goes here, it is too small to currently bother
@@ -250,7 +267,7 @@ static int s3c_pm_enter(suspend_state_t state)
 	/* save all necessary core registers not covered by the drivers */
 
 	s3c_pm_save_gpios();
-	s3c_pm_save_uart();
+	s3c_pm_save_uarts();
 	s3c_pm_save_core();
 
 	/* set the irq configuration for wake */
@@ -293,7 +310,7 @@ static int s3c_pm_enter(suspend_state_t state)
 	/* restore the system state */
 
 	s3c_pm_restore_core();
-	s3c_pm_restore_uart();
+	s3c_pm_restore_uarts();
 	s3c_pm_restore_gpios();
 
 	s3c_pm_debug_init();
diff --git a/arch/arm/plat-s3c24xx/include/plat/map.h b/arch/arm/plat-s3c24xx/include/plat/map.h
index fef8ea8b8e1e..eed8f78e7593 100644
--- a/arch/arm/plat-s3c24xx/include/plat/map.h
+++ b/arch/arm/plat-s3c24xx/include/plat/map.h
@@ -31,6 +31,8 @@
 #define S3C24XX_SZ_UART	   SZ_1M
 #define S3C_UART_OFFSET	   (0x4000)
 
+#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET)))
+
 /* Timers */
 #define S3C24XX_VA_TIMER   S3C_VA_TIMER
 #define S3C2410_PA_TIMER   (0x51000000)