From: Michael Spang Date: Fri, 9 Nov 2012 19:33:47 +0000 (-0500) Subject: CHROMIUM: serial: exynos: Resume UART earlier with SAMSUNG_PM_DEBUG X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=7ec6a1e273e61526b5836c63981b557396ffe252;p=people%2Faperard%2Flinux-chromebook.git CHROMIUM: serial: exynos: Resume UART earlier with SAMSUNG_PM_DEBUG Even with SAMSUNG_PM_DEBUG enabled, we're losing lots of console UART output during resume. This patch makes SAMSUNG_PM_DEBUG correcly resume the UART as early as possible, so that no output is lost. BUG=chrome-os-partner:10932 TEST=powerd_suspend with no_console_suspend and SAMSUNG_PM_DEBUG Change-Id: Ic892ed225c9075e8d72d851a4f2e22263ee6047d Signed-off-by: Michael Spang Reviewed-on: https://gerrit.chromium.org/gerrit/37734 Reviewed-by: Jon Kliegman --- diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h index 7dbbfec13ea5b..360e8f64c36ad 100644 --- a/arch/arm/mach-exynos/include/mach/pm-core.h +++ b/arch/arm/mach-exynos/include/mach/pm-core.h @@ -18,13 +18,36 @@ #ifndef __ASM_ARCH_PM_CORE_H #define __ASM_ARCH_PM_CORE_H __FILE__ +#include +#include #include +#include +#include static inline void s3c_pm_debug_init_uart(void) { /* nothing here yet */ } +#ifdef CONFIG_SAMSUNG_PM_DEBUG + +static inline void s3c_pm_arch_restore_uarts(void) +{ + if (soc_is_exynos5250()) { + WARN_ON_ONCE(!(__raw_readl(S5P_PAD_RET_UART_OPTION) & + EXYNOS5_PAD_RET_UART_AUTOMATIC_WAKEUP)); + + /* force gpio pins GPA1(4) and GPA1(5) to UART3 mode */ + s3c_gpio_cfgpin(EXYNOS5_GPA1(4), S3C_GPIO_SPECIAL(2)); + s3c_gpio_cfgpin(EXYNOS5_GPA1(5), S3C_GPIO_SPECIAL(2)); + + /* wait for things to settle */ + mdelay(1); + } +} + +#endif + static inline void s3c_pm_arch_prepare_irqs(void) { __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index ed99e6c09c85e..e3b2302656f7d 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -165,6 +165,7 @@ #define S5P_PAD_RET_MAUDIO_OPTION S5P_PMUREG(0x3028) #define S5P_PAD_RET_GPIO_OPTION S5P_PMUREG(0x3108) +#define S5P_PAD_RET_UART_STATUS S5P_PMUREG(0x3124) #define S5P_PAD_RET_UART_OPTION S5P_PMUREG(0x3128) #define S5P_PAD_RET_MMCA_OPTION S5P_PMUREG(0x3148) #define S5P_PAD_RET_MMCB_OPTION S5P_PMUREG(0x3168) @@ -385,6 +386,8 @@ #define EXYNOS5_OPTION_USE_RETENTION (1 << 4) +#define EXYNOS5_PAD_RET_UART_AUTOMATIC_WAKEUP (1 << 29) + #define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x234) #define EXYNOS5_SYS_DISP1BLK_CFG S5P_SYSREG(0x214) #define ENABLE_FIMDBYPASS_DISP1 (1 << 15) diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index fadaaf51b11d0..8c3824d846716 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -349,6 +349,18 @@ static void exynos5_power_off(void) ; } +static void exynos5_debug_enable_uart_wakeup(void) +{ +#ifdef CONFIG_SAMSUNG_PM_DEBUG + unsigned int tmp; + + /* Enable UART automatic wakeup for resume console output */ + tmp = __raw_readl(S5P_PAD_RET_UART_OPTION); + tmp |= EXYNOS5_PAD_RET_UART_AUTOMATIC_WAKEUP; + __raw_writel(tmp, S5P_PAD_RET_UART_OPTION); +#endif +} + static void exynos5_init_pmu(void) { unsigned int i; @@ -382,6 +394,8 @@ static void exynos5_init_pmu(void) EXYNOS5_OPTION_USE_STANDBYWFI); __raw_writel(tmp, exynos5_list_diable_wfi_wfe[i]); } + + exynos5_debug_enable_uart_wakeup(); } void exynos4_sys_powerdown_conf(enum sys_powerdown mode) diff --git a/arch/arm/mach-s3c24xx/include/mach/pm-core.h b/arch/arm/mach-s3c24xx/include/mach/pm-core.h index 2eef7e6f76758..01718f4c1b101 100644 --- a/arch/arm/mach-s3c24xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c24xx/include/mach/pm-core.h @@ -24,6 +24,15 @@ static inline void s3c_pm_debug_init_uart(void) udelay(10); } +#ifdef CONFIG_SAMSUNG_PM_DEBUG + +static inline void s3c_pm_arch_restore_uarts(void) +{ + /* nothing here yet */ +} + +#endif + static inline void s3c_pm_arch_prepare_irqs(void) { __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK); diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h index fcf3dcabb6944..307cff5256386 100644 --- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h @@ -33,6 +33,15 @@ static inline void s3c_pm_debug_init_uart(void) udelay(10); } +#ifdef CONFIG_SAMSUNG_PM_DEBUG + +static inline void s3c_pm_arch_restore_uarts(void) +{ + /* nothing here yet */ +} + +#endif + static inline void s3c_pm_arch_prepare_irqs(void) { /* VIC should have already been taken care of */ diff --git a/arch/arm/mach-s5p64x0/include/mach/pm-core.h b/arch/arm/mach-s5p64x0/include/mach/pm-core.h index e52f7545d3aa6..230d451e2595e 100644 --- a/arch/arm/mach-s5p64x0/include/mach/pm-core.h +++ b/arch/arm/mach-s5p64x0/include/mach/pm-core.h @@ -33,6 +33,15 @@ static inline void s3c_pm_debug_init_uart(void) udelay(10); } +#ifdef CONFIG_SAMSUNG_PM_DEBUG + +static inline void s3c_pm_arch_restore_uarts(void) +{ + /* nothing here yet */ +} + +#endif + static inline void s3c_pm_arch_prepare_irqs(void) { /* VIC should have already been taken care of */ diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h index eba8aea63ed8f..457438093761d 100644 --- a/arch/arm/mach-s5pv210/include/mach/pm-core.h +++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h @@ -20,6 +20,15 @@ static inline void s3c_pm_debug_init_uart(void) /* nothing here yet */ } +#ifdef CONFIG_SAMSUNG_PM_DEBUG + +static inline void s3c_pm_arch_restore_uarts(void) +{ + /* nothing here yet */ +} + +#endif + static inline void s3c_pm_arch_prepare_irqs(void) { __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK); diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index a4336a5faa3b1..76962d2a19b50 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -125,6 +125,8 @@ static void s3c_pm_restore_uarts(void) for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++) s3c_pm_restore_uart(uart, save); + + s3c_pm_arch_restore_uarts(); } static void s3c_pm_drain_uart(int uart)