diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 40 |
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; } |