regulator: Fixes for v5.10

Mostly core fixes here, one set from Michał Mirosław which cleans up
 some issues introduced as part of the coupled regulators work, one
 memory leak during probe and two due to regulators which have an input
 supply name and regulator name which are identical, which is very
 unusual.  There's also a fix for our handling of the similarly unusual
 case where we can't determine if a regulator is enabled during boot.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl+2rrIACgkQJNaLcl1U
 h9BaJwf+OYQtWUrn7QgM3kceZBrMh8zOZs20aM78gYZW1HgEqnvULHUQn7yh84MP
 M17BXdV2/cJZhUhDzwGimBOXpU7uYPy4Wglfoz6q/TpIPnQUDGXPLhmYB6+zJjJy
 VCm2rb0Mk1WOkH5RhNV16vikq4R+FbY5kV6kIYMjaLx9iaDjxEqPmz988VbEEyWN
 MUi4V890CiWCzj9WlrVJOxFM90VNuLwlq3ecfLwLmFyH68JC+2TCC6fTFiH1MHD3
 JB1p5JVU+2VgRtGDB9u58HJJZKSgHMs8snm+bdiDfnHRe0+hSkr5VSJSxNCpSbuW
 sjOV9kE0gDO09DsZGM0jhi6sT98iBw==
 =34Nk
 -----END PGP SIGNATURE-----

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

Pull regulator fixes from Mark Brown:
 "Mostly core fixes here, one set from Michał Mirosław which cleans up
  some issues introduced as part of the coupled regulators work, one
  memory leak during probe and two due to regulators which have an input
  supply name and regulator name which are identical, which is very
  unusual.

  There's also a fix for our handling of the similarly unusual case
  where we can't determine if a regulator is enabled during boot"

* tag 'regulator-fix-v5.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: ti-abb: Fix array out of bound read access on the first transition
  regulator: workaround self-referent regulators
  regulator: avoid resolve_supply() infinite recursion
  regulator: fix memory leak with repeated set_machine_constraints()
  regulator: pfuze100: limit pfuze-support-disable-sw to pfuze{100,200}
  regulator: core: don't disable regulator if is_enabled return error.
This commit is contained in:
Linus Torvalds 2020-11-19 10:55:54 -08:00
commit d748287a28
3 changed files with 44 additions and 24 deletions

View file

@ -1315,7 +1315,6 @@ static int _regulator_do_enable(struct regulator_dev *rdev);
/**
* set_machine_constraints - sets regulator constraints
* @rdev: regulator source
* @constraints: constraints to apply
*
* Allows platform initialisation code to define and constrain
* regulator circuits e.g. valid voltage/current ranges, etc. NOTE:
@ -1323,21 +1322,11 @@ static int _regulator_do_enable(struct regulator_dev *rdev);
* regulator operations to proceed i.e. set_voltage, set_current_limit,
* set_mode.
*/
static int set_machine_constraints(struct regulator_dev *rdev,
const struct regulation_constraints *constraints)
static int set_machine_constraints(struct regulator_dev *rdev)
{
int ret = 0;
const struct regulator_ops *ops = rdev->desc->ops;
if (constraints)
rdev->constraints = kmemdup(constraints, sizeof(*constraints),
GFP_KERNEL);
else
rdev->constraints = kzalloc(sizeof(*constraints),
GFP_KERNEL);
if (!rdev->constraints)
return -ENOMEM;
ret = machine_constraints_voltage(rdev, rdev->constraints);
if (ret != 0)
return ret;
@ -1852,6 +1841,15 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
}
}
if (r == rdev) {
dev_err(dev, "Supply for %s (%s) resolved to itself\n",
rdev->desc->name, rdev->supply_name);
if (!have_full_constraints())
return -EINVAL;
r = dummy_regulator_rdev;
get_device(&r->dev);
}
/*
* If the supply's parent device is not the same as the
* regulator's parent device, then ensure the parent device
@ -5146,7 +5144,6 @@ struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc,
const struct regulator_config *cfg)
{
const struct regulation_constraints *constraints = NULL;
const struct regulator_init_data *init_data;
struct regulator_config *config = NULL;
static atomic_t regulator_no = ATOMIC_INIT(-1);
@ -5285,14 +5282,23 @@ regulator_register(const struct regulator_desc *regulator_desc,
/* set regulator constraints */
if (init_data)
constraints = &init_data->constraints;
rdev->constraints = kmemdup(&init_data->constraints,
sizeof(*rdev->constraints),
GFP_KERNEL);
else
rdev->constraints = kzalloc(sizeof(*rdev->constraints),
GFP_KERNEL);
if (!rdev->constraints) {
ret = -ENOMEM;
goto wash;
}
if (init_data && init_data->supply_regulator)
rdev->supply_name = init_data->supply_regulator;
else if (regulator_desc->supply_name)
rdev->supply_name = regulator_desc->supply_name;
ret = set_machine_constraints(rdev, constraints);
ret = set_machine_constraints(rdev);
if (ret == -EPROBE_DEFER) {
/* Regulator might be in bypass mode and so needs its supply
* to set the constraints */
@ -5301,7 +5307,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
* that is just being created */
ret = regulator_resolve_supply(rdev);
if (!ret)
ret = set_machine_constraints(rdev, constraints);
ret = set_machine_constraints(rdev);
else
rdev_dbg(rdev, "unable to resolve supply early: %pe\n",
ERR_PTR(ret));
@ -5843,13 +5849,14 @@ static int regulator_late_cleanup(struct device *dev, void *data)
if (rdev->use_count)
goto unlock;
/* If we can't read the status assume it's on. */
/* If we can't read the status assume it's always on. */
if (ops->is_enabled)
enabled = ops->is_enabled(rdev);
else
enabled = 1;
if (!enabled)
/* But if reading the status failed, assume that it's off. */
if (enabled <= 0)
goto unlock;
if (have_full_constraints()) {

View file

@ -836,11 +836,14 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
* the switched regulator till yet.
*/
if (pfuze_chip->flags & PFUZE_FLAG_DISABLE_SW) {
if (pfuze_chip->regulator_descs[i].sw_reg) {
desc->ops = &pfuze100_sw_disable_regulator_ops;
desc->enable_val = 0x8;
desc->disable_val = 0x0;
desc->enable_time = 500;
if (pfuze_chip->chip_id == PFUZE100 ||
pfuze_chip->chip_id == PFUZE200) {
if (pfuze_chip->regulator_descs[i].sw_reg) {
desc->ops = &pfuze100_sw_disable_regulator_ops;
desc->enable_val = 0x8;
desc->disable_val = 0x0;
desc->enable_time = 500;
}
}
}

View file

@ -342,8 +342,17 @@ static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel)
return ret;
}
/* If data is exactly the same, then just update index, no change */
info = &abb->info[sel];
/*
* When Linux kernel is starting up, we are'nt sure of the
* Bias configuration that bootloader has configured.
* So, we get to know the actual setting the first time
* we are asked to transition.
*/
if (abb->current_info_idx == -EINVAL)
goto just_set_abb;
/* If data is exactly the same, then just update index, no change */
oinfo = &abb->info[abb->current_info_idx];
if (!memcmp(info, oinfo, sizeof(*info))) {
dev_dbg(dev, "%s: Same data new idx=%d, old idx=%d\n", __func__,
@ -351,6 +360,7 @@ static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel)
goto out;
}
just_set_abb:
ret = ti_abb_set_opp(rdev, abb, info);
out: