]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/base/power/opp/cpu.c
Merge branches 'pm-core', 'pm-qos', 'pm-domains' and 'pm-opp'
[linux.git] / drivers / base / power / opp / cpu.c
index 8c3434bdb26dee8c23a637798b18a3963666ee70..2d87bc1adf38b682d5416a72987115eb68737000 100644 (file)
  *
  * WARNING: It is  important for the callers to ensure refreshing their copy of
  * the table if any of the mentioned functions have been invoked in the interim.
- *
- * Locking: The internal opp_table and opp structures are RCU protected.
- * Since we just use the regular accessor functions to access the internal data
- * structures, we use RCU read lock inside this function. As a result, users of
- * this function DONOT need to use explicit locks for invoking.
  */
 int dev_pm_opp_init_cpufreq_table(struct device *dev,
                                  struct cpufreq_frequency_table **table)
@@ -56,19 +51,13 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
        int i, max_opps, ret = 0;
        unsigned long rate;
 
-       rcu_read_lock();
-
        max_opps = dev_pm_opp_get_opp_count(dev);
-       if (max_opps <= 0) {
-               ret = max_opps ? max_opps : -ENODATA;
-               goto out;
-       }
+       if (max_opps <= 0)
+               return max_opps ? max_opps : -ENODATA;
 
        freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_ATOMIC);
-       if (!freq_table) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!freq_table)
+               return -ENOMEM;
 
        for (i = 0, rate = 0; i < max_opps; i++, rate++) {
                /* find next rate */
@@ -83,6 +72,8 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
                /* Is Boost/turbo opp ? */
                if (dev_pm_opp_is_turbo(opp))
                        freq_table[i].flags = CPUFREQ_BOOST_FREQ;
+
+               dev_pm_opp_put(opp);
        }
 
        freq_table[i].driver_data = i;
@@ -91,7 +82,6 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
        *table = &freq_table[0];
 
 out:
-       rcu_read_unlock();
        if (ret)
                kfree(freq_table);
 
@@ -147,12 +137,6 @@ void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of)
  * This removes the OPP tables for CPUs present in the @cpumask.
  * This should be used to remove all the OPPs entries associated with
  * the cpus in @cpumask.
- *
- * Locking: The internal opp_table and opp structures are RCU protected.
- * Hence this function internally uses RCU updater strategy with mutex locks
- * to keep the integrity of the internal data structures. Callers should ensure
- * that this function is *NOT* called under RCU protection or in contexts where
- * mutex cannot be locked.
  */
 void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask)
 {
@@ -169,12 +153,6 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_cpumask_remove_table);
  * @cpumask.
  *
  * Returns -ENODEV if OPP table isn't already present.
- *
- * Locking: The internal opp_table and opp structures are RCU protected.
- * Hence this function internally uses RCU updater strategy with mutex locks
- * to keep the integrity of the internal data structures. Callers should ensure
- * that this function is *NOT* called under RCU protection or in contexts where
- * mutex cannot be locked.
  */
 int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev,
                                const struct cpumask *cpumask)
@@ -184,13 +162,9 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev,
        struct device *dev;
        int cpu, ret = 0;
 
-       mutex_lock(&opp_table_lock);
-
        opp_table = _find_opp_table(cpu_dev);
-       if (IS_ERR(opp_table)) {
-               ret = PTR_ERR(opp_table);
-               goto unlock;
-       }
+       if (IS_ERR(opp_table))
+               return PTR_ERR(opp_table);
 
        for_each_cpu(cpu, cpumask) {
                if (cpu == cpu_dev->id)
@@ -213,8 +187,8 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev,
                /* Mark opp-table as multiple CPUs are sharing it now */
                opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED;
        }
-unlock:
-       mutex_unlock(&opp_table_lock);
+
+       dev_pm_opp_put_opp_table(opp_table);
 
        return ret;
 }
@@ -229,12 +203,6 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus);
  *
  * Returns -ENODEV if OPP table isn't already present and -EINVAL if the OPP
  * table's status is access-unknown.
- *
- * Locking: The internal opp_table and opp structures are RCU protected.
- * Hence this function internally uses RCU updater strategy with mutex locks
- * to keep the integrity of the internal data structures. Callers should ensure
- * that this function is *NOT* called under RCU protection or in contexts where
- * mutex cannot be locked.
  */
 int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
 {
@@ -242,17 +210,13 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
        struct opp_table *opp_table;
        int ret = 0;
 
-       mutex_lock(&opp_table_lock);
-
        opp_table = _find_opp_table(cpu_dev);
-       if (IS_ERR(opp_table)) {
-               ret = PTR_ERR(opp_table);
-               goto unlock;
-       }
+       if (IS_ERR(opp_table))
+               return PTR_ERR(opp_table);
 
        if (opp_table->shared_opp == OPP_TABLE_ACCESS_UNKNOWN) {
                ret = -EINVAL;
-               goto unlock;
+               goto put_opp_table;
        }
 
        cpumask_clear(cpumask);
@@ -264,8 +228,8 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
                cpumask_set_cpu(cpu_dev->id, cpumask);
        }
 
-unlock:
-       mutex_unlock(&opp_table_lock);
+put_opp_table:
+       dev_pm_opp_put_opp_table(opp_table);
 
        return ret;
 }