From e79055d62ea6ca3c36962209f4c819614972c95a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 Oct 2009 15:53:50 +0100 Subject: [PATCH] regulator: Factor out voltage constraint setup This allows constraints to take effect on regulators that support voltage setting but for which the board does not specify a voltage range (for example, because it is fixed correctly at system startup). Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 148 +++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 69 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 9b43dab16387..c1a49917af24 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -672,6 +672,82 @@ static void print_constraints(struct regulator_dev *rdev) printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf); } +static int machine_constraints_voltage(struct regulator_dev *rdev, + const char *name, struct regulation_constraints *constraints) +{ + struct regulator_ops *ops = rdev->desc->ops; + + /* constrain machine-level voltage specs to fit + * the actual range supported by this regulator. + */ + if (ops->list_voltage && rdev->desc->n_voltages) { + int count = rdev->desc->n_voltages; + int i; + int min_uV = INT_MAX; + int max_uV = INT_MIN; + int cmin = constraints->min_uV; + int cmax = constraints->max_uV; + + /* it's safe to autoconfigure fixed-voltage supplies + and the constraints are used by list_voltage. */ + if (count == 1 && !cmin) { + cmin = 1; + cmax = INT_MAX; + constraints->min_uV = cmin; + constraints->max_uV = cmax; + } + + /* voltage constraints are optional */ + if ((cmin == 0) && (cmax == 0)) + return 0; + + /* else require explicit machine-level constraints */ + if (cmin <= 0 || cmax <= 0 || cmax < cmin) { + pr_err("%s: %s '%s' voltage constraints\n", + __func__, "invalid", name); + return -EINVAL; + } + + /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ + for (i = 0; i < count; i++) { + int value; + + value = ops->list_voltage(rdev, i); + if (value <= 0) + continue; + + /* maybe adjust [min_uV..max_uV] */ + if (value >= cmin && value < min_uV) + min_uV = value; + if (value <= cmax && value > max_uV) + max_uV = value; + } + + /* final: [min_uV..max_uV] valid iff constraints valid */ + if (max_uV < min_uV) { + pr_err("%s: %s '%s' voltage constraints\n", + __func__, "unsupportable", name); + return -EINVAL; + } + + /* use regulator's subset of machine constraints */ + if (constraints->min_uV < min_uV) { + pr_debug("%s: override '%s' %s, %d -> %d\n", + __func__, name, "min_uV", + constraints->min_uV, min_uV); + constraints->min_uV = min_uV; + } + if (constraints->max_uV > max_uV) { + pr_debug("%s: override '%s' %s, %d -> %d\n", + __func__, name, "max_uV", + constraints->max_uV, max_uV); + constraints->max_uV = max_uV; + } + } + + return 0; +} + /** * set_machine_constraints - sets regulator constraints * @rdev: regulator source @@ -697,75 +773,9 @@ static int set_machine_constraints(struct regulator_dev *rdev, else name = "regulator"; - /* constrain machine-level voltage specs to fit - * the actual range supported by this regulator. - */ - if (ops->list_voltage && rdev->desc->n_voltages) { - int count = rdev->desc->n_voltages; - int i; - int min_uV = INT_MAX; - int max_uV = INT_MIN; - int cmin = constraints->min_uV; - int cmax = constraints->max_uV; - - /* it's safe to autoconfigure fixed-voltage supplies - and the constraints are used by list_voltage. */ - if (count == 1 && !cmin) { - cmin = 1; - cmax = INT_MAX; - constraints->min_uV = cmin; - constraints->max_uV = cmax; - } - - /* voltage constraints are optional */ - if ((cmin == 0) && (cmax == 0)) - goto out; - - /* else require explicit machine-level constraints */ - if (cmin <= 0 || cmax <= 0 || cmax < cmin) { - pr_err("%s: %s '%s' voltage constraints\n", - __func__, "invalid", name); - ret = -EINVAL; - goto out; - } - - /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ - for (i = 0; i < count; i++) { - int value; - - value = ops->list_voltage(rdev, i); - if (value <= 0) - continue; - - /* maybe adjust [min_uV..max_uV] */ - if (value >= cmin && value < min_uV) - min_uV = value; - if (value <= cmax && value > max_uV) - max_uV = value; - } - - /* final: [min_uV..max_uV] valid iff constraints valid */ - if (max_uV < min_uV) { - pr_err("%s: %s '%s' voltage constraints\n", - __func__, "unsupportable", name); - ret = -EINVAL; - goto out; - } - - /* use regulator's subset of machine constraints */ - if (constraints->min_uV < min_uV) { - pr_debug("%s: override '%s' %s, %d -> %d\n", - __func__, name, "min_uV", - constraints->min_uV, min_uV); - constraints->min_uV = min_uV; - } - if (constraints->max_uV > max_uV) { - pr_debug("%s: override '%s' %s, %d -> %d\n", - __func__, name, "max_uV", - constraints->max_uV, max_uV); - constraints->max_uV = max_uV; - } - } + ret = machine_constraints_voltage(rdev, name, constraints); + if (ret != 0) + goto out; rdev->constraints = constraints;