]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/cpuidle/cpuidle.c
Bluetooth: Simplify UUID removal code
[karo-tx-linux.git] / drivers / cpuidle / cpuidle.c
index 7f15b8514a1899460e16c2fcf7505d038eafe2d7..8df53dd8dbe17b4bb0c0d432bbec56d31895dc84 100644 (file)
@@ -68,7 +68,7 @@ static cpuidle_enter_t cpuidle_enter_ops;
 int cpuidle_play_dead(void)
 {
        struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
-       struct cpuidle_driver *drv = cpuidle_get_driver();
+       struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
        int i, dead_state = -1;
        int power_usage = -1;
 
@@ -109,8 +109,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
                /* This can be moved to within driver enter routine
                 * but that results in multiple copies of same code.
                 */
-               dev->states_usage[entered_state].time +=
-                               (unsigned long long)dev->last_residency;
+               dev->states_usage[entered_state].time += dev->last_residency;
                dev->states_usage[entered_state].usage++;
        } else {
                dev->last_residency = 0;
@@ -128,7 +127,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
 int cpuidle_idle_call(void)
 {
        struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
-       struct cpuidle_driver *drv = cpuidle_get_driver();
+       struct cpuidle_driver *drv;
        int next_state, entered_state;
 
        if (off)
@@ -141,9 +140,15 @@ int cpuidle_idle_call(void)
        if (!dev || !dev->enabled)
                return -EBUSY;
 
+       drv = cpuidle_get_cpu_driver(dev);
+
        /* ask the governor for the next state */
        next_state = cpuidle_curr_governor->select(drv, dev);
        if (need_resched()) {
+               dev->last_residency = 0;
+               /* give the governor an opportunity to reflect on the outcome */
+               if (cpuidle_curr_governor->reflect)
+                       cpuidle_curr_governor->reflect(dev, next_state);
                local_irq_enable();
                return 0;
        }
@@ -308,15 +313,19 @@ static void poll_idle_init(struct cpuidle_driver *drv) {}
 int cpuidle_enable_device(struct cpuidle_device *dev)
 {
        int ret, i;
-       struct cpuidle_driver *drv = cpuidle_get_driver();
+       struct cpuidle_driver *drv;
 
        if (!dev)
                return -EINVAL;
 
        if (dev->enabled)
                return 0;
+
+       drv = cpuidle_get_cpu_driver(dev);
+
        if (!drv || !cpuidle_curr_governor)
                return -EIO;
+
        if (!dev->state_count)
                dev->state_count = drv->state_count;
 
@@ -331,7 +340,8 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
 
        poll_idle_init(drv);
 
-       if ((ret = cpuidle_add_state_sysfs(dev)))
+       ret = cpuidle_add_device_sysfs(dev);
+       if (ret)
                return ret;
 
        if (cpuidle_curr_governor->enable &&
@@ -352,7 +362,7 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
        return 0;
 
 fail_sysfs:
-       cpuidle_remove_state_sysfs(dev);
+       cpuidle_remove_device_sysfs(dev);
 
        return ret;
 }
@@ -368,17 +378,20 @@ EXPORT_SYMBOL_GPL(cpuidle_enable_device);
  */
 void cpuidle_disable_device(struct cpuidle_device *dev)
 {
+       struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+
        if (!dev || !dev->enabled)
                return;
-       if (!cpuidle_get_driver() || !cpuidle_curr_governor)
+
+       if (!drv || !cpuidle_curr_governor)
                return;
 
        dev->enabled = 0;
 
        if (cpuidle_curr_governor->disable)
-               cpuidle_curr_governor->disable(cpuidle_get_driver(), dev);
+               cpuidle_curr_governor->disable(drv, dev);
 
-       cpuidle_remove_state_sysfs(dev);
+       cpuidle_remove_device_sysfs(dev);
        enabled_devices--;
 }
 
@@ -394,17 +407,14 @@ EXPORT_SYMBOL_GPL(cpuidle_disable_device);
 static int __cpuidle_register_device(struct cpuidle_device *dev)
 {
        int ret;
-       struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
-       struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
+       struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
 
-       if (!try_module_get(cpuidle_driver->owner))
+       if (!try_module_get(drv->owner))
                return -EINVAL;
 
-       init_completion(&dev->kobj_unregister);
-
        per_cpu(cpuidle_devices, dev->cpu) = dev;
        list_add(&dev->device_list, &cpuidle_detected_devices);
-       ret = cpuidle_add_sysfs(cpu_dev);
+       ret = cpuidle_add_sysfs(dev);
        if (ret)
                goto err_sysfs;
 
@@ -416,12 +426,11 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
        return 0;
 
 err_coupled:
-       cpuidle_remove_sysfs(cpu_dev);
-       wait_for_completion(&dev->kobj_unregister);
+       cpuidle_remove_sysfs(dev);
 err_sysfs:
        list_del(&dev->device_list);
        per_cpu(cpuidle_devices, dev->cpu) = NULL;
-       module_put(cpuidle_driver->owner);
+       module_put(drv->owner);
        return ret;
 }
 
@@ -460,8 +469,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device);
  */
 void cpuidle_unregister_device(struct cpuidle_device *dev)
 {
-       struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
-       struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();
+       struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
 
        if (dev->registered == 0)
                return;
@@ -470,16 +478,15 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
 
        cpuidle_disable_device(dev);
 
-       cpuidle_remove_sysfs(cpu_dev);
+       cpuidle_remove_sysfs(dev);
        list_del(&dev->device_list);
-       wait_for_completion(&dev->kobj_unregister);
        per_cpu(cpuidle_devices, dev->cpu) = NULL;
 
        cpuidle_coupled_unregister_device(dev);
 
        cpuidle_resume_and_unlock();
 
-       module_put(cpuidle_driver->owner);
+       module_put(drv->owner);
 }
 
 EXPORT_SYMBOL_GPL(cpuidle_unregister_device);