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 d6a533e68e0f..e28f6ea46f1a 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);
@@ -299,6 +310,9 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
299 int ret, i; 310 int ret, i;
300 struct cpuidle_driver *drv = cpuidle_get_driver(); 311 struct cpuidle_driver *drv = cpuidle_get_driver();
301 312
313 if (!dev)
314 return -EINVAL;
315
302 if (dev->enabled) 316 if (dev->enabled)
303 return 0; 317 return 0;
304 if (!drv || !cpuidle_curr_governor) 318 if (!drv || !cpuidle_curr_governor)
@@ -383,8 +397,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
383 struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); 397 struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
384 struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); 398 struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
385 399
386 if (!dev)
387 return -EINVAL;
388 if (!try_module_get(cpuidle_driver->owner)) 400 if (!try_module_get(cpuidle_driver->owner))
389 return -EINVAL; 401 return -EINVAL;
390 402
@@ -392,13 +404,25 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
392 404
393 per_cpu(cpuidle_devices, dev->cpu) = dev; 405 per_cpu(cpuidle_devices, dev->cpu) = dev;
394 list_add(&dev->device_list, &cpuidle_detected_devices); 406 list_add(&dev->device_list, &cpuidle_detected_devices);
395 if ((ret = cpuidle_add_sysfs(cpu_dev))) { 407 ret = cpuidle_add_sysfs(cpu_dev);
396 module_put(cpuidle_driver->owner); 408 if (ret)
397 return ret; 409 goto err_sysfs;
398 } 410
411 ret = cpuidle_coupled_register_device(dev);
412 if (ret)
413 goto err_coupled;
399 414
400 dev->registered = 1; 415 dev->registered = 1;
401 return 0; 416 return 0;
417
418err_coupled:
419 cpuidle_remove_sysfs(cpu_dev);
420 wait_for_completion(&dev->kobj_unregister);
421err_sysfs:
422 list_del(&dev->device_list);
423 per_cpu(cpuidle_devices, dev->cpu) = NULL;
424 module_put(cpuidle_driver->owner);
425 return ret;
402} 426}
403 427
404/** 428/**
@@ -409,6 +433,9 @@ int cpuidle_register_device(struct cpuidle_device *dev)
409{ 433{
410 int ret; 434 int ret;
411 435
436 if (!dev)
437 return -EINVAL;
438
412 mutex_lock(&cpuidle_lock); 439 mutex_lock(&cpuidle_lock);
413 440
414 if ((ret = __cpuidle_register_device(dev))) { 441 if ((ret = __cpuidle_register_device(dev))) {
@@ -448,6 +475,8 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
448 wait_for_completion(&dev->kobj_unregister); 475 wait_for_completion(&dev->kobj_unregister);
449 per_cpu(cpuidle_devices, dev->cpu) = NULL; 476 per_cpu(cpuidle_devices, dev->cpu) = NULL;
450 477
478 cpuidle_coupled_unregister_device(dev);
479
451 cpuidle_resume_and_unlock(); 480 cpuidle_resume_and_unlock();
452 481
453 module_put(cpuidle_driver->owner); 482 module_put(cpuidle_driver->owner);