Commit c0006dc6 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 425bec00 7ee5fd12
...@@ -435,7 +435,7 @@ static void genpd_restore_performance_state(struct device *dev, ...@@ -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) int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state)
{ {
struct generic_pm_domain *genpd; struct generic_pm_domain *genpd;
int ret; int ret = 0;
genpd = dev_to_genpd_safe(dev); genpd = dev_to_genpd_safe(dev);
if (!genpd) if (!genpd)
...@@ -446,7 +446,13 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state) ...@@ -446,7 +446,13 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state)
return -EINVAL; return -EINVAL;
genpd_lock(genpd); genpd_lock(genpd);
if (pm_runtime_suspended(dev)) {
dev_gpd_data(dev)->rpm_pstate = state;
} else {
ret = genpd_set_performance_state(dev, state); ret = genpd_set_performance_state(dev, state);
if (!ret)
dev_gpd_data(dev)->rpm_pstate = 0;
}
genpd_unlock(genpd); genpd_unlock(genpd);
return ret; return ret;
......
...@@ -893,6 +893,10 @@ static int _set_required_opps(struct device *dev, ...@@ -893,6 +893,10 @@ static int _set_required_opps(struct device *dev,
if (!required_opp_tables) if (!required_opp_tables)
return 0; 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 * 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 * 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, ...@@ -903,10 +907,6 @@ static int _set_required_opps(struct device *dev,
return -ENOENT; return -ENOENT;
} }
/* required-opps not fully initialized yet */
if (lazy_linking_pending(opp_table))
return -EBUSY;
/* Single genpd case */ /* Single genpd case */
if (!genpd_virt_devs) if (!genpd_virt_devs)
return _set_required_opp(dev, dev, opp, 0); return _set_required_opp(dev, dev, opp, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment