summaryrefslogtreecommitdiffstats
path: root/drivers/opp
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2018-05-22 07:08:08 -0400
committerViresh Kumar <viresh.kumar@linaro.org>2018-05-22 07:30:10 -0400
commit779b783cfaa726cbe35317ae2c1968c5496a3a03 (patch)
tree9e9242379d47b8dc8820528ff94f6ddb8916629c /drivers/opp
parent878ec1a9f0e5a6b344c12fdc349ec7cb036c2a42 (diff)
PM / OPP: Fix shared OPP table support in dev_pm_opp_set_regulators()
It should be fine to call dev_pm_opp_set_regulators() for all possible CPUs, even if some of them share the OPP table as the caller may not be aware of sharing policy. Lets increment the reference count of the OPP table and return its pointer. The caller need to call dev_pm_opp_put_regulators() the same number of times later on to drop all the references. To avoid adding another counter to count how many times dev_pm_opp_set_regulators() is called for the same OPP table, dev_pm_opp_put_regulators() frees the resources on the very first call made to it, assuming that the caller would be calling it sequentially for all the CPUs. We can revisit that if that assumption is broken in the future. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'drivers/opp')
-rw-r--r--drivers/opp/core.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 86e8e2c1905f..780c89a49d18 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1320,11 +1320,9 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
1320 goto err; 1320 goto err;
1321 } 1321 }
1322 1322
1323 /* Already have regulators set */ 1323 /* Another CPU that shares the OPP table has set the regulators ? */
1324 if (opp_table->regulators) { 1324 if (opp_table->regulators)
1325 ret = -EBUSY; 1325 return opp_table;
1326 goto err;
1327 }
1328 1326
1329 opp_table->regulators = kmalloc_array(count, 1327 opp_table->regulators = kmalloc_array(count,
1330 sizeof(*opp_table->regulators), 1328 sizeof(*opp_table->regulators),
@@ -1378,10 +1376,8 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
1378{ 1376{
1379 int i; 1377 int i;
1380 1378
1381 if (!opp_table->regulators) { 1379 if (!opp_table->regulators)
1382 pr_err("%s: Doesn't have regulators set\n", __func__); 1380 goto put_opp_table;
1383 return;
1384 }
1385 1381
1386 /* Make sure there are no concurrent readers while updating opp_table */ 1382 /* Make sure there are no concurrent readers while updating opp_table */
1387 WARN_ON(!list_empty(&opp_table->opp_list)); 1383 WARN_ON(!list_empty(&opp_table->opp_list));
@@ -1395,6 +1391,7 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
1395 opp_table->regulators = NULL; 1391 opp_table->regulators = NULL;
1396 opp_table->regulator_count = 0; 1392 opp_table->regulator_count = 0;
1397 1393
1394put_opp_table:
1398 dev_pm_opp_put_opp_table(opp_table); 1395 dev_pm_opp_put_opp_table(opp_table);
1399} 1396}
1400EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators); 1397EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators);