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 <paul@pwsan.com>
Tested-by: Jean Pihet <j-pihet@ti.com>
Tested-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>

authored by Kevin Hilman and committed by Tony Lindgren e83df17f 28dd3198

+51 -10
+31 -3
arch/arm/mach-omap2/pm24xx.c
··· 53 #include <plat/powerdomain.h> 54 #include <plat/clockdomain.h> 55 56 static void (*omap2_sram_idle)(void); 57 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, 58 void __iomem *sdrc_power); ··· 133 goto no_sleep; 134 135 /* Block console output in case it is on one of the OMAP UARTs */ 136 - if (try_acquire_console_sem()) 137 - goto no_sleep; 138 139 omap_uart_prepare_idle(0); 140 omap_uart_prepare_idle(1); ··· 150 omap_uart_resume_idle(1); 151 omap_uart_resume_idle(0); 152 153 - release_console_sem(); 154 155 no_sleep: 156 if (omap2_pm_debug) { ··· 299 local_irq_enable(); 300 } 301 302 static int omap2_pm_prepare(void) 303 { 304 /* We cannot sleep in idle until we have resumed */ ··· 354 enable_hlt(); 355 } 356 357 static struct platform_suspend_ops omap_pm_ops = { 358 .prepare = omap2_pm_prepare, 359 .enter = omap2_pm_enter, 360 .finish = omap2_pm_finish, 361 .valid = suspend_valid_only_mem, 362 }; 363
··· 53 #include <plat/powerdomain.h> 54 #include <plat/clockdomain.h> 55 56 + #ifdef CONFIG_SUSPEND 57 + static suspend_state_t suspend_state = PM_SUSPEND_ON; 58 + static inline bool is_suspending(void) 59 + { 60 + return (suspend_state != PM_SUSPEND_ON); 61 + } 62 + #else 63 + static inline bool is_suspending(void) 64 + { 65 + return false; 66 + } 67 + #endif 68 + 69 static void (*omap2_sram_idle)(void); 70 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, 71 void __iomem *sdrc_power); ··· 120 goto no_sleep; 121 122 /* Block console output in case it is on one of the OMAP UARTs */ 123 + if (!is_suspending()) 124 + if (try_acquire_console_sem()) 125 + goto no_sleep; 126 127 omap_uart_prepare_idle(0); 128 omap_uart_prepare_idle(1); ··· 136 omap_uart_resume_idle(1); 137 omap_uart_resume_idle(0); 138 139 + if (!is_suspending()) 140 + release_console_sem(); 141 142 no_sleep: 143 if (omap2_pm_debug) { ··· 284 local_irq_enable(); 285 } 286 287 + static int omap2_pm_begin(suspend_state_t state) 288 + { 289 + suspend_state = state; 290 + return 0; 291 + } 292 + 293 static int omap2_pm_prepare(void) 294 { 295 /* We cannot sleep in idle until we have resumed */ ··· 333 enable_hlt(); 334 } 335 336 + static void omap2_pm_end(void) 337 + { 338 + suspend_state = PM_SUSPEND_ON; 339 + } 340 + 341 static struct platform_suspend_ops omap_pm_ops = { 342 + .begin = omap2_pm_begin, 343 .prepare = omap2_pm_prepare, 344 .enter = omap2_pm_enter, 345 .finish = omap2_pm_finish, 346 + .end = omap2_pm_end, 347 .valid = suspend_valid_only_mem, 348 }; 349
+20 -7
arch/arm/mach-omap2/pm34xx.c
··· 50 #include "sdrc.h" 51 #include "control.h" 52 53 /* Scratchpad offsets */ 54 #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 55 #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 ··· 400 } 401 402 /* Block console output in case it is on one of the OMAP UARTs */ 403 - if (per_next_state < PWRDM_POWER_ON || 404 - core_next_state < PWRDM_POWER_ON) 405 - if (try_acquire_console_sem()) 406 - goto console_still_active; 407 408 /* PER */ 409 if (per_next_state < PWRDM_POWER_ON) { ··· 484 omap_uart_resume_idle(3); 485 } 486 487 - release_console_sem(); 488 489 console_still_active: 490 /* Disable IO-PAD and IO-CHAIN wakeup */ ··· 529 } 530 531 #ifdef CONFIG_SUSPEND 532 - static suspend_state_t suspend_state; 533 - 534 static int omap3_pm_prepare(void) 535 { 536 disable_hlt();
··· 50 #include "sdrc.h" 51 #include "control.h" 52 53 + #ifdef CONFIG_SUSPEND 54 + static suspend_state_t suspend_state = PM_SUSPEND_ON; 55 + static inline bool is_suspending(void) 56 + { 57 + return (suspend_state != PM_SUSPEND_ON); 58 + } 59 + #else 60 + static inline bool is_suspending(void) 61 + { 62 + return false; 63 + } 64 + #endif 65 + 66 /* Scratchpad offsets */ 67 #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 68 #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 ··· 387 } 388 389 /* Block console output in case it is on one of the OMAP UARTs */ 390 + if (!is_suspending()) 391 + if (per_next_state < PWRDM_POWER_ON || 392 + core_next_state < PWRDM_POWER_ON) 393 + if (try_acquire_console_sem()) 394 + goto console_still_active; 395 396 /* PER */ 397 if (per_next_state < PWRDM_POWER_ON) { ··· 470 omap_uart_resume_idle(3); 471 } 472 473 + if (!is_suspending()) 474 + release_console_sem(); 475 476 console_still_active: 477 /* Disable IO-PAD and IO-CHAIN wakeup */ ··· 514 } 515 516 #ifdef CONFIG_SUSPEND 517 static int omap3_pm_prepare(void) 518 { 519 disable_hlt();