diff options
author | Jean Pihet <j-pihet@ti.com> | 2010-12-09 12:39:58 -0500 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-12-21 17:29:34 -0500 |
commit | c166381d4013fd32512f124c237f4213ae9888e9 (patch) | |
tree | af6328f75dfe7099f7b92acf2cc6ef8a2edeec43 /arch | |
parent | 90a8a73c06cc32b609a880d48449d7083327e11a (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.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 16 |
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 | ||
302 | static int omap2_pm_begin(suspend_state_t state) | 302 | static int omap2_pm_begin(suspend_state_t state) |
303 | { | 303 | { |
304 | suspend_state = state; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static 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 | ||
352 | static void omap2_pm_finish(void) | ||
353 | { | ||
354 | enable_hlt(); | ||
355 | } | ||
356 | |||
357 | static void omap2_pm_end(void) | 346 | static 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 | ||
362 | static struct platform_suspend_ops omap_pm_ops = { | 352 | static 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 |
532 | static int omap3_pm_prepare(void) | ||
533 | { | ||
534 | disable_hlt(); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int omap3_pm_suspend(void) | 532 | static 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 | ||
600 | static 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 */ |
606 | static int omap3_pm_begin(suspend_state_t state) | 595 | static 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 | ||
620 | static struct platform_suspend_ops omap_pm_ops = { | 611 | static 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 { | |||
31 | static LIST_HEAD(pwrst_list); | 31 | static LIST_HEAD(pwrst_list); |
32 | 32 | ||
33 | #ifdef CONFIG_SUSPEND | 33 | #ifdef CONFIG_SUSPEND |
34 | static int omap4_pm_prepare(void) | ||
35 | { | ||
36 | disable_hlt(); | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static int omap4_pm_suspend(void) | 34 | static 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 | ||
62 | static void omap4_pm_finish(void) | ||
63 | { | ||
64 | enable_hlt(); | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | static int omap4_pm_begin(suspend_state_t state) | 56 | static int omap4_pm_begin(suspend_state_t state) |
69 | { | 57 | { |
58 | disable_hlt(); | ||
70 | return 0; | 59 | return 0; |
71 | } | 60 | } |
72 | 61 | ||
73 | static void omap4_pm_end(void) | 62 | static void omap4_pm_end(void) |
74 | { | 63 | { |
64 | enable_hlt(); | ||
75 | return; | 65 | return; |
76 | } | 66 | } |
77 | 67 | ||
78 | static struct platform_suspend_ops omap_pm_ops = { | 68 | static 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 */ |