Commit 8b6ce251 authored by Linus Torvalds's avatar Linus Torvalds

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

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

Pull regulator fixes from Mark Brown:
 "The biggest set of fixes here is those from Michał Mirosław fixing
  some locking issues with coupled regulators that are triggered in
  cases where a coupled regulator is used by a device involved in
  fs_reclaim like eMMC storage.

  These are relatively serious for the affected systems, though the
  circumstances where they trigger are very rare"

* tag 'regulator-fix-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: pwm: Fix machine constraints application
  regulator: core: Fix slab-out-of-bounds in regulator_unlock_recursive()
  regulator: remove superfluous lock in regulator_resolve_coupling()
  regulator: cleanup regulator_ena_gpio_free()
  regulator: plug of_node leak in regulator_register()'s error path
  regulator: push allocation in set_consumer_device_supply() out of lock
  regulator: push allocations in create_regulator() outside of lock
  regulator: push allocation in regulator_ena_gpio_request() out of lock
  regulator: push allocation in regulator_init_coupling() outside of lock
  regulator: fix spelling mistake "Cant" -> "Can't"
  regulator: cros-ec-regulator: Add NULL test for devm_kmemdup call
parents 063d6a4c 59ae97a7
...@@ -236,8 +236,8 @@ static bool regulator_supply_is_couple(struct regulator_dev *rdev) ...@@ -236,8 +236,8 @@ static bool regulator_supply_is_couple(struct regulator_dev *rdev)
static void regulator_unlock_recursive(struct regulator_dev *rdev, static void regulator_unlock_recursive(struct regulator_dev *rdev,
unsigned int n_coupled) unsigned int n_coupled)
{ {
struct regulator_dev *c_rdev; struct regulator_dev *c_rdev, *supply_rdev;
int i; int i, supply_n_coupled;
for (i = n_coupled; i > 0; i--) { for (i = n_coupled; i > 0; i--) {
c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1]; c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1];
...@@ -245,10 +245,13 @@ static void regulator_unlock_recursive(struct regulator_dev *rdev, ...@@ -245,10 +245,13 @@ static void regulator_unlock_recursive(struct regulator_dev *rdev,
if (!c_rdev) if (!c_rdev)
continue; continue;
if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) {
regulator_unlock_recursive( supply_rdev = c_rdev->supply->rdev;
c_rdev->supply->rdev, supply_n_coupled = supply_rdev->coupling_desc.n_coupled;
c_rdev->coupling_desc.n_coupled);
regulator_unlock_recursive(supply_rdev,
supply_n_coupled);
}
regulator_unlock(c_rdev); regulator_unlock(c_rdev);
} }
...@@ -1461,7 +1464,7 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, ...@@ -1461,7 +1464,7 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
const char *consumer_dev_name, const char *consumer_dev_name,
const char *supply) const char *supply)
{ {
struct regulator_map *node; struct regulator_map *node, *new_node;
int has_dev; int has_dev;
if (supply == NULL) if (supply == NULL)
...@@ -1472,6 +1475,22 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, ...@@ -1472,6 +1475,22 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
else else
has_dev = 0; has_dev = 0;
new_node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
if (new_node == NULL)
return -ENOMEM;
new_node->regulator = rdev;
new_node->supply = supply;
if (has_dev) {
new_node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
if (new_node->dev_name == NULL) {
kfree(new_node);
return -ENOMEM;
}
}
mutex_lock(&regulator_list_mutex);
list_for_each_entry(node, &regulator_map_list, list) { list_for_each_entry(node, &regulator_map_list, list) {
if (node->dev_name && consumer_dev_name) { if (node->dev_name && consumer_dev_name) {
if (strcmp(node->dev_name, consumer_dev_name) != 0) if (strcmp(node->dev_name, consumer_dev_name) != 0)
...@@ -1489,26 +1508,19 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, ...@@ -1489,26 +1508,19 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
node->regulator->desc->name, node->regulator->desc->name,
supply, supply,
dev_name(&rdev->dev), rdev_get_name(rdev)); dev_name(&rdev->dev), rdev_get_name(rdev));
return -EBUSY; goto fail;
} }
node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL); list_add(&new_node->list, &regulator_map_list);
if (node == NULL) mutex_unlock(&regulator_list_mutex);
return -ENOMEM;
node->regulator = rdev;
node->supply = supply;
if (has_dev) {
node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
if (node->dev_name == NULL) {
kfree(node);
return -ENOMEM;
}
}
list_add(&node->list, &regulator_map_list);
return 0; return 0;
fail:
mutex_unlock(&regulator_list_mutex);
kfree(new_node->dev_name);
kfree(new_node);
return -EBUSY;
} }
static void unset_regulator_supplies(struct regulator_dev *rdev) static void unset_regulator_supplies(struct regulator_dev *rdev)
...@@ -1580,44 +1592,53 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, ...@@ -1580,44 +1592,53 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
const char *supply_name) const char *supply_name)
{ {
struct regulator *regulator; struct regulator *regulator;
int err;
if (dev) {
char buf[REG_STR_SIZE]; char buf[REG_STR_SIZE];
int err, size; int size;
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
dev->kobj.name, supply_name);
if (size >= REG_STR_SIZE)
return NULL;
supply_name = kstrdup(buf, GFP_KERNEL);
if (supply_name == NULL)
return NULL;
} else {
supply_name = kstrdup_const(supply_name, GFP_KERNEL);
if (supply_name == NULL)
return NULL;
}
regulator = kzalloc(sizeof(*regulator), GFP_KERNEL); regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
if (regulator == NULL) if (regulator == NULL) {
kfree(supply_name);
return NULL; return NULL;
}
regulator_lock(rdev);
regulator->rdev = rdev; regulator->rdev = rdev;
regulator->supply_name = supply_name;
regulator_lock(rdev);
list_add(&regulator->list, &rdev->consumer_list); list_add(&regulator->list, &rdev->consumer_list);
regulator_unlock(rdev);
if (dev) { if (dev) {
regulator->dev = dev; regulator->dev = dev;
/* Add a link to the device sysfs entry */ /* Add a link to the device sysfs entry */
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
dev->kobj.name, supply_name);
if (size >= REG_STR_SIZE)
goto overflow_err;
regulator->supply_name = kstrdup(buf, GFP_KERNEL);
if (regulator->supply_name == NULL)
goto overflow_err;
err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj, err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj,
buf); supply_name);
if (err) { if (err) {
rdev_dbg(rdev, "could not add device link %s err %d\n", rdev_dbg(rdev, "could not add device link %s err %d\n",
dev->kobj.name, err); dev->kobj.name, err);
/* non-fatal */ /* non-fatal */
} }
} else {
regulator->supply_name = kstrdup_const(supply_name, GFP_KERNEL);
if (regulator->supply_name == NULL)
goto overflow_err;
} }
regulator->debugfs = debugfs_create_dir(regulator->supply_name, regulator->debugfs = debugfs_create_dir(supply_name,
rdev->debugfs); rdev->debugfs);
if (!regulator->debugfs) { if (!regulator->debugfs) {
rdev_dbg(rdev, "Failed to create debugfs directory\n"); rdev_dbg(rdev, "Failed to create debugfs directory\n");
...@@ -1642,13 +1663,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, ...@@ -1642,13 +1663,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
_regulator_is_enabled(rdev)) _regulator_is_enabled(rdev))
regulator->always_on = true; regulator->always_on = true;
regulator_unlock(rdev);
return regulator; return regulator;
overflow_err:
list_del(&regulator->list);
kfree(regulator);
regulator_unlock(rdev);
return NULL;
} }
static int _regulator_get_enable_time(struct regulator_dev *rdev) static int _regulator_get_enable_time(struct regulator_dev *rdev)
...@@ -2230,10 +2245,13 @@ EXPORT_SYMBOL_GPL(regulator_bulk_unregister_supply_alias); ...@@ -2230,10 +2245,13 @@ EXPORT_SYMBOL_GPL(regulator_bulk_unregister_supply_alias);
static int regulator_ena_gpio_request(struct regulator_dev *rdev, static int regulator_ena_gpio_request(struct regulator_dev *rdev,
const struct regulator_config *config) const struct regulator_config *config)
{ {
struct regulator_enable_gpio *pin; struct regulator_enable_gpio *pin, *new_pin;
struct gpio_desc *gpiod; struct gpio_desc *gpiod;
gpiod = config->ena_gpiod; gpiod = config->ena_gpiod;
new_pin = kzalloc(sizeof(*new_pin), GFP_KERNEL);
mutex_lock(&regulator_list_mutex);
list_for_each_entry(pin, &regulator_ena_gpio_list, list) { list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
if (pin->gpiod == gpiod) { if (pin->gpiod == gpiod) {
...@@ -2242,9 +2260,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, ...@@ -2242,9 +2260,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
} }
} }
pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL); if (new_pin == NULL) {
if (pin == NULL) mutex_unlock(&regulator_list_mutex);
return -ENOMEM; return -ENOMEM;
}
pin = new_pin;
new_pin = NULL;
pin->gpiod = gpiod; pin->gpiod = gpiod;
list_add(&pin->list, &regulator_ena_gpio_list); list_add(&pin->list, &regulator_ena_gpio_list);
...@@ -2252,6 +2274,10 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, ...@@ -2252,6 +2274,10 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
update_ena_gpio_to_rdev: update_ena_gpio_to_rdev:
pin->request_count++; pin->request_count++;
rdev->ena_pin = pin; rdev->ena_pin = pin;
mutex_unlock(&regulator_list_mutex);
kfree(new_pin);
return 0; return 0;
} }
...@@ -2264,19 +2290,19 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) ...@@ -2264,19 +2290,19 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
/* Free the GPIO only in case of no use */ /* Free the GPIO only in case of no use */
list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) { list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
if (pin->gpiod == rdev->ena_pin->gpiod) { if (pin != rdev->ena_pin)
if (pin->request_count <= 1) { continue;
pin->request_count = 0;
if (--pin->request_count)
break;
gpiod_put(pin->gpiod); gpiod_put(pin->gpiod);
list_del(&pin->list); list_del(&pin->list);
kfree(pin); kfree(pin);
rdev->ena_pin = NULL; break;
return;
} else {
pin->request_count--;
}
}
} }
rdev->ena_pin = NULL;
} }
/** /**
...@@ -4949,13 +4975,9 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev) ...@@ -4949,13 +4975,9 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev)
return; return;
} }
regulator_lock(c_rdev);
c_desc->coupled_rdevs[i] = c_rdev; c_desc->coupled_rdevs[i] = c_rdev;
c_desc->n_resolved++; c_desc->n_resolved++;
regulator_unlock(c_rdev);
regulator_resolve_coupling(c_rdev); regulator_resolve_coupling(c_rdev);
} }
} }
...@@ -5040,7 +5062,10 @@ static int regulator_init_coupling(struct regulator_dev *rdev) ...@@ -5040,7 +5062,10 @@ static int regulator_init_coupling(struct regulator_dev *rdev)
if (!of_check_coupling_data(rdev)) if (!of_check_coupling_data(rdev))
return -EPERM; return -EPERM;
mutex_lock(&regulator_list_mutex);
rdev->coupling_desc.coupler = regulator_find_coupler(rdev); rdev->coupling_desc.coupler = regulator_find_coupler(rdev);
mutex_unlock(&regulator_list_mutex);
if (IS_ERR(rdev->coupling_desc.coupler)) { if (IS_ERR(rdev->coupling_desc.coupler)) {
err = PTR_ERR(rdev->coupling_desc.coupler); err = PTR_ERR(rdev->coupling_desc.coupler);
rdev_err(rdev, "failed to get coupler: %d\n", err); rdev_err(rdev, "failed to get coupler: %d\n", err);
...@@ -5141,6 +5166,7 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5141,6 +5166,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
ret = -ENOMEM; ret = -ENOMEM;
goto rinse; goto rinse;
} }
device_initialize(&rdev->dev);
/* /*
* Duplicate the config so the driver could override it after * Duplicate the config so the driver could override it after
...@@ -5148,9 +5174,8 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5148,9 +5174,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
*/ */
config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL); config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL);
if (config == NULL) { if (config == NULL) {
kfree(rdev);
ret = -ENOMEM; ret = -ENOMEM;
goto rinse; goto clean;
} }
init_data = regulator_of_get_init_data(dev, regulator_desc, config, init_data = regulator_of_get_init_data(dev, regulator_desc, config,
...@@ -5162,10 +5187,8 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5162,10 +5187,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
* from a gpio extender or something else. * from a gpio extender or something else.
*/ */
if (PTR_ERR(init_data) == -EPROBE_DEFER) { if (PTR_ERR(init_data) == -EPROBE_DEFER) {
kfree(config);
kfree(rdev);
ret = -EPROBE_DEFER; ret = -EPROBE_DEFER;
goto rinse; goto clean;
} }
/* /*
...@@ -5206,9 +5229,7 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5206,9 +5229,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
} }
if (config->ena_gpiod) { if (config->ena_gpiod) {
mutex_lock(&regulator_list_mutex);
ret = regulator_ena_gpio_request(rdev, config); ret = regulator_ena_gpio_request(rdev, config);
mutex_unlock(&regulator_list_mutex);
if (ret != 0) { if (ret != 0) {
rdev_err(rdev, "Failed to request enable GPIO: %d\n", rdev_err(rdev, "Failed to request enable GPIO: %d\n",
ret); ret);
...@@ -5220,7 +5241,6 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5220,7 +5241,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
} }
/* register with sysfs */ /* register with sysfs */
device_initialize(&rdev->dev);
rdev->dev.class = &regulator_class; rdev->dev.class = &regulator_class;
rdev->dev.parent = dev; rdev->dev.parent = dev;
dev_set_name(&rdev->dev, "regulator.%lu", dev_set_name(&rdev->dev, "regulator.%lu",
...@@ -5248,27 +5268,22 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5248,27 +5268,22 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret < 0) if (ret < 0)
goto wash; goto wash;
mutex_lock(&regulator_list_mutex);
ret = regulator_init_coupling(rdev); ret = regulator_init_coupling(rdev);
mutex_unlock(&regulator_list_mutex);
if (ret < 0) if (ret < 0)
goto wash; goto wash;
/* add consumers devices */ /* add consumers devices */
if (init_data) { if (init_data) {
mutex_lock(&regulator_list_mutex);
for (i = 0; i < init_data->num_consumer_supplies; i++) { for (i = 0; i < init_data->num_consumer_supplies; i++) {
ret = set_consumer_device_supply(rdev, ret = set_consumer_device_supply(rdev,
init_data->consumer_supplies[i].dev_name, init_data->consumer_supplies[i].dev_name,
init_data->consumer_supplies[i].supply); init_data->consumer_supplies[i].supply);
if (ret < 0) { if (ret < 0) {
mutex_unlock(&regulator_list_mutex);
dev_err(dev, "Failed to set supply %s\n", dev_err(dev, "Failed to set supply %s\n",
init_data->consumer_supplies[i].supply); init_data->consumer_supplies[i].supply);
goto unset_supplies; goto unset_supplies;
} }
} }
mutex_unlock(&regulator_list_mutex);
} }
if (!rdev->desc->ops->get_voltage && if (!rdev->desc->ops->get_voltage &&
...@@ -5303,13 +5318,11 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -5303,13 +5318,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
mutex_lock(&regulator_list_mutex); mutex_lock(&regulator_list_mutex);
regulator_ena_gpio_free(rdev); regulator_ena_gpio_free(rdev);
mutex_unlock(&regulator_list_mutex); mutex_unlock(&regulator_list_mutex);
put_device(&rdev->dev);
rdev = NULL;
clean: clean:
if (dangling_of_gpiod) if (dangling_of_gpiod)
gpiod_put(config->ena_gpiod); gpiod_put(config->ena_gpiod);
kfree(rdev);
kfree(config); kfree(config);
put_device(&rdev->dev);
rinse: rinse:
if (dangling_cfg_gpiod) if (dangling_cfg_gpiod)
gpiod_put(cfg->ena_gpiod); gpiod_put(cfg->ena_gpiod);
......
...@@ -170,6 +170,9 @@ static int cros_ec_regulator_init_info(struct device *dev, ...@@ -170,6 +170,9 @@ static int cros_ec_regulator_init_info(struct device *dev,
data->voltages_mV = data->voltages_mV =
devm_kmemdup(dev, resp.voltages_mv, devm_kmemdup(dev, resp.voltages_mv,
sizeof(u16) * data->num_voltages, GFP_KERNEL); sizeof(u16) * data->num_voltages, GFP_KERNEL);
if (!data->voltages_mV)
return -ENOMEM;
data->desc.n_voltages = data->num_voltages; data->desc.n_voltages = data->num_voltages;
/* Make sure the returned name is always a valid string */ /* Make sure the returned name is always a valid string */
......
...@@ -182,7 +182,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) ...@@ -182,7 +182,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata->enable_clock = devm_clk_get(dev, NULL); drvdata->enable_clock = devm_clk_get(dev, NULL);
if (IS_ERR(drvdata->enable_clock)) { if (IS_ERR(drvdata->enable_clock)) {
dev_err(dev, "Cant get enable-clock from devicetree\n"); dev_err(dev, "Can't get enable-clock from devicetree\n");
return -ENOENT; return -ENOENT;
} }
} else { } else {
......
...@@ -279,7 +279,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev, ...@@ -279,7 +279,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
return ret; return ret;
} }
drvdata->state = -EINVAL; drvdata->state = -ENOTRECOVERABLE;
drvdata->duty_cycle_table = duty_cycle_table; drvdata->duty_cycle_table = duty_cycle_table;
drvdata->desc.ops = &pwm_regulator_voltage_table_ops; drvdata->desc.ops = &pwm_regulator_voltage_table_ops;
drvdata->desc.n_voltages = length / sizeof(*duty_cycle_table); drvdata->desc.n_voltages = length / sizeof(*duty_cycle_table);
......
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