diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e63366f826f9..a1b12379b09f 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -142,6 +142,27 @@ static int regulator_check_voltage(struct regulator_dev *rdev, return 0; } +/* Make sure we select a voltage that suits the needs of all + * regulator consumers + */ +static int regulator_check_consumers(struct regulator_dev *rdev, + int *min_uV, int *max_uV) +{ + struct regulator *regulator; + + list_for_each_entry(regulator, &rdev->consumer_list, list) { + if (*max_uV > regulator->max_uV) + *max_uV = regulator->max_uV; + if (*min_uV < regulator->min_uV) + *min_uV = regulator->min_uV; + } + + if (*min_uV > *max_uV) + return -EINVAL; + + return 0; +} + /* current constraint check */ static int regulator_check_current_limit(struct regulator_dev *rdev, int *min_uA, int *max_uA) @@ -1637,6 +1658,10 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) regulator->min_uV = min_uV; regulator->max_uV = max_uV; + ret = regulator_check_consumers(rdev, &min_uV, &max_uV); + if (ret < 0) + goto out; + trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector);