Merge branch 'opp/defer-probe' into HEAD
[linux-2.6-microblaze.git] / drivers / opp / of.c
index 7d9d445..2f294c5 100644 (file)
@@ -886,11 +886,25 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
        const __be32 *val;
        int nr, ret = 0;
 
+       mutex_lock(&opp_table->lock);
+       if (opp_table->parsed_static_opps) {
+               opp_table->parsed_static_opps++;
+               mutex_unlock(&opp_table->lock);
+               return 0;
+       }
+
+       opp_table->parsed_static_opps = 1;
+       mutex_unlock(&opp_table->lock);
+
        prop = of_find_property(dev->of_node, "operating-points", NULL);
-       if (!prop)
-               return -ENODEV;
-       if (!prop->value)
-               return -ENODATA;
+       if (!prop) {
+               ret = -ENODEV;
+               goto remove_static_opp;
+       }
+       if (!prop->value) {
+               ret = -ENODATA;
+               goto remove_static_opp;
+       }
 
        /*
         * Each OPP is a set of tuples consisting of frequency and
@@ -899,13 +913,10 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
        nr = prop->length / sizeof(u32);
        if (nr % 2) {
                dev_err(dev, "%s: Invalid OPP table\n", __func__);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto remove_static_opp;
        }
 
-       mutex_lock(&opp_table->lock);
-       opp_table->parsed_static_opps = 1;
-       mutex_unlock(&opp_table->lock);
-
        val = prop->value;
        while (nr) {
                unsigned long freq = be32_to_cpup(val++) * 1000;
@@ -915,12 +926,14 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
                if (ret) {
                        dev_err(dev, "%s: Failed to add OPP %ld (%d)\n",
                                __func__, freq, ret);
-                       _opp_remove_all_static(opp_table);
-                       return ret;
+                       goto remove_static_opp;
                }
                nr -= 2;
        }
 
+remove_static_opp:
+       _opp_remove_all_static(opp_table);
+
        return ret;
 }
 
@@ -947,8 +960,8 @@ int dev_pm_opp_of_add_table(struct device *dev)
        int ret;
 
        opp_table = dev_pm_opp_get_opp_table_indexed(dev, 0);
-       if (!opp_table)
-               return -ENOMEM;
+       if (IS_ERR(opp_table))
+               return PTR_ERR(opp_table);
 
        /*
         * OPPs have two version of bindings now. Also try the old (v1)
@@ -1002,8 +1015,8 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
        }
 
        opp_table = dev_pm_opp_get_opp_table_indexed(dev, index);
-       if (!opp_table)
-               return -ENOMEM;
+       if (IS_ERR(opp_table))
+               return PTR_ERR(opp_table);
 
        ret = _of_add_opp_table_v2(dev, opp_table);
        if (ret)