Commit d748287a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regulator-fix-v5.10-rc4' of...

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.
parents 841d6e9e 2ba546eb
...@@ -1315,7 +1315,6 @@ static int _regulator_do_enable(struct regulator_dev *rdev); ...@@ -1315,7 +1315,6 @@ static int _regulator_do_enable(struct regulator_dev *rdev);
/** /**
* set_machine_constraints - sets regulator constraints * set_machine_constraints - sets regulator constraints
* @rdev: regulator source * @rdev: regulator source
* @constraints: constraints to apply
* *
* Allows platform initialisation code to define and constrain * Allows platform initialisation code to define and constrain
* regulator circuits e.g. valid voltage/current ranges, etc. NOTE: * regulator circuits e.g. valid voltage/current ranges, etc. NOTE:
...@@ -1323,21 +1322,11 @@ static int _regulator_do_enable(struct regulator_dev *rdev); ...@@ -1323,21 +1322,11 @@ static int _regulator_do_enable(struct regulator_dev *rdev);
* regulator operations to proceed i.e. set_voltage, set_current_limit, * regulator operations to proceed i.e. set_voltage, set_current_limit,
* set_mode. * set_mode.
*/ */
static int set_machine_constraints(struct regulator_dev *rdev, static int set_machine_constraints(struct regulator_dev *rdev)
const struct regulation_constraints *constraints)
{ {
int ret = 0; int ret = 0;
const struct regulator_ops *ops = rdev->desc->ops; 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); ret = machine_constraints_voltage(rdev, rdev->constraints);
if (ret != 0) if (ret != 0)
return ret; return ret;
...@@ -1852,6 +1841,15 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) ...@@ -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 * If the supply's parent device is not the same as the
* regulator's parent device, then ensure the parent device * regulator's parent device, then ensure the parent device
...@@ -5146,7 +5144,6 @@ struct regulator_dev * ...@@ -5146,7 +5144,6 @@ struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc, regulator_register(const struct regulator_desc *regulator_desc,
const struct regulator_config *cfg) const struct regulator_config *cfg)
{ {
const struct regulation_constraints *constraints = NULL;
const struct regulator_init_data *init_data; const struct regulator_init_data *init_data;
struct regulator_config *config = NULL; struct regulator_config *config = NULL;
static atomic_t regulator_no = ATOMIC_INIT(-1); static atomic_t regulator_no = ATOMIC_INIT(-1);
...@@ -5285,14 +5282,23 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5285,14 +5282,23 @@ regulator_register(const struct regulator_desc *regulator_desc,
/* set regulator constraints */ /* set regulator constraints */
if (init_data) 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) if (init_data && init_data->supply_regulator)
rdev->supply_name = init_data->supply_regulator; rdev->supply_name = init_data->supply_regulator;
else if (regulator_desc->supply_name) else if (regulator_desc->supply_name)
rdev->supply_name = 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) { if (ret == -EPROBE_DEFER) {
/* Regulator might be in bypass mode and so needs its supply /* Regulator might be in bypass mode and so needs its supply
* to set the constraints */ * to set the constraints */
...@@ -5301,7 +5307,7 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5301,7 +5307,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
* that is just being created */ * that is just being created */
ret = regulator_resolve_supply(rdev); ret = regulator_resolve_supply(rdev);
if (!ret) if (!ret)
ret = set_machine_constraints(rdev, constraints); ret = set_machine_constraints(rdev);
else else
rdev_dbg(rdev, "unable to resolve supply early: %pe\n", rdev_dbg(rdev, "unable to resolve supply early: %pe\n",
ERR_PTR(ret)); ERR_PTR(ret));
...@@ -5843,13 +5849,14 @@ static int regulator_late_cleanup(struct device *dev, void *data) ...@@ -5843,13 +5849,14 @@ static int regulator_late_cleanup(struct device *dev, void *data)
if (rdev->use_count) if (rdev->use_count)
goto unlock; 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) if (ops->is_enabled)
enabled = ops->is_enabled(rdev); enabled = ops->is_enabled(rdev);
else else
enabled = 1; enabled = 1;
if (!enabled) /* But if reading the status failed, assume that it's off. */
if (enabled <= 0)
goto unlock; goto unlock;
if (have_full_constraints()) { if (have_full_constraints()) {
......
...@@ -836,6 +836,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client, ...@@ -836,6 +836,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
* the switched regulator till yet. * the switched regulator till yet.
*/ */
if (pfuze_chip->flags & PFUZE_FLAG_DISABLE_SW) { if (pfuze_chip->flags & PFUZE_FLAG_DISABLE_SW) {
if (pfuze_chip->chip_id == PFUZE100 ||
pfuze_chip->chip_id == PFUZE200) {
if (pfuze_chip->regulator_descs[i].sw_reg) { if (pfuze_chip->regulator_descs[i].sw_reg) {
desc->ops = &pfuze100_sw_disable_regulator_ops; desc->ops = &pfuze100_sw_disable_regulator_ops;
desc->enable_val = 0x8; desc->enable_val = 0x8;
...@@ -843,6 +845,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, ...@@ -843,6 +845,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
desc->enable_time = 500; desc->enable_time = 500;
} }
} }
}
config.dev = &client->dev; config.dev = &client->dev;
config.init_data = init_data; config.init_data = init_data;
......
...@@ -342,8 +342,17 @@ static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel) ...@@ -342,8 +342,17 @@ static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel)
return ret; return ret;
} }
/* If data is exactly the same, then just update index, no change */
info = &abb->info[sel]; 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]; oinfo = &abb->info[abb->current_info_idx];
if (!memcmp(info, oinfo, sizeof(*info))) { if (!memcmp(info, oinfo, sizeof(*info))) {
dev_dbg(dev, "%s: Same data new idx=%d, old idx=%d\n", __func__, 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) ...@@ -351,6 +360,7 @@ static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel)
goto out; goto out;
} }
just_set_abb:
ret = ti_abb_set_opp(rdev, abb, info); ret = ti_abb_set_opp(rdev, abb, info);
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment