OMAP2+: disable idle early in the suspend sequence

Some bad interaction between the idle and the suspend paths has been
identified: the idle code is called during the suspend enter and exit
sequences. This could cause corruption or lock-up of resources.

The solution is to move the calls to disable_hlt at the very beginning
of the suspend sequence (ex. in omap3_pm_begin instead of
omap3_pm_prepare), and the call to enable_hlt at the very end of
the suspend sequence (ex. in omap3_pm_end instead of omap3_pm_finish).

Tested with RET and OFF on Beagle and OMAP3EVM.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
This commit is contained in:
Jean Pihet 2010-12-09 18:39:58 +01:00 committed by Kevin Hilman
parent 90a8a73c06
commit c166381d40
3 changed files with 6 additions and 41 deletions

View File

@ -301,14 +301,8 @@ static void omap2_pm_idle(void)
static int omap2_pm_begin(suspend_state_t state) 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 */
disable_hlt(); disable_hlt();
suspend_state = state;
return 0; return 0;
} }
@ -349,21 +343,15 @@ static int omap2_pm_enter(suspend_state_t state)
return ret; return ret;
} }
static void omap2_pm_finish(void)
{
enable_hlt();
}
static void omap2_pm_end(void) static void omap2_pm_end(void)
{ {
suspend_state = PM_SUSPEND_ON; suspend_state = PM_SUSPEND_ON;
enable_hlt();
} }
static struct platform_suspend_ops omap_pm_ops = { static struct platform_suspend_ops omap_pm_ops = {
.begin = omap2_pm_begin, .begin = omap2_pm_begin,
.prepare = omap2_pm_prepare,
.enter = omap2_pm_enter, .enter = omap2_pm_enter,
.finish = omap2_pm_finish,
.end = omap2_pm_end, .end = omap2_pm_end,
.valid = suspend_valid_only_mem, .valid = suspend_valid_only_mem,
}; };

View File

@ -529,12 +529,6 @@ static void omap3_pm_idle(void)
} }
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
static int omap3_pm_prepare(void)
{
disable_hlt();
return 0;
}
static int omap3_pm_suspend(void) static int omap3_pm_suspend(void)
{ {
struct power_state *pwrst; struct power_state *pwrst;
@ -597,14 +591,10 @@ static int omap3_pm_enter(suspend_state_t unused)
return ret; return ret;
} }
static void omap3_pm_finish(void)
{
enable_hlt();
}
/* Hooks to enable / disable UART interrupts during suspend */ /* Hooks to enable / disable UART interrupts during suspend */
static int omap3_pm_begin(suspend_state_t state) static int omap3_pm_begin(suspend_state_t state)
{ {
disable_hlt();
suspend_state = state; suspend_state = state;
omap_uart_enable_irqs(0); omap_uart_enable_irqs(0);
return 0; return 0;
@ -614,15 +604,14 @@ static void omap3_pm_end(void)
{ {
suspend_state = PM_SUSPEND_ON; suspend_state = PM_SUSPEND_ON;
omap_uart_enable_irqs(1); omap_uart_enable_irqs(1);
enable_hlt();
return; return;
} }
static struct platform_suspend_ops omap_pm_ops = { static struct platform_suspend_ops omap_pm_ops = {
.begin = omap3_pm_begin, .begin = omap3_pm_begin,
.end = omap3_pm_end, .end = omap3_pm_end,
.prepare = omap3_pm_prepare,
.enter = omap3_pm_enter, .enter = omap3_pm_enter,
.finish = omap3_pm_finish,
.valid = suspend_valid_only_mem, .valid = suspend_valid_only_mem,
}; };
#endif /* CONFIG_SUSPEND */ #endif /* CONFIG_SUSPEND */

View File

@ -31,12 +31,6 @@ struct power_state {
static LIST_HEAD(pwrst_list); static LIST_HEAD(pwrst_list);
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
static int omap4_pm_prepare(void)
{
disable_hlt();
return 0;
}
static int omap4_pm_suspend(void) static int omap4_pm_suspend(void)
{ {
do_wfi(); do_wfi();
@ -59,28 +53,22 @@ static int omap4_pm_enter(suspend_state_t suspend_state)
return ret; return ret;
} }
static void omap4_pm_finish(void)
{
enable_hlt();
return;
}
static int omap4_pm_begin(suspend_state_t state) static int omap4_pm_begin(suspend_state_t state)
{ {
disable_hlt();
return 0; return 0;
} }
static void omap4_pm_end(void) static void omap4_pm_end(void)
{ {
enable_hlt();
return; return;
} }
static struct platform_suspend_ops omap_pm_ops = { static struct platform_suspend_ops omap_pm_ops = {
.begin = omap4_pm_begin, .begin = omap4_pm_begin,
.end = omap4_pm_end, .end = omap4_pm_end,
.prepare = omap4_pm_prepare,
.enter = omap4_pm_enter, .enter = omap4_pm_enter,
.finish = omap4_pm_finish,
.valid = suspend_valid_only_mem, .valid = suspend_valid_only_mem,
}; };
#endif /* CONFIG_SUSPEND */ #endif /* CONFIG_SUSPEND */