aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/cpuidle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpuidle/cpuidle.c')
-rw-r--r--drivers/cpuidle/cpuidle.c85
1 files changed, 57 insertions, 28 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index d90519cec880..bb4e827434ce 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -92,6 +92,34 @@ int cpuidle_play_dead(void)
92} 92}
93 93
94/** 94/**
95 * cpuidle_enter_state - enter the state and update stats
96 * @dev: cpuidle device for this cpu
97 * @drv: cpuidle driver for this cpu
98 * @next_state: index into drv->states of the state to enter
99 */
100int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
101 int next_state)
102{
103 int entered_state;
104
105 entered_state = cpuidle_enter_ops(dev, drv, next_state);
106
107 if (entered_state >= 0) {
108 /* Update cpuidle counters */
109 /* This can be moved to within driver enter routine
110 * but that results in multiple copies of same code.
111 */
112 dev->states_usage[entered_state].time +=
113 (unsigned long long)dev->last_residency;
114 dev->states_usage[entered_state].usage++;
115 } else {
116 dev->last_residency = 0;
117 }
118
119 return entered_state;
120}
121
122/**
95 * cpuidle_idle_call - the main idle loop 123 * cpuidle_idle_call - the main idle loop
96 * 124 *
97 * NOTE: no locks or semaphores should be used here 125 * NOTE: no locks or semaphores should be used here
@@ -113,15 +141,6 @@ int cpuidle_idle_call(void)
113 if (!dev || !dev->enabled) 141 if (!dev || !dev->enabled)
114 return -EBUSY; 142 return -EBUSY;
115 143
116#if 0
117 /* shows regressions, re-enable for 2.6.29 */
118 /*
119 * run any timers that can be run now, at this point
120 * before calculating the idle duration etc.
121 */
122 hrtimer_peek_ahead_timers();
123#endif
124
125 /* ask the governor for the next state */ 144 /* ask the governor for the next state */
126 next_state = cpuidle_curr_governor->select(drv, dev); 145 next_state = cpuidle_curr_governor->select(drv, dev);
127 if (need_resched()) { 146 if (need_resched()) {
@@ -132,23 +151,15 @@ int cpuidle_idle_call(void)
132 trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu); 151 trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu);
133 trace_cpu_idle_rcuidle(next_state, dev->cpu); 152 trace_cpu_idle_rcuidle(next_state, dev->cpu);
134 153
135 entered_state = cpuidle_enter_ops(dev, drv, next_state); 154 if (cpuidle_state_is_coupled(dev, drv, next_state))
155 entered_state = cpuidle_enter_state_coupled(dev, drv,
156 next_state);
157 else
158 entered_state = cpuidle_enter_state(dev, drv, next_state);
136 159
137 trace_power_end_rcuidle(dev->cpu); 160 trace_power_end_rcuidle(dev->cpu);
138 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); 161 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
139 162
140 if (entered_state >= 0) {
141 /* Update cpuidle counters */
142 /* This can be moved to within driver enter routine
143 * but that results in multiple copies of same code.
144 */
145 dev->states_usage[entered_state].time +=
146 (unsigned long long)dev->last_residency;
147 dev->states_usage[entered_state].usage++;
148 } else {
149 dev->last_residency = 0;
150 }
151
152 /* give the governor an opportunity to reflect on the outcome */ 163 /* give the governor an opportunity to reflect on the outcome */
153 if (cpuidle_curr_governor->reflect) 164 if (cpuidle_curr_governor->reflect)
154 cpuidle_curr_governor->reflect(dev, entered_state); 165 cpuidle_curr_governor->reflect(dev, entered_state);
@@ -283,6 +294,9 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
283 int ret, i; 294 int ret, i;
284 struct cpuidle_driver *drv = cpuidle_get_driver(); 295 struct cpuidle_driver *drv = cpuidle_get_driver();
285 296
297 if (!dev)
298 return -EINVAL;
299
286 if (dev->enabled) 300 if (dev->enabled)
287 return 0; 301 return 0;
288 if (!drv || !cpuidle_curr_governor) 302 if (!drv || !cpuidle_curr_governor)
@@ -367,8 +381,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
367 struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); 381 struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
368 struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); 382 struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
369 383
370 if (!dev)
371 return -EINVAL;
372 if (!try_module_get(cpuidle_driver->owner)) 384 if (!try_module_get(cpuidle_driver->owner))
373 return -EINVAL; 385 return -EINVAL;
374 386
@@ -376,13 +388,25 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
376 388
377 per_cpu(cpuidle_devices, dev->cpu) = dev; 389 per_cpu(cpuidle_devices, dev->cpu) = dev;
378 list_add(&dev->device_list, &cpuidle_detected_devices); 390 list_add(&dev->device_list, &cpuidle_detected_devices);
379 if ((ret = cpuidle_add_sysfs(cpu_dev))) { 391 ret = cpuidle_add_sysfs(cpu_dev);
380 module_put(cpuidle_driver->owner); 392 if (ret)
381 return ret; 393 goto err_sysfs;
382 } 394
395 ret = cpuidle_coupled_register_device(dev);
396 if (ret)
397 goto err_coupled;
383 398
384 dev->registered = 1; 399 dev->registered = 1;
385 return 0; 400 return 0;
401
402err_coupled:
403 cpuidle_remove_sysfs(cpu_dev);
404 wait_for_completion(&dev->kobj_unregister);
405err_sysfs:
406 list_del(&dev->device_list);
407 per_cpu(cpuidle_devices, dev->cpu) = NULL;
408 module_put(cpuidle_driver->owner);
409 return ret;
386} 410}
387 411
388/** 412/**
@@ -393,6 +417,9 @@ int cpuidle_register_device(struct cpuidle_device *dev)
393{ 417{
394 int ret; 418 int ret;
395 419
420 if (!dev)
421 return -EINVAL;
422
396 mutex_lock(&cpuidle_lock); 423 mutex_lock(&cpuidle_lock);
397 424
398 if ((ret = __cpuidle_register_device(dev))) { 425 if ((ret = __cpuidle_register_device(dev))) {
@@ -432,6 +459,8 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
432 wait_for_completion(&dev->kobj_unregister); 459 wait_for_completion(&dev->kobj_unregister);
433 per_cpu(cpuidle_devices, dev->cpu) = NULL; 460 per_cpu(cpuidle_devices, dev->cpu) = NULL;
434 461
462 cpuidle_coupled_unregister_device(dev);
463
435 cpuidle_resume_and_unlock(); 464 cpuidle_resume_and_unlock();
436 465
437 module_put(cpuidle_driver->owner); 466 module_put(cpuidle_driver->owner);