aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-04-17 09:56:28 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-04-17 09:56:28 -0700
commit5a32fe48bcc7956f55a1bd2a2799f37020f5a208 (patch)
treea47d358f1eaddde5e29f3e2bbaf26625da0e0eea
parentc8a6552ff1155788b9a25ad376ab42e0742eef6b (diff)
parent2c127c46ec98ff0f1cdb236321bdd54e6e43fcf5 (diff)
downloadlinux-5a32fe48bcc7956f55a1bd2a2799f37020f5a208.tar.gz
Merge tag 'pm-5.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management update from Rafael Wysocki: "Allow the operating performance points (OPP) core to be used in the case when the same driver is used on different platforms, some of which have an OPP table and some of which have a clock node (Rajendra Nayak)" * tag 'pm-5.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: opp: Manage empty OPP tables with clk handle
-rw-r--r--drivers/opp/core.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index ba43e6a3dc0aee..e4f01e7771a223 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -819,6 +819,8 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
if (unlikely(!target_freq)) {
if (opp_table->required_opp_tables) {
ret = _set_required_opps(dev, opp_table, NULL);
+ } else if (!_get_opp_count(opp_table)) {
+ return 0;
} else {
dev_err(dev, "target frequency can't be 0\n");
ret = -EINVAL;
@@ -849,6 +851,18 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
goto put_opp_table;
}
+ /*
+ * For IO devices which require an OPP on some platforms/SoCs
+ * while just needing to scale the clock on some others
+ * we look for empty OPP tables with just a clock handle and
+ * scale only the clk. This makes dev_pm_opp_set_rate()
+ * equivalent to a clk_set_rate()
+ */
+ if (!_get_opp_count(opp_table)) {
+ ret = _generic_set_opp_clk_only(dev, clk, freq);
+ goto put_opp_table;
+ }
+
temp_freq = old_freq;
old_opp = _find_freq_ceil(opp_table, &temp_freq);
if (IS_ERR(old_opp)) {