Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e83df17f authored by Kevin Hilman's avatar Kevin Hilman Committed by Tony Lindgren
Browse files

OMAP2+: PM/serial: fix console semaphore acquire during suspend



commit 0d8e2d0d (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: default avatarJean Pihet <j-pihet@ti.com>
Tested-by: default avatarPaul Walmsley <paul@pwsan.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 28dd3198
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -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);
@@ -120,6 +133,7 @@ static void omap2_enter_full_retention(void)
		goto no_sleep;

	/* Block console output in case it is on one of the OMAP UARTs */
	if (!is_suspending())
		if (try_acquire_console_sem())
			goto no_sleep;

@@ -136,6 +150,7 @@ static void omap2_enter_full_retention(void)
	omap_uart_resume_idle(1);
	omap_uart_resume_idle(0);

	if (!is_suspending())
		release_console_sem();

no_sleep:
@@ -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,
};

+20 −7
Original line number Diff line number Diff line
@@ -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
@@ -387,6 +400,7 @@ void omap_sram_idle(void)
	}

	/* Block console output in case it is on one of the OMAP UARTs */
	if (!is_suspending())
		if (per_next_state < PWRDM_POWER_ON ||
		    core_next_state < PWRDM_POWER_ON)
			if (try_acquire_console_sem())
@@ -470,6 +484,7 @@ void omap_sram_idle(void)
		omap_uart_resume_idle(3);
	}

	if (!is_suspending())
		release_console_sem();

console_still_active:
@@ -514,8 +529,6 @@ out:
}

#ifdef CONFIG_SUSPEND
static suspend_state_t suspend_state;

static int omap3_pm_prepare(void)
{
	disable_hlt();