Merge branch 'acpi-pm'
[linux-block.git] / drivers / thermal / cpufreq_cooling.c
index 10af3341e5eaaeaa64e1f516a8be8f326c6b5cb5..eeb4e4b76c0be18c05d00a9f4829fd5c6634f3ba 100644 (file)
 #include <linux/cpu.h>
 #include <linux/cpufreq.h>
 #include <linux/cpu_cooling.h>
+#include <linux/device.h>
 #include <linux/energy_model.h>
 #include <linux/err.h>
 #include <linux/export.h>
-#include <linux/idr.h>
 #include <linux/pm_opp.h>
 #include <linux/pm_qos.h>
 #include <linux/slab.h>
@@ -50,8 +50,6 @@ struct time_in_idle {
 
 /**
  * struct cpufreq_cooling_device - data for cooling device with cpufreq
- * @id: unique integer value corresponding to each cpufreq_cooling_device
- *     registered.
  * @last_load: load measured by the latest call to cpufreq_get_requested_power()
  * @cpufreq_state: integer value representing the current state of cpufreq
  *     cooling devices.
@@ -61,7 +59,6 @@ struct time_in_idle {
  * @cdev: thermal_cooling_device pointer to keep track of the
  *     registered cooling device.
  * @policy: cpufreq policy.
- * @node: list_head to link all cpufreq_cooling_device together.
  * @idle_time: idle time stats
  * @qos_req: PM QoS contraint to apply
  *
@@ -69,23 +66,17 @@ struct time_in_idle {
  * cpufreq_cooling_device.
  */
 struct cpufreq_cooling_device {
-       int id;
        u32 last_load;
        unsigned int cpufreq_state;
        unsigned int max_level;
        struct em_perf_domain *em;
        struct cpufreq_policy *policy;
-       struct list_head node;
 #ifndef CONFIG_SMP
        struct time_in_idle *idle_time;
 #endif
        struct freq_qos_request qos_req;
 };
 
-static DEFINE_IDA(cpufreq_ida);
-static DEFINE_MUTEX(cooling_list_lock);
-static LIST_HEAD(cpufreq_cdev_list);
-
 #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
 /**
  * get_level: Find the level for a particular frequency
@@ -125,7 +116,7 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
 {
        int i;
 
-       for (i = cpufreq_cdev->max_level; i >= 0; i--) {
+       for (i = cpufreq_cdev->max_level; i > 0; i--) {
                if (power >= cpufreq_cdev->em->table[i].power)
                        break;
        }
@@ -528,11 +519,11 @@ __cpufreq_cooling_register(struct device_node *np,
 {
        struct thermal_cooling_device *cdev;
        struct cpufreq_cooling_device *cpufreq_cdev;
-       char dev_name[THERMAL_NAME_LENGTH];
        unsigned int i;
        struct device *dev;
        int ret;
        struct thermal_cooling_device_ops *cooling_ops;
+       char *name;
 
        dev = get_cpu_device(policy->cpu);
        if (unlikely(!dev)) {
@@ -567,16 +558,6 @@ __cpufreq_cooling_register(struct device_node *np,
        /* max_level is an index, not a counter */
        cpufreq_cdev->max_level = i - 1;
 
-       ret = ida_simple_get(&cpufreq_ida, 0, 0, GFP_KERNEL);
-       if (ret < 0) {
-               cdev = ERR_PTR(ret);
-               goto free_idle_time;
-       }
-       cpufreq_cdev->id = ret;
-
-       snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
-                cpufreq_cdev->id);
-
        cooling_ops = &cpufreq_cooling_ops;
 
 #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
@@ -591,7 +572,7 @@ __cpufreq_cooling_register(struct device_node *np,
                pr_err("%s: unsorted frequency tables are not supported\n",
                       __func__);
                cdev = ERR_PTR(-EINVAL);
-               goto remove_ida;
+               goto free_idle_time;
        }
 
        ret = freq_qos_add_request(&policy->constraints,
@@ -601,24 +582,25 @@ __cpufreq_cooling_register(struct device_node *np,
                pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
                       ret);
                cdev = ERR_PTR(ret);
-               goto remove_ida;
+               goto free_idle_time;
        }
 
-       cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,
+       cdev = ERR_PTR(-ENOMEM);
+       name = kasprintf(GFP_KERNEL, "cpufreq-%s", dev_name(dev));
+       if (!name)
+               goto remove_qos_req;
+
+       cdev = thermal_of_cooling_device_register(np, name, cpufreq_cdev,
                                                  cooling_ops);
+       kfree(name);
+
        if (IS_ERR(cdev))
                goto remove_qos_req;
 
-       mutex_lock(&cooling_list_lock);
-       list_add(&cpufreq_cdev->node, &cpufreq_cdev_list);
-       mutex_unlock(&cooling_list_lock);
-
        return cdev;
 
 remove_qos_req:
        freq_qos_remove_request(&cpufreq_cdev->qos_req);
-remove_ida:
-       ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
 free_idle_time:
        free_idle_time(cpufreq_cdev);
 free_cdev:
@@ -706,13 +688,8 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 
        cpufreq_cdev = cdev->devdata;
 
-       mutex_lock(&cooling_list_lock);
-       list_del(&cpufreq_cdev->node);
-       mutex_unlock(&cooling_list_lock);
-
        thermal_cooling_device_unregister(cdev);
        freq_qos_remove_request(&cpufreq_cdev->qos_req);
-       ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
        free_idle_time(cpufreq_cdev);
        kfree(cpufreq_cdev);
 }