Skip to content

Commit

Permalink
PM / OPP: Don't use OPP structure outside of rcu protected section
Browse files Browse the repository at this point in the history
The OPP structure must not be used out of the rcu protected section.
Cache the values to be used in separate variables instead.

Cc: 4.6+ <stable@vger.kernel.org> # 4.6+
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Viresh Kumar authored and Rafael J. Wysocki committed Dec 6, 2016
1 parent 579c49e commit dc39d06
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions drivers/base/power/opp/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
struct clk *clk;
unsigned long freq, old_freq;
unsigned long u_volt, u_volt_min, u_volt_max;
unsigned long old_u_volt, old_u_volt_min, old_u_volt_max;
int ret;

if (unlikely(!target_freq)) {
Expand Down Expand Up @@ -633,6 +634,14 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
return ret;
}

if (IS_ERR(old_opp)) {
old_u_volt = 0;
} else {
old_u_volt = old_opp->u_volt;
old_u_volt_min = old_opp->u_volt_min;
old_u_volt_max = old_opp->u_volt_max;
}

u_volt = opp->u_volt;
u_volt_min = opp->u_volt_min;
u_volt_max = opp->u_volt_max;
Expand Down Expand Up @@ -677,9 +686,10 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
__func__, old_freq);
restore_voltage:
/* This shouldn't harm even if the voltages weren't updated earlier */
if (!IS_ERR(old_opp))
_set_opp_voltage(dev, reg, old_opp->u_volt,
old_opp->u_volt_min, old_opp->u_volt_max);
if (old_u_volt) {
_set_opp_voltage(dev, reg, old_u_volt, old_u_volt_min,
old_u_volt_max);
}

return ret;
}
Expand Down

0 comments on commit dc39d06

Please sign in to comment.