summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2010-08-30 12:52:55 +0530
committerSantosh Shilimkar <santosh.shilimkar@ti.com>2010-09-06 17:22:12 +0530
commit90c29472e97a7d7eb2943fb1edb4aab9ab89570c (patch)
treef2064d18152cf7dd1f6e6ba5c2801d6aa91e5462
parente9646569cec451fafeb606a8328fafb8859a6fc0 (diff)
omap4: pm: Fix the cpuidle barriers and restore CPUx state
This patch fixes two issues. 1. Barriers in the cpudile path 2. Restoration of CPUx state, to avoid accidental transitions of CPUx power domain to low power states while executing WFI outside the idle thread. Secure software and hotplog path are examples of this problems Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c6
-rw-r--r--arch/arm/mach-omap2/omap4-mpuss-lowpower.c17
2 files changed, 19 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 53fe278cc295..3686e0763c77 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -85,8 +85,8 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
* Do only WFI for non-boot CPU(aux cores)
*/
if (dev->cpu) {
- do_wfi();
wmb();
+ do_wfi();
goto return_sleep_time;
}
@@ -94,8 +94,8 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
* Do only a WFI as long as CPU1 is online
*/
if (num_online_cpus() > 1) {
- do_wfi();
wmb();
+ do_wfi();
goto return_sleep_time;
}
@@ -104,8 +104,8 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
*/
cpu1_state = pwrdm_read_pwrst(cpu1_pd);
if (cpu1_state != PWRDM_POWER_OFF) {
- do_wfi();
wmb();
+ do_wfi();
goto return_sleep_time;
}
diff --git a/arch/arm/mach-omap2/omap4-mpuss-lowpower.c b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
index 12245ea56795..5ca9298492e1 100644
--- a/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap4-mpuss-lowpower.c
@@ -502,11 +502,26 @@ cpu_prepare:
* targeted power state
*/
__omap4_cpu_suspend(cpu, save_state);
+ wakeup_cpu = hard_smp_processor_id();
+
+ /*
+ * Restore the CPUx and mpuss power state to ON otherwise
+ * CPUx power domain can transitions to programmed low power
+ * state while doing WFI outside the low powe code. On HS devices,
+ * CPUx can do WFI outside idle thread which can result in
+ * power domain domain transition if the previous state was
+ * programmed to OFF/RET.
+ */
+ if (wakeup_cpu) {
+ pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
+ } else {
+ pwrdm_set_next_pwrst(cpu0_pwrdm, PWRDM_POWER_ON);
+ pwrdm_set_next_pwrst(mpuss_pd, PWRDM_POWER_ON);
+ }
/*
* Check the CPUx previous power state
*/
- wakeup_cpu = hard_smp_processor_id();
if (read_cpu_prev_pwrst(wakeup_cpu) == PWRDM_POWER_OFF) {
cpu_init();
restore_mmu_table_entry();