提交 779b783c 编写于 作者: V Viresh Kumar

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: NViresh Kumar <viresh.kumar@linaro.org>
上级 878ec1a9
......@@ -1320,11 +1320,9 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
goto err;
}
/* Already have regulators set */
if (opp_table->regulators) {
ret = -EBUSY;
goto err;
}
/* Another CPU that shares the OPP table has set the regulators ? */
if (opp_table->regulators)
return opp_table;
opp_table->regulators = kmalloc_array(count,
sizeof(*opp_table->regulators),
......@@ -1378,10 +1376,8 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
{
int i;
if (!opp_table->regulators) {
pr_err("%s: Doesn't have regulators set\n", __func__);
return;
}
if (!opp_table->regulators)
goto put_opp_table;
/* Make sure there are no concurrent readers while updating opp_table */
WARN_ON(!list_empty(&opp_table->opp_list));
......@@ -1395,6 +1391,7 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
opp_table->regulators = NULL;
opp_table->regulator_count = 0;
put_opp_table:
dev_pm_opp_put_opp_table(opp_table);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册