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) |
