summaryrefslogtreecommitdiffstats
path: root/drivers/devfreq
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2016-12-05 08:53:52 +0530
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-12-08 01:46:07 +0100
commite37d35082e75982ef714f9e25bfa43a061d0c5e6 (patch)
tree5c4a2fa8a614c3592249972c54a6850c61aff126 /drivers/devfreq
parentd8323de3d4062e1b5a5aa7e9c0f935138405a582 (diff)
downloadlinux-e37d35082e75982ef714f9e25bfa43a061d0c5e6.tar.gz
linux-e37d35082e75982ef714f9e25bfa43a061d0c5e6.tar.bz2
linux-e37d35082e75982ef714f9e25bfa43a061d0c5e6.zip
devfreq: rk3399_dmc: Don't use OPP structures outside of RCU locks
The OPP structures are abused to the best here, without understanding how the OPP core and RCU locks work. In short, the OPP pointer saved in 'rk3399_dmcfreq' can become invalid under your nose, as the OPP core may free it. Fix various abuses around OPP structures and calls. Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/devfreq')
-rw-r--r--drivers/devfreq/rk3399_dmc.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 971ee6358456..27d2f349b53c 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -80,7 +80,6 @@ struct rk3399_dmcfreq {
struct regulator *vdd_center;
unsigned long rate, target_rate;
unsigned long volt, target_volt;
- struct dev_pm_opp *curr_opp;
};
static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
@@ -102,9 +101,6 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
target_rate = dev_pm_opp_get_freq(opp);
target_volt = dev_pm_opp_get_voltage(opp);
- dmcfreq->rate = dev_pm_opp_get_freq(dmcfreq->curr_opp);
- dmcfreq->volt = dev_pm_opp_get_voltage(dmcfreq->curr_opp);
-
rcu_read_unlock();
if (dmcfreq->rate == target_rate)
@@ -165,7 +161,9 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
if (err)
dev_err(dev, "Cannot to set vol %lu uV\n", target_volt);
- dmcfreq->curr_opp = opp;
+ dmcfreq->rate = target_rate;
+ dmcfreq->volt = target_volt;
+
out:
mutex_unlock(&dmcfreq->lock);
return err;
@@ -430,8 +428,9 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
rcu_read_unlock();
return PTR_ERR(opp);
}
+ data->rate = dev_pm_opp_get_freq(opp);
+ data->volt = dev_pm_opp_get_voltage(opp);
rcu_read_unlock();
- data->curr_opp = opp;
rk3399_devfreq_dmc_profile.initial_freq = data->rate;