Skip to content

Commit 5906f15

Browse files
committed
Merge tag 'regulator-fix-v7.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator fixes from Mark Brown: "There's a couple of core fixes here: there were a couple of issues with of_regulator_bulk_get_all() not behaving consistently with the other bulk regulator APIs which caused memory leaks and error handling issues in users. We also have a couple of fairly standard driver specific fixes" * tag 'regulator-fix-v7.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: regulator: ltc3676: don't read the write-only HRST and CLIRQ registers regulator: of: state who owns the array from of_regulator_bulk_get_all() regulator: of: fill in supply names in of_regulator_bulk_get_all() regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4
2 parents d5b6dc3 + 28c2388 commit 5906f15

3 files changed

Lines changed: 37 additions & 13 deletions

File tree

‎drivers/regulator/ltc3676.c‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ static const struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] =
232232
LTC3676_FIXED_REG(LDO4, ldo4, LDOB, 2),
233233
};
234234

235-
static bool ltc3676_readable_writeable_reg(struct device *dev, unsigned int reg)
235+
static bool ltc3676_writeable_reg(struct device *dev, unsigned int reg)
236236
{
237237
switch (reg) {
238238
case LTC3676_BUCK1 ... LTC3676_IRQSTAT:
@@ -243,6 +243,15 @@ static bool ltc3676_readable_writeable_reg(struct device *dev, unsigned int reg)
243243
return false;
244244
}
245245

246+
static bool ltc3676_readable_reg(struct device *dev, unsigned int reg)
247+
{
248+
switch (reg) {
249+
case LTC3676_BUCK1 ... LTC3676_IRQSTAT:
250+
return true;
251+
}
252+
return false;
253+
}
254+
246255
static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg)
247256
{
248257
switch (reg) {
@@ -255,8 +264,8 @@ static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg)
255264
static const struct regmap_config ltc3676_regmap_config = {
256265
.reg_bits = 8,
257266
.val_bits = 8,
258-
.writeable_reg = ltc3676_readable_writeable_reg,
259-
.readable_reg = ltc3676_readable_writeable_reg,
267+
.writeable_reg = ltc3676_writeable_reg,
268+
.readable_reg = ltc3676_readable_reg,
260269
.volatile_reg = ltc3676_volatile_reg,
261270
.max_register = LTC3676_CLIRQ,
262271
.use_single_read = true,

‎drivers/regulator/of_regulator.c‎

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -929,21 +929,26 @@ static int is_supply_name(const char *name)
929929
* before returning to the caller, and @consumers will not be
930930
* changed.
931931
*
932+
* On success the array is allocated here and handed to the caller, which
933+
* owns it from then on: release the regulators with regulator_bulk_free()
934+
* and free the array itself with kfree(). The supply names live in the
935+
* same allocation, so they are gone once the array is freed.
936+
*
932937
* Return: Number of regulators on success, or a negative error number
933938
* on failure.
934939
*/
935940
int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
936941
struct regulator_bulk_data **consumers)
937942
{
938-
int num_consumers = 0;
943+
int num_consumers = 0, names_len = 0;
939944
struct regulator *tmp;
940945
struct regulator_bulk_data *_consumers = NULL;
941946
struct property *prop;
947+
char *names;
942948
int i, n = 0, ret;
943-
char name[64];
944949

945950
/*
946-
* first pass: get numbers of xxx-supply
951+
* first pass: get numbers of xxx-supply and the room their names take
947952
* second pass: fill consumers
948953
*/
949954
restart:
@@ -953,16 +958,19 @@ int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
953958
continue;
954959
if (!_consumers) {
955960
num_consumers++;
961+
names_len += i + 1;
956962
continue;
957963
} else {
958-
memcpy(name, prop->name, i);
959-
name[i] = '\0';
960-
tmp = regulator_get(dev, name);
964+
memcpy(names, prop->name, i);
965+
names[i] = '\0';
966+
tmp = regulator_get(dev, names);
961967
if (IS_ERR(tmp)) {
962968
ret = PTR_ERR(tmp);
963969
goto error;
964970
}
971+
_consumers[n].supply = names;
965972
_consumers[n].consumer = tmp;
973+
names += i + 1;
966974
n++;
967975
continue;
968976
}
@@ -973,9 +981,16 @@ int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
973981
}
974982
if (num_consumers == 0)
975983
return 0;
976-
_consumers = kmalloc_objs(struct regulator_bulk_data, num_consumers);
984+
/*
985+
* The supply names are kept in the same allocation as the array, so
986+
* that they share its lifetime and the caller has nothing extra to
987+
* free.
988+
*/
989+
_consumers = kzalloc(size_add(size_mul(num_consumers, sizeof(*_consumers)),
990+
names_len), GFP_KERNEL);
977991
if (!_consumers)
978992
return -ENOMEM;
993+
names = (char *)(_consumers + num_consumers);
979994
goto restart;
980995

981996
error:

‎drivers/regulator/tps6594-regulator.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,21 +241,21 @@ static const struct regulator_desc tps65224_buck_regs[] = {
241241
TPS65224_MASK_BUCKS_VSET,
242242
TPS6594_REG_BUCKX_CTRL(1),
243243
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
244-
4, 0, 0, NULL, 0, 0),
244+
ARRAY_SIZE(tps65224_bucks_2_3_4_ranges), 0, 0, NULL, 0, 0),
245245
TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
246246
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
247247
TPS6594_REG_BUCKX_VOUT_1(2),
248248
TPS65224_MASK_BUCKS_VSET,
249249
TPS6594_REG_BUCKX_CTRL(2),
250250
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
251-
4, 0, 0, NULL, 0, 0),
251+
ARRAY_SIZE(tps65224_bucks_2_3_4_ranges), 0, 0, NULL, 0, 0),
252252
TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
253253
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
254254
TPS6594_REG_BUCKX_VOUT_1(3),
255255
TPS65224_MASK_BUCKS_VSET,
256256
TPS6594_REG_BUCKX_CTRL(3),
257257
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
258-
4, 0, 0, NULL, 0, 0),
258+
ARRAY_SIZE(tps65224_bucks_2_3_4_ranges), 0, 0, NULL, 0, 0),
259259
};
260260

261261
static const struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {

0 commit comments

Comments
 (0)