diff options
-rw-r--r-- | arch/arm/plat-s3c/include/plat/pm.h | 19 | ||||
-rw-r--r-- | arch/arm/plat-s3c/pm.c | 61 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/include/plat/map.h | 2 |
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 { | |||
71 | #define SAVE_ITEM(x) \ | 71 | #define SAVE_ITEM(x) \ |
72 | { .reg = (x) } | 72 | { .reg = (x) } |
73 | 73 | ||
74 | /** | ||
75 | * struct pm_uart_save - save block for core UART | ||
76 | * @ulcon: Save value for S3C2410_ULCON | ||
77 | * @ucon: Save value for S3C2410_UCON | ||
78 | * @ufcon: Save value for S3C2410_UFCON | ||
79 | * @umcon: Save value for S3C2410_UMCON | ||
80 | * @ubrdiv: Save value for S3C2410_UBRDIV | ||
81 | * | ||
82 | * Save block for UART registers to be held over sleep and restored if they | ||
83 | * are needed (say by debug). | ||
84 | */ | ||
85 | struct pm_uart_save { | ||
86 | u32 ulcon; | ||
87 | u32 ucon; | ||
88 | u32 ufcon; | ||
89 | u32 umcon; | ||
90 | u32 ubrdiv; | ||
91 | }; | ||
92 | |||
74 | /* helper functions to save/restore lists of registers. */ | 93 | /* helper functions to save/restore lists of registers. */ |
75 | 94 | ||
76 | extern void s3c_pm_do_save(struct sleep_save *ptr, int count); | 95 | 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) | |||
72 | 72 | ||
73 | #ifdef CONFIG_S3C2410_PM_DEBUG | 73 | #ifdef CONFIG_S3C2410_PM_DEBUG |
74 | 74 | ||
75 | #define SAVE_UART(va) \ | 75 | struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS]; |
76 | SAVE_ITEM((va) + S3C2410_ULCON), \ | 76 | |
77 | SAVE_ITEM((va) + S3C2410_UCON), \ | 77 | static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save) |
78 | SAVE_ITEM((va) + S3C2410_UFCON), \ | 78 | { |
79 | SAVE_ITEM((va) + S3C2410_UMCON), \ | 79 | void __iomem *regs = S3C_VA_UARTx(uart); |
80 | SAVE_ITEM((va) + S3C2410_UBRDIV) | 80 | |
81 | 81 | save->ulcon = __raw_readl(regs + S3C2410_ULCON); | |
82 | static struct sleep_save uart_save[] = { | 82 | save->ucon = __raw_readl(regs + S3C2410_UCON); |
83 | SAVE_UART(S3C_VA_UART0), | 83 | save->ufcon = __raw_readl(regs + S3C2410_UFCON); |
84 | SAVE_UART(S3C_VA_UART1), | 84 | save->umcon = __raw_readl(regs + S3C2410_UMCON); |
85 | #ifndef CONFIG_CPU_S3C2400 | 85 | save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV); |
86 | SAVE_UART(S3C_VA_UART2), | 86 | } |
87 | #endif | ||
88 | }; | ||
89 | 87 | ||
90 | static void s3c_pm_save_uart(void) | 88 | static void s3c_pm_save_uarts(void) |
91 | { | 89 | { |
92 | s3c_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); | 90 | struct pm_uart_save *save = uart_save; |
91 | unsigned int uart; | ||
92 | |||
93 | for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++) | ||
94 | s3c_pm_save_uart(uart, save); | ||
95 | } | ||
96 | |||
97 | static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save) | ||
98 | { | ||
99 | void __iomem *regs = S3C_VA_UARTx(uart); | ||
100 | |||
101 | __raw_writel(save->ulcon, regs + S3C2410_ULCON); | ||
102 | __raw_writel(save->ucon, regs + S3C2410_UCON); | ||
103 | __raw_writel(save->ufcon, regs + S3C2410_UFCON); | ||
104 | __raw_writel(save->umcon, regs + S3C2410_UMCON); | ||
105 | __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV); | ||
93 | } | 106 | } |
94 | 107 | ||
95 | static void s3c_pm_restore_uart(void) | 108 | static void s3c_pm_restore_uarts(void) |
96 | { | 109 | { |
97 | s3c_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); | 110 | struct pm_uart_save *save = uart_save; |
111 | unsigned int uart; | ||
112 | |||
113 | for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++) | ||
114 | s3c_pm_restore_uart(uart, save); | ||
98 | } | 115 | } |
99 | #else | 116 | #else |
100 | static void s3c_pm_save_uart(void) { } | 117 | static void s3c_pm_save_uarts(void) { } |
101 | static void s3c_pm_restore_uart(void) { } | 118 | static void s3c_pm_restore_uarts(void) { } |
102 | #endif | 119 | #endif |
103 | 120 | ||
104 | /* The IRQ ext-int code goes here, it is too small to currently bother | 121 | /* 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) | |||
250 | /* save all necessary core registers not covered by the drivers */ | 267 | /* save all necessary core registers not covered by the drivers */ |
251 | 268 | ||
252 | s3c_pm_save_gpios(); | 269 | s3c_pm_save_gpios(); |
253 | s3c_pm_save_uart(); | 270 | s3c_pm_save_uarts(); |
254 | s3c_pm_save_core(); | 271 | s3c_pm_save_core(); |
255 | 272 | ||
256 | /* set the irq configuration for wake */ | 273 | /* set the irq configuration for wake */ |
@@ -293,7 +310,7 @@ static int s3c_pm_enter(suspend_state_t state) | |||
293 | /* restore the system state */ | 310 | /* restore the system state */ |
294 | 311 | ||
295 | s3c_pm_restore_core(); | 312 | s3c_pm_restore_core(); |
296 | s3c_pm_restore_uart(); | 313 | s3c_pm_restore_uarts(); |
297 | s3c_pm_restore_gpios(); | 314 | s3c_pm_restore_gpios(); |
298 | 315 | ||
299 | s3c_pm_debug_init(); | 316 | 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 @@ | |||
31 | #define S3C24XX_SZ_UART SZ_1M | 31 | #define S3C24XX_SZ_UART SZ_1M |
32 | #define S3C_UART_OFFSET (0x4000) | 32 | #define S3C_UART_OFFSET (0x4000) |
33 | 33 | ||
34 | #define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET))) | ||
35 | |||
34 | /* Timers */ | 36 | /* Timers */ |
35 | #define S3C24XX_VA_TIMER S3C_VA_TIMER | 37 | #define S3C24XX_VA_TIMER S3C_VA_TIMER |
36 | #define S3C2410_PA_TIMER (0x51000000) | 38 | #define S3C2410_PA_TIMER (0x51000000) |