diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-08-27 21:06:51 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-08-27 21:06:51 +0200 |
commit | c0006dc6957ef0b5d3e785556f30f928af05ab0c (patch) | |
tree | 81287acd5aebad4954e2b6db50069eabee9eb458 | |
parent | virtio-mem: fix sleeping in RCU read side section in virtio_mem_online_page_cb() (diff) | |
parent | Merge branch 'pm-opp' (diff) | |
download | linux-c0006dc6957ef0b5d3e785556f30f928af05ab0c.tar.xz linux-c0006dc6957ef0b5d3e785556f30f928af05ab0c.zip |
Merge tag 'pm-5.14-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki:
"These fix two issues introduced during this cycle, one of which is a
regression and the other one affects new code.
Specifics:
- Prevent the operating performance points (OPP) code from crashing
when some entries in the table of required OPPs are set to error
pointer values (Marijn Suijten)
- Prevent the generic power domains (genpd) framework from
incorrectly overriding the performance state of a device set by its
driver while it is runtime-suspended or when runtime PM of it is
disabled (Dmitry Osipenko)"
* tag 'pm-5.14-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM: domains: Improve runtime PM performance state handling
opp: core: Check for pending links before reading required_opp pointers
-rw-r--r-- | drivers/base/power/domain.c | 10 | ||||
-rw-r--r-- | drivers/opp/core.c | 8 |
2 files changed, 12 insertions, 6 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index a934c679e6ce..f10688e83226 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -435,7 +435,7 @@ static void genpd_restore_performance_state(struct device *dev, int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state) { struct generic_pm_domain *genpd; - int ret; + int ret = 0; genpd = dev_to_genpd_safe(dev); if (!genpd) @@ -446,7 +446,13 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state) return -EINVAL; genpd_lock(genpd); - ret = genpd_set_performance_state(dev, state); + if (pm_runtime_suspended(dev)) { + dev_gpd_data(dev)->rpm_pstate = state; + } else { + ret = genpd_set_performance_state(dev, state); + if (!ret) + dev_gpd_data(dev)->rpm_pstate = 0; + } genpd_unlock(genpd); return ret; diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 5543c54dacc5..04b4691a8aac 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -893,6 +893,10 @@ static int _set_required_opps(struct device *dev, if (!required_opp_tables) return 0; + /* required-opps not fully initialized yet */ + if (lazy_linking_pending(opp_table)) + return -EBUSY; + /* * We only support genpd's OPPs in the "required-opps" for now, as we * don't know much about other use cases. Error out if the required OPP @@ -903,10 +907,6 @@ static int _set_required_opps(struct device *dev, return -ENOENT; } - /* required-opps not fully initialized yet */ - if (lazy_linking_pending(opp_table)) - return -EBUSY; - /* Single genpd case */ if (!genpd_virt_devs) return _set_required_opp(dev, dev, opp, 0); |