aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/cpuidle34xx.c
diff options
context:
space:
mode:
authorJean Pihet <j-pihet@ti.com>2011-05-09 06:02:16 -0400
committerKevin Hilman <khilman@ti.com>2011-05-20 11:15:54 -0400
commit04908918191f7926ec7af99890fb4ddb3b769c13 (patch)
tree96a531896df79761459d6f10735a5aa85b484a31 /arch/arm/mach-omap2/cpuidle34xx.c
parentc6cd91de1cb4694f2dfcc7df831e276fffdffffc (diff)
OMAP3: cpuidle: change the power domains modes determination logic
The achievable power modes of the power domains in cpuidle depends on the system wide 'enable_off_mode' knob in debugfs. Upon changing enable_off_mode, do not change the C-states 'valid' field but instead dynamically restrict the power modes when entering idle. The C-states 'valid' field is just used to enable/disable some C-states at init and shall not be changed later on. Signed-off-by: Jean Pihet <j-pihet@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/cpuidle34xx.c')
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c58
1 files changed, 24 insertions, 34 deletions
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index dd31e539274c..4bf6e6e8b100 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -138,22 +138,40 @@ return_sleep_time:
138} 138}
139 139
140/** 140/**
141 * next_valid_state - Find next valid c-state 141 * next_valid_state - Find next valid C-state
142 * @dev: cpuidle device 142 * @dev: cpuidle device
143 * @state: Currently selected c-state 143 * @state: Currently selected C-state
144 * 144 *
145 * If the current state is valid, it is returned back to the caller. 145 * If the current state is valid, it is returned back to the caller.
146 * Else, this function searches for a lower c-state which is still 146 * Else, this function searches for a lower c-state which is still
147 * valid. 147 * valid.
148 *
149 * A state is valid if the 'valid' field is enabled and
150 * if it satisfies the enable_off_mode condition.
148 */ 151 */
149static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, 152static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
150 struct cpuidle_state *curr) 153 struct cpuidle_state *curr)
151{ 154{
152 struct cpuidle_state *next = NULL; 155 struct cpuidle_state *next = NULL;
153 struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr); 156 struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
157 u32 mpu_deepest_state = PWRDM_POWER_RET;
158 u32 core_deepest_state = PWRDM_POWER_RET;
159
160 if (enable_off_mode) {
161 mpu_deepest_state = PWRDM_POWER_OFF;
162 /*
163 * Erratum i583: valable for ES rev < Es1.2 on 3630.
164 * CORE OFF mode is not supported in a stable form, restrict
165 * instead the CORE state to RET.
166 */
167 if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
168 core_deepest_state = PWRDM_POWER_OFF;
169 }
154 170
155 /* Check if current state is valid */ 171 /* Check if current state is valid */
156 if (cx->valid) { 172 if ((cx->valid) &&
173 (cx->mpu_state >= mpu_deepest_state) &&
174 (cx->core_state >= core_deepest_state)) {
157 return curr; 175 return curr;
158 } else { 176 } else {
159 int idx = OMAP3_NUM_STATES - 1; 177 int idx = OMAP3_NUM_STATES - 1;
@@ -176,7 +194,9 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
176 idx--; 194 idx--;
177 for (; idx >= 0; idx--) { 195 for (; idx >= 0; idx--) {
178 cx = cpuidle_get_statedata(&dev->states[idx]); 196 cx = cpuidle_get_statedata(&dev->states[idx]);
179 if (cx->valid) { 197 if ((cx->valid) &&
198 (cx->mpu_state >= mpu_deepest_state) &&
199 (cx->core_state >= core_deepest_state)) {
180 next = &dev->states[idx]; 200 next = &dev->states[idx];
181 break; 201 break;
182 } 202 }
@@ -259,31 +279,6 @@ select_state:
259 279
260DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); 280DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
261 281
262/**
263 * omap3_cpuidle_update_states() - Update the cpuidle states
264 * @mpu_deepest_state: Enable states up to and including this for mpu domain
265 * @core_deepest_state: Enable states up to and including this for core domain
266 *
267 * This goes through the list of states available and enables and disables the
268 * validity of C states based on deepest state that can be achieved for the
269 * variable domain
270 */
271void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state)
272{
273 int i;
274
275 for (i = 0; i < OMAP3_NUM_STATES; i++) {
276 struct omap3_idle_statedata *cx = &omap3_idle_data[i];
277
278 if ((cx->mpu_state >= mpu_deepest_state) &&
279 (cx->core_state >= core_deepest_state)) {
280 cx->valid = 1;
281 } else {
282 cx->valid = 0;
283 }
284 }
285}
286
287void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) 282void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
288{ 283{
289 int i; 284 int i;
@@ -393,11 +388,6 @@ int __init omap3_idle_init(void)
393 cx->mpu_state = PWRDM_POWER_OFF; 388 cx->mpu_state = PWRDM_POWER_OFF;
394 cx->core_state = PWRDM_POWER_OFF; 389 cx->core_state = PWRDM_POWER_OFF;
395 390
396 if (enable_off_mode)
397 omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF);
398 else
399 omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET);
400
401 dev->state_count = OMAP3_NUM_STATES; 391 dev->state_count = OMAP3_NUM_STATES;
402 if (cpuidle_register_device(dev)) { 392 if (cpuidle_register_device(dev)) {
403 printk(KERN_ERR "%s: CPUidle register device failed\n", 393 printk(KERN_ERR "%s: CPUidle register device failed\n",