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 <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
This commit is contained in:
Родитель
5b30762773
Коммит
e79055d62e
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче