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);
/**
* 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()) {
......
......@@ -836,6 +836,8 @@ 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->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;
......@@ -843,6 +845,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
desc->enable_time = 500;
}
}
}
config.dev = &client->dev;
config.init_data = init_data;
......
......@@ -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:
......
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