mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
OPP: Extend support for the opp-level beyond required-opps
At this point the level (performance state) for an OPP is currently limited to be requested for a device that is attached to a PM domain. Moreover, the device needs to have the so called required-opps assigned to it, which are based upon OPP tables being described in DT. To extend the support beyond required-opps and DT, let's enable the level to be set for all OPPs. More precisely, if the requested OPP has a valid level let's try to request it through the device's optional PM domain, via calling dev_pm_domain_set_performance_state(). Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> [ Viresh: Handle NULL opp in _set_opp_level() ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
This commit is contained in:
parent
892c60c6b4
commit
0025ff64ff
|
|
@ -1107,6 +1107,28 @@ void _update_set_required_opps(struct opp_table *opp_table)
|
|||
opp_table->set_required_opps = _opp_set_required_opps_generic;
|
||||
}
|
||||
|
||||
static int _set_opp_level(struct device *dev, struct opp_table *opp_table,
|
||||
struct dev_pm_opp *opp)
|
||||
{
|
||||
unsigned int level = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (opp) {
|
||||
if (!opp->level)
|
||||
return 0;
|
||||
|
||||
level = opp->level;
|
||||
}
|
||||
|
||||
/* Request a new performance state through the device's PM domain. */
|
||||
ret = dev_pm_domain_set_performance_state(dev, level);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to set performance state %u (%d)\n", level,
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _find_current_opp(struct device *dev, struct opp_table *opp_table)
|
||||
{
|
||||
struct dev_pm_opp *opp = ERR_PTR(-ENODEV);
|
||||
|
|
@ -1154,8 +1176,13 @@ static int _disable_opp_table(struct device *dev, struct opp_table *opp_table)
|
|||
if (opp_table->regulators)
|
||||
regulator_disable(opp_table->regulators[0]);
|
||||
|
||||
ret = _set_opp_level(dev, opp_table, NULL);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = _set_required_opps(dev, opp_table, NULL, false);
|
||||
|
||||
out:
|
||||
opp_table->enabled = false;
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1198,6 +1225,10 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = _set_opp_level(dev, opp_table, opp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _set_opp_bw(opp_table, opp, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to set bw: %d\n", ret);
|
||||
|
|
@ -1241,6 +1272,10 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = _set_opp_level(dev, opp_table, opp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _set_required_opps(dev, opp_table, opp, false);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to set required opps: %d\n", ret);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user