提交 c166381d 编写于 作者: J Jean Pihet 提交者: Kevin Hilman

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: NJean Pihet <j-pihet@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: NKevin Hilman <khilman@deeprootsystems.com>
上级 90a8a73c
...@@ -301,14 +301,8 @@ static void omap2_pm_idle(void) ...@@ -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) ...@@ -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,
}; };
......
...@@ -529,12 +529,6 @@ static void omap3_pm_idle(void) ...@@ -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) ...@@ -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) ...@@ -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 */
......
...@@ -31,12 +31,6 @@ struct power_state { ...@@ -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) ...@@ -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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册