[PATCH] regulator: core: allow non-exact matches in regulator_set_voltage_time()

From: Lucas Stach
Date: Wed May 21 2014 - 12:54:10 EST


Currently this function only provides a valid output if both
old_uV and new_uV are exact voltages that can be provided by the
regulator.
This is almost impossible to achive as the consumer has
no way to know the exact voltages provided by the regulator.
Also it creates an unexpected twist in the API, as a user
could possibly not use the same voltage parameters for
set_voltage_time() as for set_voltage_time().

This breaks the current cpufreq users of this function, as they
stick in the raw voltages retrieved from their operating points,
which may or may not match one of the regulator voltages.

To make this function behave as expected employ the same logic
as used when calling set_voltage() and round the voltages to
the closest matching voltage supported by the regulator.

Signed-off-by: Lucas Stach <l.stach@xxxxxxxxxxxxxx>
---
drivers/regulator/core.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 9a09f3cdbabb..29ab83f49da9 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2477,7 +2477,7 @@ int regulator_set_voltage_time(struct regulator *regulator,
struct regulator_ops *ops = rdev->desc->ops;
int old_sel = -1;
int new_sel = -1;
- int voltage;
+ int voltage, best_match_old_uV = INT_MAX, best_match_new_uV = INT_MAX;
int i;

/* Currently requires operations to do this */
@@ -2486,16 +2486,19 @@ int regulator_set_voltage_time(struct regulator *regulator,
return -EINVAL;

for (i = 0; i < rdev->desc->n_voltages; i++) {
- /* We only look for exact voltage matches here */
voltage = regulator_list_voltage(regulator, i);
if (voltage < 0)
return -EINVAL;
if (voltage == 0)
continue;
- if (voltage == old_uV)
+ if (voltage >= old_uV && voltage < best_match_old_uV) {
old_sel = i;
- if (voltage == new_uV)
+ best_match_old_uV = voltage;
+ }
+ if (voltage >= new_uV && voltage < best_match_new_uV) {
new_sel = i;
+ best_match_new_uV = voltage;
+ }
}

if (old_sel < 0 || new_sel < 0)
--
2.0.0.rc0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/