regulator: Fixes for v5.9
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. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl9baDITHGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0NAOCACGwc1Rxsr9cMDY5vQS7AHzfPVRdoQJ Z9KIOQT9ER0hFHRNh1/t1n/p4DcK+3ke0MH/R/VndijvePJgHyL01Bsjq92iDiIy b80nDJwRwLWWdvKAPG5JklVK8pL/6LxaC9eL8zK93Hm4fGkNJzBi7jF2++jep/tB 2jRM4Vrq8B0dkh/jPQMscl4Z66purIiyKLJjy1QFjXXq0/jkjZizURy+aofS3uJD 0vebim9OI7z0H4g6cflJrHUAuDraNmGCfGAyUMH7AESJlUGNRk7BzNYT51tLVYqG ithNZDh/AbWhGzntuUUKNlM4D8p26FNJmU51crh33kBH3va737dvc/BT =3fwP -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
8b6ce25177
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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(®ulator_list_mutex);
|
||||||
list_for_each_entry(node, ®ulator_map_list, list) {
|
list_for_each_entry(node, ®ulator_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,
|
|||||||
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, ®ulator_map_list);
|
||||||
if (node == NULL)
|
mutex_unlock(®ulator_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, ®ulator_map_list);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
mutex_unlock(®ulator_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,
|
|||||||
const char *supply_name)
|
const char *supply_name)
|
||||||
{
|
{
|
||||||
struct regulator *regulator;
|
struct regulator *regulator;
|
||||||
char buf[REG_STR_SIZE];
|
int err;
|
||||||
int err, size;
|
|
||||||
|
|
||||||
regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
|
if (dev) {
|
||||||
if (regulator == NULL)
|
char buf[REG_STR_SIZE];
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
|
||||||
|
dev->kobj.name, supply_name);
|
||||||
|
if (size >= REG_STR_SIZE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
regulator_lock(rdev);
|
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);
|
||||||
|
if (regulator == NULL) {
|
||||||
|
kfree(supply_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
regulator->rdev = rdev;
|
regulator->rdev = rdev;
|
||||||
|
regulator->supply_name = supply_name;
|
||||||
|
|
||||||
|
regulator_lock(rdev);
|
||||||
list_add(®ulator->list, &rdev->consumer_list);
|
list_add(®ulator->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,
|
|||||||
_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(®ulator->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);
|
|||||||
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(®ulator_list_mutex);
|
||||||
|
|
||||||
list_for_each_entry(pin, ®ulator_ena_gpio_list, list) {
|
list_for_each_entry(pin, ®ulator_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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL);
|
if (new_pin == NULL) {
|
||||||
if (pin == NULL)
|
mutex_unlock(®ulator_list_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin = new_pin;
|
||||||
|
new_pin = NULL;
|
||||||
|
|
||||||
pin->gpiod = gpiod;
|
pin->gpiod = gpiod;
|
||||||
list_add(&pin->list, ®ulator_ena_gpio_list);
|
list_add(&pin->list, ®ulator_ena_gpio_list);
|
||||||
@ -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(®ulator_list_mutex);
|
||||||
|
kfree(new_pin);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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, ®ulator_ena_gpio_list, list) {
|
list_for_each_entry_safe(pin, n, ®ulator_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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rdev->ena_pin = NULL;
|
rdev->ena_pin = NULL;
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
pin->request_count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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)
|
|||||||
if (!of_check_coupling_data(rdev))
|
if (!of_check_coupling_data(rdev))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
mutex_lock(®ulator_list_mutex);
|
||||||
rdev->coupling_desc.coupler = regulator_find_coupler(rdev);
|
rdev->coupling_desc.coupler = regulator_find_coupler(rdev);
|
||||||
|
mutex_unlock(®ulator_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,
|
|||||||
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,
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
* 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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config->ena_gpiod) {
|
if (config->ena_gpiod) {
|
||||||
mutex_lock(®ulator_list_mutex);
|
|
||||||
ret = regulator_ena_gpio_request(rdev, config);
|
ret = regulator_ena_gpio_request(rdev, config);
|
||||||
mutex_unlock(®ulator_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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* register with sysfs */
|
/* register with sysfs */
|
||||||
device_initialize(&rdev->dev);
|
|
||||||
rdev->dev.class = ®ulator_class;
|
rdev->dev.class = ®ulator_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,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto wash;
|
goto wash;
|
||||||
|
|
||||||
mutex_lock(®ulator_list_mutex);
|
|
||||||
ret = regulator_init_coupling(rdev);
|
ret = regulator_init_coupling(rdev);
|
||||||
mutex_unlock(®ulator_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(®ulator_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(®ulator_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(®ulator_list_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rdev->desc->ops->get_voltage &&
|
if (!rdev->desc->ops->get_voltage &&
|
||||||
@ -5303,13 +5318,11 @@ wash:
|
|||||||
mutex_lock(®ulator_list_mutex);
|
mutex_lock(®ulator_list_mutex);
|
||||||
regulator_ena_gpio_free(rdev);
|
regulator_ena_gpio_free(rdev);
|
||||||
mutex_unlock(®ulator_list_mutex);
|
mutex_unlock(®ulator_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,
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user