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 @@
18#include <plat/omap_device.h> 18#include <plat/omap_device.h>
19#include <plat/common.h> 19#include <plat/common.h>
20 20
21#include <plat/powerdomain.h> 21#include "powerdomain.h"
22#include <plat/clockdomain.h> 22#include "clockdomain.h"
23 23
24static struct omap_device_pm_latency *pm_lats; 24static struct omap_device_pm_latency *pm_lats;
25 25
@@ -89,10 +89,13 @@ static void omap2_init_processor_devices(void)
89 } 89 }
90} 90}
91 91
92/* Types of sleep_switch used in omap_set_pwrdm_state */
93#define FORCEWAKEUP_SWITCH 0
94#define LOWPOWERSTATE_SWITCH 1
95
92/* 96/*
93 * This sets pwrdm state (other than mpu & core. Currently only ON & 97 * This sets pwrdm state (other than mpu & core. Currently only ON &
94 * RET are supported. Function is assuming that clkdm doesn't have 98 * RET are supported.
95 * hw_sup mode enabled.
96 */ 99 */
97int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) 100int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
98{ 101{
@@ -114,9 +117,14 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
114 return ret; 117 return ret;
115 118
116 if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { 119 if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
117 omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); 120 if ((pwrdm_read_pwrst(pwrdm) > state) &&
118 sleep_switch = 1; 121 (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
119 pwrdm_wait_transition(pwrdm); 122 sleep_switch = LOWPOWERSTATE_SWITCH;
123 } else {
124 omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
125 pwrdm_wait_transition(pwrdm);
126 sleep_switch = FORCEWAKEUP_SWITCH;
127 }
120 } 128 }
121 129
122 ret = pwrdm_set_next_pwrst(pwrdm, state); 130 ret = pwrdm_set_next_pwrst(pwrdm, state);
@@ -126,12 +134,22 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
126 goto err; 134 goto err;
127 } 135 }
128 136
129 if (sleep_switch) { 137 switch (sleep_switch) {
130 omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); 138 case FORCEWAKEUP_SWITCH:
131 pwrdm_wait_transition(pwrdm); 139 if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
132 pwrdm_state_switch(pwrdm); 140 omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
141 else
142 omap2_clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
143 break;
144 case LOWPOWERSTATE_SWITCH:
145 pwrdm_set_lowpwrstchange(pwrdm);
146 break;
147 default:
148 return ret;
133 } 149 }
134 150
151 pwrdm_wait_transition(pwrdm);
152 pwrdm_state_switch(pwrdm);
135err: 153err:
136 return ret; 154 return ret;
137} 155}