Browse Source

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+ <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>
Viresh Kumar 8 năm trước cách đây
mục cha
commit
dc39d06fcd
1 tập tin đã thay đổi với 13 bổ sung3 xóa
  1. 13 3
      drivers/base/power/opp/core.c

+ 13 - 3
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;
 	struct clk *clk;
 	unsigned long freq, old_freq;
 	unsigned long freq, old_freq;
 	unsigned long u_volt, u_volt_min, u_volt_max;
 	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;
 	int ret;
 
 
 	if (unlikely(!target_freq)) {
 	if (unlikely(!target_freq)) {
@@ -633,6 +634,14 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
 		return ret;
 		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 = opp->u_volt;
 	u_volt_min = opp->u_volt_min;
 	u_volt_min = opp->u_volt_min;
 	u_volt_max = opp->u_volt_max;
 	u_volt_max = opp->u_volt_max;
@@ -677,9 +686,10 @@ restore_freq:
 			__func__, old_freq);
 			__func__, old_freq);
 restore_voltage:
 restore_voltage:
 	/* This shouldn't harm even if the voltages weren't updated earlier */
 	/* 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;
 	return ret;
 }
 }