diff options
Diffstat (limited to 'drivers/thermal/devfreq_cooling.c')
-rw-r--r-- | drivers/thermal/devfreq_cooling.c | 68 |
1 files changed, 13 insertions, 55 deletions
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 5a737fd5f1aa..7743a78d4723 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -21,14 +21,14 @@ #include <linux/devfreq.h> #include <linux/devfreq_cooling.h> #include <linux/export.h> +#include <linux/idr.h> #include <linux/slab.h> #include <linux/pm_opp.h> #include <linux/thermal.h> #include <trace/events/thermal.h> -static DEFINE_MUTEX(devfreq_lock); -static DEFINE_IDR(devfreq_idr); +static DEFINE_IDA(devfreq_ida); /** * struct devfreq_cooling_device - Devfreq cooling device @@ -58,42 +58,6 @@ struct devfreq_cooling_device { }; /** - * get_idr - function to get a unique id. - * @idr: struct idr * handle used to create a id. - * @id: int * value generated by this function. - * - * This function will populate @id with an unique - * id, using the idr API. - * - * Return: 0 on success, an error code on failure. - */ -static int get_idr(struct idr *idr, int *id) -{ - int ret; - - mutex_lock(&devfreq_lock); - ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL); - mutex_unlock(&devfreq_lock); - if (unlikely(ret < 0)) - return ret; - *id = ret; - - return 0; -} - -/** - * release_idr - function to free the unique id. - * @idr: struct idr * handle used for creating the id. - * @id: int value representing the unique id. - */ -static void release_idr(struct idr *idr, int id) -{ - mutex_lock(&devfreq_lock); - idr_remove(idr, id); - mutex_unlock(&devfreq_lock); -} - -/** * partition_enable_opps() - disable all opps above a given state * @dfc: Pointer to devfreq we are operating on * @cdev_state: cooling device state we're setting @@ -113,15 +77,15 @@ static int partition_enable_opps(struct devfreq_cooling_device *dfc, unsigned int freq = dfc->freq_table[i]; bool want_enable = i >= cdev_state ? true : false; - rcu_read_lock(); opp = dev_pm_opp_find_freq_exact(dev, freq, !want_enable); - rcu_read_unlock(); if (PTR_ERR(opp) == -ERANGE) continue; else if (IS_ERR(opp)) return PTR_ERR(opp); + dev_pm_opp_put(opp); + if (want_enable) ret = dev_pm_opp_enable(dev, freq); else @@ -221,15 +185,12 @@ get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq) if (!dfc->power_ops->get_static_power) return 0; - rcu_read_lock(); - opp = dev_pm_opp_find_freq_exact(dev, freq, true); if (IS_ERR(opp) && (PTR_ERR(opp) == -ERANGE)) opp = dev_pm_opp_find_freq_exact(dev, freq, false); voltage = dev_pm_opp_get_voltage(opp) / 1000; /* mV */ - - rcu_read_unlock(); + dev_pm_opp_put(opp); if (voltage == 0) { dev_warn_ratelimited(dev, @@ -412,18 +373,14 @@ static int devfreq_cooling_gen_tables(struct devfreq_cooling_device *dfc) unsigned long power_dyn, voltage; struct dev_pm_opp *opp; - rcu_read_lock(); - opp = dev_pm_opp_find_freq_floor(dev, &freq); if (IS_ERR(opp)) { - rcu_read_unlock(); ret = PTR_ERR(opp); goto free_tables; } voltage = dev_pm_opp_get_voltage(opp) / 1000; /* mV */ - - rcu_read_unlock(); + dev_pm_opp_put(opp); if (dfc->power_ops) { power_dyn = get_dynamic_power(dfc, freq, voltage); @@ -496,9 +453,10 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, if (err) goto free_dfc; - err = get_idr(&devfreq_idr, &dfc->id); - if (err) + err = ida_simple_get(&devfreq_ida, 0, 0, GFP_KERNEL); + if (err < 0) goto free_tables; + dfc->id = err; snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d", dfc->id); @@ -509,15 +467,15 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, dev_err(df->dev.parent, "Failed to register devfreq cooling device (%d)\n", err); - goto release_idr; + goto release_ida; } dfc->cdev = cdev; return cdev; -release_idr: - release_idr(&devfreq_idr, dfc->id); +release_ida: + ida_simple_remove(&devfreq_ida, dfc->id); free_tables: kfree(dfc->power_table); kfree(dfc->freq_table); @@ -565,7 +523,7 @@ void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) dfc = cdev->devdata; thermal_cooling_device_unregister(dfc->cdev); - release_idr(&devfreq_idr, dfc->id); + ida_simple_remove(&devfreq_ida, dfc->id); kfree(dfc->power_table); kfree(dfc->freq_table); |