From e83df17f178360a8e7874441bca04a710c869e42 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 8 Dec 2010 22:40:40 +0000 Subject: OMAP2+: PM/serial: fix console semaphore acquire during suspend commit 0d8e2d0dad98a693bad88aea6876ac8b94ad95c6 (OMAP2+: PM/serial: hold console semaphore while OMAP UARTs are disabled) added use of the console semaphore to protect UARTs from being accessed after disabled during idle, but this causes problems in suspend. During suspend, the console semaphore is acquired by the console suspend method (console_suspend()) so the try_acquire_console_sem() will always fail and suspend will be aborted. To fix, introduce a check so the console semaphore is only attempted during idle, and not during suspend. Also use the same check so that the console semaphore is not prematurely released during resume. Thanks to Paul Walmsley for suggesting adding the same check during resume. Cc: Paul Walmsley Tested-by: Jean Pihet Tested-by: Paul Walmsley Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pm24xx.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-omap2/pm24xx.c') diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c85923e56b8..aaeea49b9bd 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -53,6 +53,19 @@ #include #include +#ifdef CONFIG_SUSPEND +static suspend_state_t suspend_state = PM_SUSPEND_ON; +static inline bool is_suspending(void) +{ + return (suspend_state != PM_SUSPEND_ON); +} +#else +static inline bool is_suspending(void) +{ + return false; +} +#endif + static void (*omap2_sram_idle)(void); static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, void __iomem *sdrc_power); @@ -120,8 +133,9 @@ static void omap2_enter_full_retention(void) goto no_sleep; /* Block console output in case it is on one of the OMAP UARTs */ - if (try_acquire_console_sem()) - goto no_sleep; + if (!is_suspending()) + if (try_acquire_console_sem()) + goto no_sleep; omap_uart_prepare_idle(0); omap_uart_prepare_idle(1); @@ -136,7 +150,8 @@ static void omap2_enter_full_retention(void) omap_uart_resume_idle(1); omap_uart_resume_idle(0); - release_console_sem(); + if (!is_suspending()) + release_console_sem(); no_sleep: if (omap2_pm_debug) { @@ -284,6 +299,12 @@ out: local_irq_enable(); } +static int omap2_pm_begin(suspend_state_t state) +{ + suspend_state = state; + return 0; +} + static int omap2_pm_prepare(void) { /* We cannot sleep in idle until we have resumed */ @@ -333,10 +354,17 @@ static void omap2_pm_finish(void) enable_hlt(); } +static void omap2_pm_end(void) +{ + suspend_state = PM_SUSPEND_ON; +} + static struct platform_suspend_ops omap_pm_ops = { + .begin = omap2_pm_begin, .prepare = omap2_pm_prepare, .enter = omap2_pm_enter, .finish = omap2_pm_finish, + .end = omap2_pm_end, .valid = suspend_valid_only_mem, }; -- cgit v1.2.3-70-g09d2