aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJean Pihet <j-pihet@ti.com>2010-12-09 12:39:58 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-12-21 17:29:34 -0500
commitc166381d4013fd32512f124c237f4213ae9888e9 (patch)
treeaf6328f75dfe7099f7b92acf2cc6ef8a2edeec43 /arch
parent90a8a73c06cc32b609a880d48449d7083327e11a (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/pm24xx.c16
-rw-r--r--arch/arm/mach-omap2/pm34xx.c15
-rw-r--r--arch/arm/mach-omap2/pm44xx.c16
3 files changed, 6 insertions, 41 deletions
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index aaeea49b9bdd..aea7ced9a2ff 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -301,14 +301,8 @@ out:
301 301
302static int omap2_pm_begin(suspend_state_t state) 302static int omap2_pm_begin(suspend_state_t state)
303{ 303{
304 suspend_state = state;
305 return 0;
306}
307
308static int omap2_pm_prepare(void)
309{
310 /* We cannot sleep in idle until we have resumed */
311 disable_hlt(); 304 disable_hlt();
305 suspend_state = state;
312 return 0; 306 return 0;
313} 307}
314 308
@@ -349,21 +343,15 @@ static int omap2_pm_enter(suspend_state_t state)
349 return ret; 343 return ret;
350} 344}
351 345
352static void omap2_pm_finish(void)
353{
354 enable_hlt();
355}
356
357static void omap2_pm_end(void) 346static void omap2_pm_end(void)
358{ 347{
359 suspend_state = PM_SUSPEND_ON; 348 suspend_state = PM_SUSPEND_ON;
349 enable_hlt();
360} 350}
361 351
362static struct platform_suspend_ops omap_pm_ops = { 352static struct platform_suspend_ops omap_pm_ops = {
363 .begin = omap2_pm_begin, 353 .begin = omap2_pm_begin,
364 .prepare = omap2_pm_prepare,
365 .enter = omap2_pm_enter, 354 .enter = omap2_pm_enter,
366 .finish = omap2_pm_finish,
367 .end = omap2_pm_end, 355 .end = omap2_pm_end,
368 .valid = suspend_valid_only_mem, 356 .valid = suspend_valid_only_mem,
369}; 357};
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 648b8c50d024..5bf344a3fcf5 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -529,12 +529,6 @@ out:
529} 529}
530 530
531#ifdef CONFIG_SUSPEND 531#ifdef CONFIG_SUSPEND
532static int omap3_pm_prepare(void)
533{
534 disable_hlt();
535 return 0;
536}
537
538static int omap3_pm_suspend(void) 532static int omap3_pm_suspend(void)
539{ 533{
540 struct power_state *pwrst; 534 struct power_state *pwrst;
@@ -597,14 +591,10 @@ static int omap3_pm_enter(suspend_state_t unused)
597 return ret; 591 return ret;
598} 592}
599 593
600static void omap3_pm_finish(void)
601{
602 enable_hlt();
603}
604
605/* Hooks to enable / disable UART interrupts during suspend */ 594/* Hooks to enable / disable UART interrupts during suspend */
606static int omap3_pm_begin(suspend_state_t state) 595static int omap3_pm_begin(suspend_state_t state)
607{ 596{
597 disable_hlt();
608 suspend_state = state; 598 suspend_state = state;
609 omap_uart_enable_irqs(0); 599 omap_uart_enable_irqs(0);
610 return 0; 600 return 0;
@@ -614,15 +604,14 @@ static void omap3_pm_end(void)
614{ 604{
615 suspend_state = PM_SUSPEND_ON; 605 suspend_state = PM_SUSPEND_ON;
616 omap_uart_enable_irqs(1); 606 omap_uart_enable_irqs(1);
607 enable_hlt();
617 return; 608 return;
618} 609}
619 610
620static struct platform_suspend_ops omap_pm_ops = { 611static struct platform_suspend_ops omap_pm_ops = {
621 .begin = omap3_pm_begin, 612 .begin = omap3_pm_begin,
622 .end = omap3_pm_end, 613 .end = omap3_pm_end,
623 .prepare = omap3_pm_prepare,
624 .enter = omap3_pm_enter, 614 .enter = omap3_pm_enter,
625 .finish = omap3_pm_finish,
626 .valid = suspend_valid_only_mem, 615 .valid = suspend_valid_only_mem,
627}; 616};
628#endif /* CONFIG_SUSPEND */ 617#endif /* CONFIG_SUSPEND */
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 54544b4fc76b..6aff9961e35d 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -31,12 +31,6 @@ struct power_state {
31static LIST_HEAD(pwrst_list); 31static LIST_HEAD(pwrst_list);
32 32
33#ifdef CONFIG_SUSPEND 33#ifdef CONFIG_SUSPEND
34static int omap4_pm_prepare(void)
35{
36 disable_hlt();
37 return 0;
38}
39
40static int omap4_pm_suspend(void) 34static int omap4_pm_suspend(void)
41{ 35{
42 do_wfi(); 36 do_wfi();
@@ -59,28 +53,22 @@ static int omap4_pm_enter(suspend_state_t suspend_state)
59 return ret; 53 return ret;
60} 54}
61 55
62static void omap4_pm_finish(void)
63{
64 enable_hlt();
65 return;
66}
67
68static int omap4_pm_begin(suspend_state_t state) 56static int omap4_pm_begin(suspend_state_t state)
69{ 57{
58 disable_hlt();
70 return 0; 59 return 0;
71} 60}
72 61
73static void omap4_pm_end(void) 62static void omap4_pm_end(void)
74{ 63{
64 enable_hlt();
75 return; 65 return;
76} 66}
77 67
78static struct platform_suspend_ops omap_pm_ops = { 68static struct platform_suspend_ops omap_pm_ops = {
79 .begin = omap4_pm_begin, 69 .begin = omap4_pm_begin,
80 .end = omap4_pm_end, 70 .end = omap4_pm_end,
81 .prepare = omap4_pm_prepare,
82 .enter = omap4_pm_enter, 71 .enter = omap4_pm_enter,
83 .finish = omap4_pm_finish,
84 .valid = suspend_valid_only_mem, 72 .valid = suspend_valid_only_mem,
85}; 73};
86#endif /* CONFIG_SUSPEND */ 74#endif /* CONFIG_SUSPEND */