[PATCH 2/4] opp: Track device's resources configuration status
From: Viresh Kumar <viresh.kumar@linaro.org>
Date: 2020-08-13 04:29:20
Also in:
lkml
Subsystem:
operating performance points (opp), the rest · Maintainers:
Viresh Kumar, Nishanth Menon, Stephen Boyd, Linus Torvalds
The OPP core needs to track if the resources of devices are enabled or configured or not, as it disables the resources when target_freq is set to 0. Handle that with a separate variable to make it easy to maintain. Also note that we will unconditionally call clk_set_rate() in the case where the resources are getting enabled again. This shouldn't have any side effects anyway. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> --- drivers/opp/core.c | 37 ++++++++++++++++++------------------- drivers/opp/opp.h | 2 ++ 2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 9668ea04cc80..e8882e7fd8a5 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c@@ -888,22 +888,18 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) } if (unlikely(!target_freq)) { + ret = 0; + + if (!opp_table->enabled) + goto put_opp_table; + /* * Some drivers need to support cases where some platforms may * have OPP table for the device, while others don't and * opp_set_rate() just needs to behave like clk_set_rate(). */ - if (!_get_opp_count(opp_table)) { - ret = 0; - goto put_opp_table; - } - - if (!opp_table->required_opp_tables && !opp_table->regulators && - !opp_table->paths) { - dev_err(dev, "target frequency can't be 0\n"); - ret = -EINVAL; + if (!_get_opp_count(opp_table)) goto put_opp_table; - } ret = _set_opp_bw(opp_table, NULL, dev, true); if (ret)
@@ -915,6 +911,9 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) } ret = _set_required_opps(dev, opp_table, NULL); + if (!ret) + opp_table->enabled = false; + goto put_opp_table; }
@@ -933,14 +932,11 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) old_freq = clk_get_rate(clk); /* Return early if nothing to do */ - if (old_freq == freq) { - if (!opp_table->required_opp_tables && !opp_table->regulators && - !opp_table->paths) { - dev_dbg(dev, "%s: old/new frequencies (%lu Hz) are same, nothing to do\n", - __func__, freq); - ret = 0; - goto put_opp_table; - } + if (opp_table->enabled && old_freq == freq) { + dev_dbg(dev, "%s: old/new frequencies (%lu Hz) are same, nothing to do\n", + __func__, freq); + ret = 0; + goto put_opp_table; } /*
@@ -1001,8 +997,11 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) dev_err(dev, "Failed to set required opps: %d\n", ret); } - if (!ret) + if (!ret) { ret = _set_opp_bw(opp_table, opp, dev, false); + if (!ret) + opp_table->enabled = true; + } put_opp: dev_pm_opp_put(opp);
diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
index e51646ff279e..bd35802acc6e 100644
--- a/drivers/opp/opp.h
+++ b/drivers/opp/opp.h@@ -152,6 +152,7 @@ enum opp_table_access { * property). * @paths: Interconnect path handles * @path_count: Number of interconnect paths + * @enabled: Set to true if the device's resources are enabled/configured. * @genpd_performance_state: Device's power domain support performance state. * @is_genpd: Marks if the OPP table belongs to a genpd. * @set_opp: Platform specific set_opp callback
@@ -198,6 +199,7 @@ struct opp_table { bool regulator_enabled; struct icc_path **paths; unsigned int path_count; + bool enabled; bool genpd_performance_state; bool is_genpd;
--
2.14.1