Merge branch 'opp/genpd/required-opps' into opp/linux-next
[linux-2.6-block.git] / drivers / opp / of.c
index 71aef28953c23fd991b0cdfcdb31a6acfeb0c671..840f85181a3733c2aef953a493e6de4e2e8db58d 100644 (file)
@@ -595,12 +595,13 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
        if (!of_property_read_u32(np, "clock-latency-ns", &val))
                new_opp->clock_latency_ns = val;
 
-       new_opp->pstate = of_genpd_opp_to_performance_state(dev, np);
-
        ret = opp_parse_supplies(new_opp, dev, opp_table);
        if (ret)
                goto free_required_opps;
 
+       if (opp_table->is_genpd)
+               new_opp->pstate = pm_genpd_opp_to_performance_state(dev, new_opp);
+
        ret = _opp_add(dev, new_opp, opp_table, rate_not_available);
        if (ret) {
                /* Don't return error for duplicate OPPs */
@@ -819,10 +820,8 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
                 */
                count = of_count_phandle_with_args(dev->of_node,
                                                   "operating-points-v2", NULL);
-               if (count != 1)
-                       return -ENODEV;
-
-               index = 0;
+               if (count == 1)
+                       index = 0;
        }
 
        opp_table = dev_pm_opp_get_opp_table_indexed(dev, index);
@@ -969,58 +968,48 @@ put_cpu_node:
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus);
 
 /**
- * of_dev_pm_opp_find_required_opp() - Search for required OPP.
- * @dev: The device whose OPP node is referenced by the 'np' DT node.
+ * of_get_required_opp_performance_state() - Search for required OPP and return its performance state.
  * @np: Node that contains the "required-opps" property.
+ * @index: Index of the phandle to parse.
  *
- * Returns the OPP of the device 'dev', whose phandle is present in the "np"
- * node. Although the "required-opps" property supports having multiple
- * phandles, this helper routine only parses the very first phandle in the list.
- *
- * Return: Matching opp, else returns ERR_PTR in case of error and should be
- * handled using IS_ERR.
+ * Returns the performance state of the OPP pointed out by the "required-opps"
+ * property at @index in @np.
  *
- * The callers are required to call dev_pm_opp_put() for the returned OPP after
- * use.
+ * Return: Positive performance state on success, otherwise 0 on errors.
  */
-struct dev_pm_opp *of_dev_pm_opp_find_required_opp(struct device *dev,
-                                                  struct device_node *np)
+unsigned int of_get_required_opp_performance_state(struct device_node *np,
+                                                  int index)
 {
-       struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ENODEV);
+       struct dev_pm_opp *opp;
        struct device_node *required_np;
        struct opp_table *opp_table;
+       unsigned int pstate = 0;
 
-       opp_table = _find_opp_table(dev);
-       if (IS_ERR(opp_table))
-               return ERR_CAST(opp_table);
+       required_np = of_parse_required_opp(np, index);
+       if (!required_np)
+               return 0;
 
-       required_np = of_parse_phandle(np, "required-opps", 0);
-       if (unlikely(!required_np)) {
-               dev_err(dev, "Unable to parse required-opps\n");
-               goto put_opp_table;
+       opp_table = _find_table_of_opp_np(required_np);
+       if (IS_ERR(opp_table)) {
+               pr_err("%s: Failed to find required OPP table %pOF: %ld\n",
+                      __func__, np, PTR_ERR(opp_table));
+               goto put_required_np;
        }
 
-       mutex_lock(&opp_table->lock);
-
-       list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
-               if (temp_opp->available && temp_opp->np == required_np) {
-                       opp = temp_opp;
-
-                       /* Increment the reference count of OPP */
-                       dev_pm_opp_get(opp);
-                       break;
-               }
+       opp = _find_opp_of_np(opp_table, required_np);
+       if (opp) {
+               pstate = opp->pstate;
+               dev_pm_opp_put(opp);
        }
 
-       mutex_unlock(&opp_table->lock);
+       dev_pm_opp_put_opp_table(opp_table);
 
+put_required_np:
        of_node_put(required_np);
-put_opp_table:
-       dev_pm_opp_put_opp_table(opp_table);
 
-       return opp;
+       return pstate;
 }
-EXPORT_SYMBOL_GPL(of_dev_pm_opp_find_required_opp);
+EXPORT_SYMBOL_GPL(of_get_required_opp_performance_state);
 
 /**
  * dev_pm_opp_get_of_node() - Gets the DT node corresponding to an opp