diff options
author | Kevin Hilman <khilman@ti.com> | 2012-03-02 17:08:57 -0500 |
---|---|---|
committer | Kevin Hilman <khilman@ti.com> | 2012-03-06 20:37:14 -0500 |
commit | c15f1d84bb3ddd668593e9bca53221a2f82e9e99 (patch) | |
tree | 96e4bbcab2b9c470b0e3a27e2d8b62f9cb9b254b | |
parent | e160dda0f49f54deddd62e943e449a13430c2e8b (diff) |
ARM: OMAP2+: voltage: ensure voltage used is exact voltage from OPP table
When using the SMPS regulators to scale voltages, the regulator
framework may pass a minimum voltage that is not an exact OPP voltage.
For the VC/VP controlled voltage domains, we must ensure that the
voltage requested is the exact voltage from the OPP table. This is
especially critical when using SR.
To fix, voltdm_scale() uses the target voltage passed to walk through
the OPP voltages until it finds a voltage that is >= one of the OPP
voltages.
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/voltage.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index 8a36342e60d2..4dc60e83e00d 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c | |||
@@ -73,7 +73,8 @@ unsigned long voltdm_get_voltage(struct voltagedomain *voltdm) | |||
73 | int voltdm_scale(struct voltagedomain *voltdm, | 73 | int voltdm_scale(struct voltagedomain *voltdm, |
74 | unsigned long target_volt) | 74 | unsigned long target_volt) |
75 | { | 75 | { |
76 | int ret; | 76 | int ret, i; |
77 | unsigned long volt = 0; | ||
77 | 78 | ||
78 | if (!voltdm || IS_ERR(voltdm)) { | 79 | if (!voltdm || IS_ERR(voltdm)) { |
79 | pr_warning("%s: VDD specified does not exist!\n", __func__); | 80 | pr_warning("%s: VDD specified does not exist!\n", __func__); |
@@ -86,9 +87,23 @@ int voltdm_scale(struct voltagedomain *voltdm, | |||
86 | return -ENODATA; | 87 | return -ENODATA; |
87 | } | 88 | } |
88 | 89 | ||
89 | ret = voltdm->scale(voltdm, target_volt); | 90 | /* Adjust voltage to the exact voltage from the OPP table */ |
91 | for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) { | ||
92 | if (voltdm->volt_data[i].volt_nominal >= target_volt) { | ||
93 | volt = voltdm->volt_data[i].volt_nominal; | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | if (!volt) { | ||
99 | pr_warning("%s: not scaling. OPP voltage for %lu, not found.\n", | ||
100 | __func__, target_volt); | ||
101 | return -EINVAL; | ||
102 | } | ||
103 | |||
104 | ret = voltdm->scale(voltdm, volt); | ||
90 | if (!ret) | 105 | if (!ret) |
91 | voltdm->nominal_volt = target_volt; | 106 | voltdm->nominal_volt = volt; |
92 | 107 | ||
93 | return ret; | 108 | return ret; |
94 | } | 109 | } |