regulator: Fixes for v7.2

One driver specific fix where one of the MediaTek drivers duplicated
 some core code buggily, and a core fix for an ordering issue on startup
 where we could end up configuring a voltage outside of constraints due
 to the order in which we applied constraints.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmpmMC4ACgkQJNaLcl1U
 h9DoiAf/V64CUAFspev+AtzWpx1Su9zZoSzoMM5Gj0WBuMoo4G5hZj804DQ/n8al
 sai+f0loMEVcblfpZNOlYagSkDgvvIc/1SQrAQ1oIxMbpotE1vn4htzGsJJuwwgL
 lh5GC4CsrXOSRX3VG6pJeBR6RTb9VEbkAhLoxKAJyPlcynk2KdBPwR9B1ZlCgpe6
 MP2WrurEVexvuDlZdE8THYth4FXCms0uH5VLo+Q3G4r1Ayt9YpvbvG91fzJSJGti
 NAzAWma2GFGwQkka5sgMYHyP6rwM1vJ71mz+Bq9G5fUe6DyEp85jv993D5lq2vbH
 69GO6ZTZmruCqOkDEELIKA4EpKYzZA==
 =3XbV
 -----END PGP SIGNATURE-----

Merge tag 'regulator-fix-v7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator fixes from Mark Brown:
 "One driver specific fix where one of the MediaTek drivers duplicated
  some core code buggily, and a core fix for an ordering issue on
  startup where we could end up configuring a voltage outside of
  constraints due to the order in which we applied constraints"

* tag 'regulator-fix-v7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: core: clamp voltage constraints before applying apply_uV
  regulator: mt6358: use regmap helper to read fixed LDO calibration
This commit is contained in:
Linus Torvalds 2026-07-26 11:52:30 -07:00
commit e6bfeebfe1
2 changed files with 91 additions and 74 deletions

View File

@ -1220,10 +1220,98 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
{
const struct regulator_ops *ops = rdev->desc->ops;
int ret;
bool apply_uV;
/*
* Decide up front, from the constraints as handed to us, whether
* apply_uV needs to run below. The clamping pass right after this
* may rewrite constraints->min_uV/max_uV (e.g. the fixed-voltage
* autoconfigure case), and we don't want that to change whether
* apply_uV fires.
*/
apply_uV = rdev->constraints->apply_uV &&
rdev->constraints->min_uV && rdev->constraints->max_uV;
/*
* Constrain machine-level voltage specs to fit the actual range
* supported by this regulator before apply_uV (below) tries to
* force hardware to a value from that range: otherwise apply_uV
* can target a constraint value that doesn't correspond to any
* real voltage selector and fail registration outright, even
* though the clamping pass would have narrowed it to a value
* the regulator can actually hit.
*/
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)) {
/* nothing more to do */
/* else require explicit machine-level constraints */
} else if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
rdev_err(rdev, "invalid voltage constraints\n");
return -EINVAL;
/* no need to loop voltages if range is continuous */
} else if (rdev->desc->continuous_voltage_range) {
/* nothing more to do */
} else {
/* 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) {
rdev_err(rdev,
"unsupportable voltage constraints %u-%uuV\n",
min_uV, max_uV);
return -EINVAL;
}
/* use regulator's subset of machine constraints */
if (constraints->min_uV < min_uV) {
rdev_dbg(rdev, "override min_uV, %d -> %d\n",
constraints->min_uV, min_uV);
constraints->min_uV = min_uV;
}
if (constraints->max_uV > max_uV) {
rdev_dbg(rdev, "override max_uV, %d -> %d\n",
constraints->max_uV, max_uV);
constraints->max_uV = max_uV;
}
}
}
/* do we need to apply the constraint voltage */
if (rdev->constraints->apply_uV &&
rdev->constraints->min_uV && rdev->constraints->max_uV) {
if (apply_uV) {
int target_min, target_max;
int current_uV = regulator_get_voltage_rdev(rdev);
@ -1278,77 +1366,6 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
}
}
/* 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) {
rdev_err(rdev, "invalid voltage constraints\n");
return -EINVAL;
}
/* no need to loop voltages if range is continuous */
if (rdev->desc->continuous_voltage_range)
return 0;
/* 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) {
rdev_err(rdev,
"unsupportable voltage constraints %u-%uuV\n",
min_uV, max_uV);
return -EINVAL;
}
/* use regulator's subset of machine constraints */
if (constraints->min_uV < min_uV) {
rdev_dbg(rdev, "override min_uV, %d -> %d\n",
constraints->min_uV, min_uV);
constraints->min_uV = min_uV;
}
if (constraints->max_uV > max_uV) {
rdev_dbg(rdev, "override max_uV, %d -> %d\n",
constraints->max_uV, max_uV);
constraints->max_uV = max_uV;
}
}
return 0;
}

View File

@ -492,7 +492,7 @@ static const struct regulator_ops mt6358_volt_fixed_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = mt6358_get_buck_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,