aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
-rw-r--r--arch/arm/mach-omap2/pm.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 6ec2ee12272a..9b1db592759f 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -18,8 +18,8 @@
#include <plat/omap_device.h>
#include <plat/common.h>
-#include <plat/powerdomain.h>
-#include <plat/clockdomain.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
static struct omap_device_pm_latency *pm_lats;
@@ -89,10 +89,13 @@ static void omap2_init_processor_devices(void)
}
}
+/* Types of sleep_switch used in omap_set_pwrdm_state */
+#define FORCEWAKEUP_SWITCH 0
+#define LOWPOWERSTATE_SWITCH 1
+
/*
* This sets pwrdm state (other than mpu & core. Currently only ON &
- * RET are supported. Function is assuming that clkdm doesn't have
- * hw_sup mode enabled.
+ * RET are supported.
*/
int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
{
@@ -114,9 +117,14 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
return ret;
if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
- omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
- sleep_switch = 1;
- pwrdm_wait_transition(pwrdm);
+ if ((pwrdm_read_pwrst(pwrdm) > state) &&
+ (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+ sleep_switch = LOWPOWERSTATE_SWITCH;
+ } else {
+ omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+ pwrdm_wait_transition(pwrdm);
+ sleep_switch = FORCEWAKEUP_SWITCH;
+ }
}
ret = pwrdm_set_next_pwrst(pwrdm, state);
@@ -126,12 +134,22 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
goto err;
}
- if (sleep_switch) {
- omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
- pwrdm_wait_transition(pwrdm);
- pwrdm_state_switch(pwrdm);
+ switch (sleep_switch) {
+ case FORCEWAKEUP_SWITCH:
+ if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
+ omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ else
+ omap2_clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+ break;
+ case LOWPOWERSTATE_SWITCH:
+ pwrdm_set_lowpwrstchange(pwrdm);
+ break;
+ default:
+ return ret;
}
+ pwrdm_wait_transition(pwrdm);
+ pwrdm_state_switch(pwrdm);
err:
return ret;
}