Skip to content

Commit

Permalink
OMAP2+: PM/serial: fix console semaphore acquire during suspend
Browse files Browse the repository at this point in the history
commit 0d8e2d0 (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 <[email protected]>
Tested-by: Jean Pihet <[email protected]>
Tested-by: Paul Walmsley <[email protected]>
Signed-off-by: Kevin Hilman <[email protected]>
Signed-off-by: Tony Lindgren <[email protected]>
  • Loading branch information
metaliveblog authored and tmlind committed Dec 10, 2010
1 parent 28dd319 commit e83df17
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
34 changes: 31 additions & 3 deletions arch/arm/mach-omap2/pm24xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>

#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);
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -284,6 +299,12 @@ static void omap2_pm_idle(void)
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 */
Expand Down Expand Up @@ -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,
};

Expand Down
27 changes: 20 additions & 7 deletions arch/arm/mach-omap2/pm34xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@
#include "sdrc.h"
#include "control.h"

#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

/* Scratchpad offsets */
#define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4
#define OMAP343X_TABLE_VALUE_OFFSET 0xc0
Expand Down Expand Up @@ -387,10 +400,11 @@ void omap_sram_idle(void)
}

/* Block console output in case it is on one of the OMAP UARTs */
if (per_next_state < PWRDM_POWER_ON ||
core_next_state < PWRDM_POWER_ON)
if (try_acquire_console_sem())
goto console_still_active;
if (!is_suspending())
if (per_next_state < PWRDM_POWER_ON ||
core_next_state < PWRDM_POWER_ON)
if (try_acquire_console_sem())
goto console_still_active;

/* PER */
if (per_next_state < PWRDM_POWER_ON) {
Expand Down Expand Up @@ -470,7 +484,8 @@ void omap_sram_idle(void)
omap_uart_resume_idle(3);
}

release_console_sem();
if (!is_suspending())
release_console_sem();

console_still_active:
/* Disable IO-PAD and IO-CHAIN wakeup */
Expand Down Expand Up @@ -514,8 +529,6 @@ static void omap3_pm_idle(void)
}

#ifdef CONFIG_SUSPEND
static suspend_state_t suspend_state;

static int omap3_pm_prepare(void)
{
disable_hlt();
Expand Down

0 comments on commit e83df17

Please sign in to comment.