]>
Commit | Line | Data |
---|---|---|
81e265ea GKH |
1 | From c88c395f4a6485f23f81e385c79945d68bcd5c5d Mon Sep 17 00:00:00 2001 |
2 | From: Viresh Kumar <viresh.kumar@linaro.org> | |
3 | Date: Mon, 15 Feb 2016 10:21:53 +0530 | |
4 | Subject: PM / OPP: Initialize u_volt_min/max to a valid value | |
5 | ||
6 | From: Viresh Kumar <viresh.kumar@linaro.org> | |
7 | ||
8 | commit c88c395f4a6485f23f81e385c79945d68bcd5c5d upstream. | |
9 | ||
10 | We kept u_volt_min/max initialized to 0, when only the target voltage is | |
11 | present in DT, instead of the target/min/max triplet. | |
12 | ||
13 | This didn't go well with the regulator framework, as on few calls the | |
14 | min voltage was set to target and max was set to 0 and so resulted in a | |
15 | kernel crash like below: | |
16 | ||
17 | kernel BUG at ../drivers/regulator/core.c:216! | |
18 | ||
19 | [<c0684af4>] (regulator_check_voltage) from [<c06857ac>] (regulator_set_voltage_unlocked+0x58/0x230) | |
20 | [<c06857ac>] (regulator_set_voltage_unlocked) from [<c06859ac>] (regulator_set_voltage+0x28/0x54) | |
21 | [<c06859ac>] (regulator_set_voltage) from [<c0775b28>] (_set_opp_voltage+0x30/0x98) | |
22 | [<c0775b28>] (_set_opp_voltage) from [<c0776630>] (dev_pm_opp_set_rate+0xf0/0x28c) | |
23 | [<c0776630>] (dev_pm_opp_set_rate) from [<c096f784>] (__cpufreq_driver_target+0x184/0x2b4) | |
24 | [<c096f784>] (__cpufreq_driver_target) from [<c0973760>] (dbs_check_cpu+0x1b0/0x1f4) | |
25 | [<c0973760>] (dbs_check_cpu) from [<c0973f30>] (cpufreq_governor_dbs+0x324/0x5c4) | |
26 | [<c0973f30>] (cpufreq_governor_dbs) from [<c0970958>] (__cpufreq_governor+0xe4/0x1ec) | |
27 | [<c0970958>] (__cpufreq_governor) from [<c09711e0>] (cpufreq_init_policy+0x64/0x8c) | |
28 | [<c09711e0>] (cpufreq_init_policy) from [<c09718cc>] (cpufreq_online+0x2fc/0x708) | |
29 | [<c09718cc>] (cpufreq_online) from [<c0765ff0>] (subsys_interface_register+0x94/0xd8) | |
30 | [<c0765ff0>] (subsys_interface_register) from [<c0970530>] (cpufreq_register_driver+0x14c/0x19c) | |
31 | [<c0970530>] (cpufreq_register_driver) from [<c09746dc>] (dt_cpufreq_probe+0x70/0xec) | |
32 | [<c09746dc>] (dt_cpufreq_probe) from [<c076907c>] (platform_drv_probe+0x4c/0xb0) | |
33 | [<c076907c>] (platform_drv_probe) from [<c07678e0>] (driver_probe_device+0x214/0x2c0) | |
34 | [<c07678e0>] (driver_probe_device) from [<c0767a18>] (__driver_attach+0x8c/0x90) | |
35 | [<c0767a18>] (__driver_attach) from [<c0765c2c>] (bus_for_each_dev+0x68/0x9c) | |
36 | [<c0765c2c>] (bus_for_each_dev) from [<c0766d78>] (bus_add_driver+0x1a0/0x218) | |
37 | [<c0766d78>] (bus_add_driver) from [<c076810c>] (driver_register+0x78/0xf8) | |
38 | [<c076810c>] (driver_register) from [<c0301d74>] (do_one_initcall+0x90/0x1d8) | |
39 | [<c0301d74>] (do_one_initcall) from [<c1100e14>] (kernel_init_freeable+0x15c/0x1fc) | |
40 | [<c1100e14>] (kernel_init_freeable) from [<c0b27a0c>] (kernel_init+0x8/0xf0) | |
41 | [<c0b27a0c>] (kernel_init) from [<c0307d78>] (ret_from_fork+0x14/0x3c) | |
42 | Code: e1550004 baffffeb e3a00000 e8bd8070 (e7f001f2) | |
43 | ||
44 | Fix that by initializing u_volt_min/max to the target voltage in such cases. | |
45 | ||
46 | Reported-and-tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> | |
47 | Fixes: 274659029c9d (PM / OPP: Add support to parse "operating-points-v2" bindings) | |
48 | Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> | |
49 | Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | |
50 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
51 | ||
52 | --- | |
53 | drivers/base/power/opp/core.c | 10 ++++++++-- | |
54 | 1 file changed, 8 insertions(+), 2 deletions(-) | |
55 | ||
56 | --- a/drivers/base/power/opp/core.c | |
57 | +++ b/drivers/base/power/opp/core.c | |
58 | @@ -809,8 +809,14 @@ static int opp_parse_supplies(struct dev | |
59 | } | |
60 | ||
61 | opp->u_volt = microvolt[0]; | |
62 | - opp->u_volt_min = microvolt[1]; | |
63 | - opp->u_volt_max = microvolt[2]; | |
64 | + | |
65 | + if (count == 1) { | |
66 | + opp->u_volt_min = opp->u_volt; | |
67 | + opp->u_volt_max = opp->u_volt; | |
68 | + } else { | |
69 | + opp->u_volt_min = microvolt[1]; | |
70 | + opp->u_volt_max = microvolt[2]; | |
71 | + } | |
72 | ||
73 | if (!of_property_read_u32(opp->np, "opp-microamp", &val)) | |
74 | opp->u_amp = val; |