diff options
author | Viresh Kumar <[email protected]> | 2016-12-01 16:28:16 +0530 |
---|---|---|
committer | Rafael J. Wysocki <[email protected]> | 2016-12-06 02:27:58 +0100 |
commit | dc39d06fcd7a4a82d72eae7b71e94e888b96d29e (patch) | |
tree | 04f21672abaa37c78df542b32dca24b4997965f3 | |
parent | 579c49efdf5a04869b29891e46cde0ed4df5480a (diff) |
PM / OPP: Don't use OPP structure outside of rcu protected section
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+ <[email protected]> # 4.6+
Signed-off-by: Viresh Kumar <[email protected]>
Reviewed-by: Stephen Boyd <[email protected]>
Tested-by: Dave Gerlach <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
-rw-r--r-- | drivers/base/power/opp/core.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 2824d3a5e9f0..6441dfda489f 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -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)) { @@ -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; @@ -677,9 +686,10 @@ restore_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; } |