summary refs log tree commit diff
path: root/drivers/opp/of.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2020-09-16 14:02:23 +0530
committerViresh Kumar <viresh.kumar@linaro.org>2020-09-16 14:02:23 +0530
commit3a5578784d1eb4b89f5f112f67caad4a76ae19c3 (patch)
treee5011efa9df7afaa7a36a0306604503aa4b9c18d /drivers/opp/of.c
parent8aaf6264fc7fde15864c3e4d84ccc8b3af6811f3 (diff)
parent90d46d71cce279d878793a0ed4b326b4027aca6c (diff)
downloadlinux-3a5578784d1eb4b89f5f112f67caad4a76ae19c3.tar.gz
Merge branch 'opp/defer-probe' into HEAD
Diffstat (limited to 'drivers/opp/of.c')
-rw-r--r--drivers/opp/of.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index 7d9d4455a59e..2f294c57ec06 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -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)