PM / OPP: Relocate dev_pm_opp_set_sharing_cpus()
[linux-2.6-block.git] / drivers / base / power / opp / cpu.c
index ba2bdbd932ef3c1ebaff47c6203bddb27fe9c03b..491e8684bd5f19fc8e800b060b5b73236eff89e8 100644 (file)
@@ -119,48 +119,19 @@ void dev_pm_opp_free_cpufreq_table(struct device *dev,
 EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table);
 #endif /* CONFIG_CPU_FREQ */
 
-/* Required only for V1 bindings, as v2 can manage it from DT itself */
-int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask)
-{
-       struct opp_device *opp_dev;
-       struct opp_table *opp_table;
-       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 = -EINVAL;
-               goto unlock;
-       }
-
-       for_each_cpu(cpu, cpumask) {
-               if (cpu == cpu_dev->id)
-                       continue;
-
-               dev = get_cpu_device(cpu);
-               if (!dev) {
-                       dev_err(cpu_dev, "%s: failed to get cpu%d device\n",
-                               __func__, cpu);
-                       continue;
-               }
-
-               opp_dev = _add_opp_dev(dev, opp_table);
-               if (!opp_dev) {
-                       dev_err(dev, "%s: failed to add opp-dev for cpu%d device\n",
-                               __func__, cpu);
-                       continue;
-               }
-       }
-unlock:
-       mutex_unlock(&opp_table_lock);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus);
-
 #ifdef CONFIG_OF
+/**
+ * dev_pm_opp_of_cpumask_remove_table() - Removes OPP table for @cpumask
+ * @cpumask:   cpumask for which OPP table needs to be removed
+ *
+ * This removes the OPP tables for CPUs present in the @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_of_cpumask_remove_table(cpumask_var_t cpumask)
 {
        struct device *cpu_dev;
@@ -181,6 +152,18 @@ void dev_pm_opp_of_cpumask_remove_table(cpumask_var_t cpumask)
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table);
 
+/**
+ * dev_pm_opp_of_cpumask_add_table() - Adds OPP table for @cpumask
+ * @cpumask:   cpumask for which OPP table needs to be added.
+ *
+ * This adds the OPP tables for CPUs present in the @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.
+ */
 int dev_pm_opp_of_cpumask_add_table(cpumask_var_t cpumask)
 {
        struct device *cpu_dev;
@@ -216,6 +199,24 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_add_table);
  *
  * Returns -ENOENT if operating-points-v2 bindings aren't supported.
  */
+/**
+ * dev_pm_opp_of_get_sharing_cpus() - Get cpumask of CPUs sharing OPPs with
+ *                                   @cpu_dev using operating-points-v2
+ *                                   bindings.
+ *
+ * @cpu_dev:   CPU device for which we do this operation
+ * @cpumask:   cpumask to update with information of sharing CPUs
+ *
+ * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev.
+ *
+ * Returns -ENOENT if operating-points-v2 isn't present for @cpu_dev.
+ *
+ * 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_of_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask)
 {
        struct device_node *np, *tmp_np;
@@ -269,3 +270,59 @@ put_cpu_node:
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus);
 #endif
+
+/**
+ * dev_pm_opp_set_sharing_cpus() - Mark OPP table as shared by few CPUs
+ * @cpu_dev:   CPU device for which we do this operation
+ * @cpumask:   cpumask of the CPUs which share the OPP table with @cpu_dev
+ *
+ * This marks OPP table of the @cpu_dev as shared by the CPUs present in
+ * @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, cpumask_var_t cpumask)
+{
+       struct opp_device *opp_dev;
+       struct opp_table *opp_table;
+       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;
+       }
+
+       for_each_cpu(cpu, cpumask) {
+               if (cpu == cpu_dev->id)
+                       continue;
+
+               dev = get_cpu_device(cpu);
+               if (!dev) {
+                       dev_err(cpu_dev, "%s: failed to get cpu%d device\n",
+                               __func__, cpu);
+                       continue;
+               }
+
+               opp_dev = _add_opp_dev(dev, opp_table);
+               if (!opp_dev) {
+                       dev_err(dev, "%s: failed to add opp-dev for cpu%d device\n",
+                               __func__, cpu);
+                       continue;
+               }
+       }
+unlock:
+       mutex_unlock(&opp_table_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus);