Skip to content

Commit 25617a5

Browse files
committed
Merge tag 'regmap-v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown: "There's one new feature here, a regmap_multi_reg_read() matching the existing write function which has some IIO users coming. This allows atomic reads from multiple registers without the need to wrap a higher level lock in the client driver just for regmap (which already has locks anyway). We also have one fix for the KUnit tests, and a bunch of cleanups" * tag 'regmap-v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: kunit: Add test cases for regmap_multi_reg_(read,write}() regmap: Implement regmap_multi_reg_read() regmap-irq: handle const struct regmap_irq_sub_irq_map const_structs.checkpatch: add regmap structs regmap: add missing MODULE_DESCRIPTION() macros regmap-i2c: add missing MODULE_DESCRIPTION() macro regmap: kunit: Use array_size() and sizeof(*ptr) consistently regmap: maple: Switch to use kmemdup_array() regmap: cache: Switch to use kmemdup_array() regmap: cache: Use correct type of the rb_for_each() parameter regmap: Switch to use kmemdup_array() regmap: kunit: add missing MODULE_DESCRIPTION() regmap: kunit: Fix memory leaks in gen_regmap() and gen_raw_regmap()
2 parents b3c0ecc + c2bb819 commit 25617a5

16 files changed

Lines changed: 226 additions & 81 deletions

drivers/base/regmap/regcache-maple.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,
132132
lower_index = mas.index;
133133
lower_last = min -1;
134134

135-
lower = kmemdup(entry, ((min - mas.index) *
136-
sizeof(unsigned long)),
137-
map->alloc_flags);
135+
lower = kmemdup_array(entry,
136+
min - mas.index, sizeof(*lower),
137+
map->alloc_flags);
138138
if (!lower) {
139139
ret = -ENOMEM;
140140
goto out_unlocked;
@@ -145,10 +145,9 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,
145145
upper_index = max + 1;
146146
upper_last = mas.last;
147147

148-
upper = kmemdup(&entry[max - mas.index + 1],
149-
((mas.last - max) *
150-
sizeof(unsigned long)),
151-
map->alloc_flags);
148+
upper = kmemdup_array(&entry[max - mas.index + 1],
149+
mas.last - max, sizeof(*upper),
150+
map->alloc_flags);
152151
if (!upper) {
153152
ret = -ENOMEM;
154153
goto out_unlocked;

drivers/base/regmap/regcache.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
170170
* a copy of it.
171171
*/
172172
if (config->reg_defaults) {
173-
tmp_buf = kmemdup(config->reg_defaults, map->num_reg_defaults *
174-
sizeof(struct reg_default), GFP_KERNEL);
173+
tmp_buf = kmemdup_array(config->reg_defaults, map->num_reg_defaults,
174+
sizeof(*map->reg_defaults), GFP_KERNEL);
175175
if (!tmp_buf)
176176
return -ENOMEM;
177177
map->reg_defaults = tmp_buf;
@@ -407,7 +407,7 @@ int regcache_sync(struct regmap *map)
407407
* have gone out of sync, force writes of all the paging
408408
* registers.
409409
*/
410-
rb_for_each(node, 0, &map->range_tree, rbtree_all) {
410+
rb_for_each(node, NULL, &map->range_tree, rbtree_all) {
411411
struct regmap_range_node *this =
412412
rb_entry(node, struct regmap_range_node, node);
413413

drivers/base/regmap/regmap-ac97.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,5 @@ struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97,
8686
}
8787
EXPORT_SYMBOL_GPL(__devm_regmap_init_ac97);
8888

89+
MODULE_DESCRIPTION("Register map access API - AC'97 support");
8990
MODULE_LICENSE("GPL v2");

drivers/base/regmap/regmap-i2c.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,5 @@ struct regmap *__devm_regmap_init_i2c(struct i2c_client *i2c,
397397
}
398398
EXPORT_SYMBOL_GPL(__devm_regmap_init_i2c);
399399

400+
MODULE_DESCRIPTION("Register map access API - I2C support");
400401
MODULE_LICENSE("GPL");

drivers/base/regmap/regmap-irq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,8 @@ static inline int read_sub_irq_data(struct regmap_irq_chip_data *data,
305305
unsigned int b)
306306
{
307307
const struct regmap_irq_chip *chip = data->chip;
308+
const struct regmap_irq_sub_irq_map *subreg;
308309
struct regmap *map = data->map;
309-
struct regmap_irq_sub_irq_map *subreg;
310310
unsigned int reg;
311311
int i, ret = 0;
312312

drivers/base/regmap/regmap-kunit.c

Lines changed: 125 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ static struct regmap *gen_regmap(struct kunit *test,
145145
const struct regmap_test_param *param = test->param_value;
146146
struct regmap_test_priv *priv = test->priv;
147147
unsigned int *buf;
148-
struct regmap *ret;
148+
struct regmap *ret = ERR_PTR(-ENOMEM);
149149
size_t size;
150-
int i;
150+
int i, error;
151151
struct reg_default *defaults;
152152

153153
config->cache_type = param->cache;
@@ -163,7 +163,7 @@ static struct regmap *gen_regmap(struct kunit *test,
163163
config->max_register += (BLOCK_TEST_SIZE * config->reg_stride);
164164
}
165165

166-
size = (config->max_register + 1) * sizeof(unsigned int);
166+
size = array_size(config->max_register + 1, sizeof(*buf));
167167
buf = kmalloc(size, GFP_KERNEL);
168168
if (!buf)
169169
return ERR_PTR(-ENOMEM);
@@ -172,15 +172,17 @@ static struct regmap *gen_regmap(struct kunit *test,
172172

173173
*data = kzalloc(sizeof(**data), GFP_KERNEL);
174174
if (!(*data))
175-
return ERR_PTR(-ENOMEM);
175+
goto out_free;
176176
(*data)->vals = buf;
177177

178178
if (config->num_reg_defaults) {
179-
defaults = kcalloc(config->num_reg_defaults,
180-
sizeof(struct reg_default),
181-
GFP_KERNEL);
179+
defaults = kunit_kcalloc(test,
180+
config->num_reg_defaults,
181+
sizeof(struct reg_default),
182+
GFP_KERNEL);
182183
if (!defaults)
183-
return ERR_PTR(-ENOMEM);
184+
goto out_free;
185+
184186
config->reg_defaults = defaults;
185187

186188
for (i = 0; i < config->num_reg_defaults; i++) {
@@ -190,12 +192,19 @@ static struct regmap *gen_regmap(struct kunit *test,
190192
}
191193

192194
ret = regmap_init_ram(priv->dev, config, *data);
193-
if (IS_ERR(ret)) {
194-
kfree(buf);
195-
kfree(*data);
196-
} else {
197-
kunit_add_action(test, regmap_exit_action, ret);
198-
}
195+
if (IS_ERR(ret))
196+
goto out_free;
197+
198+
/* This calls regmap_exit() on failure, which frees buf and *data */
199+
error = kunit_add_action_or_reset(test, regmap_exit_action, ret);
200+
if (error)
201+
ret = ERR_PTR(error);
202+
203+
return ret;
204+
205+
out_free:
206+
kfree(buf);
207+
kfree(*data);
199208

200209
return ret;
201210
}
@@ -295,6 +304,77 @@ static void bulk_read(struct kunit *test)
295304
KUNIT_EXPECT_EQ(test, config.cache_type == REGCACHE_NONE, data->read[i]);
296305
}
297306

307+
static void multi_write(struct kunit *test)
308+
{
309+
struct regmap *map;
310+
struct regmap_config config;
311+
struct regmap_ram_data *data;
312+
struct reg_sequence sequence[BLOCK_TEST_SIZE];
313+
unsigned int val[BLOCK_TEST_SIZE], rval[BLOCK_TEST_SIZE];
314+
int i;
315+
316+
config = test_regmap_config;
317+
318+
map = gen_regmap(test, &config, &data);
319+
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
320+
if (IS_ERR(map))
321+
return;
322+
323+
get_random_bytes(&val, sizeof(val));
324+
325+
/*
326+
* Data written via the multi API can be read back with single
327+
* reads.
328+
*/
329+
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
330+
sequence[i].reg = i;
331+
sequence[i].def = val[i];
332+
sequence[i].delay_us = 0;
333+
}
334+
KUNIT_EXPECT_EQ(test, 0,
335+
regmap_multi_reg_write(map, sequence, BLOCK_TEST_SIZE));
336+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
337+
KUNIT_EXPECT_EQ(test, 0, regmap_read(map, i, &rval[i]));
338+
339+
KUNIT_EXPECT_MEMEQ(test, val, rval, sizeof(val));
340+
341+
/* If using a cache the cache satisfied the read */
342+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
343+
KUNIT_EXPECT_EQ(test, config.cache_type == REGCACHE_NONE, data->read[i]);
344+
}
345+
346+
static void multi_read(struct kunit *test)
347+
{
348+
struct regmap *map;
349+
struct regmap_config config;
350+
struct regmap_ram_data *data;
351+
unsigned int regs[BLOCK_TEST_SIZE];
352+
unsigned int val[BLOCK_TEST_SIZE], rval[BLOCK_TEST_SIZE];
353+
int i;
354+
355+
config = test_regmap_config;
356+
357+
map = gen_regmap(test, &config, &data);
358+
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
359+
if (IS_ERR(map))
360+
return;
361+
362+
get_random_bytes(&val, sizeof(val));
363+
364+
/* Data written as single writes can be read via the multi API */
365+
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
366+
regs[i] = i;
367+
KUNIT_EXPECT_EQ(test, 0, regmap_write(map, i, val[i]));
368+
}
369+
KUNIT_EXPECT_EQ(test, 0,
370+
regmap_multi_reg_read(map, regs, rval, BLOCK_TEST_SIZE));
371+
KUNIT_EXPECT_MEMEQ(test, val, rval, sizeof(val));
372+
373+
/* If using a cache the cache satisfied the read */
374+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
375+
KUNIT_EXPECT_EQ(test, config.cache_type == REGCACHE_NONE, data->read[i]);
376+
}
377+
298378
static void read_bypassed(struct kunit *test)
299379
{
300380
const struct regmap_test_param *param = test->param_value;
@@ -759,10 +839,9 @@ static void stress_insert(struct kunit *test)
759839
if (IS_ERR(map))
760840
return;
761841

762-
vals = kunit_kcalloc(test, sizeof(unsigned long), config.max_register,
763-
GFP_KERNEL);
842+
buf_sz = array_size(sizeof(*vals), config.max_register);
843+
vals = kunit_kmalloc(test, buf_sz, GFP_KERNEL);
764844
KUNIT_ASSERT_FALSE(test, vals == NULL);
765-
buf_sz = sizeof(unsigned long) * config.max_register;
766845

767846
get_random_bytes(vals, buf_sz);
768847

@@ -1497,16 +1576,17 @@ static struct regmap *gen_raw_regmap(struct kunit *test,
14971576
struct regmap_test_priv *priv = test->priv;
14981577
const struct regmap_test_param *param = test->param_value;
14991578
u16 *buf;
1500-
struct regmap *ret;
1501-
size_t size = (config->max_register + 1) * config->reg_bits / 8;
1502-
int i;
1579+
struct regmap *ret = ERR_PTR(-ENOMEM);
1580+
int i, error;
15031581
struct reg_default *defaults;
1582+
size_t size;
15041583

15051584
config->cache_type = param->cache;
15061585
config->val_format_endian = param->val_endian;
15071586
config->disable_locking = config->cache_type == REGCACHE_RBTREE ||
15081587
config->cache_type == REGCACHE_MAPLE;
15091588

1589+
size = array_size(config->max_register + 1, BITS_TO_BYTES(config->reg_bits));
15101590
buf = kmalloc(size, GFP_KERNEL);
15111591
if (!buf)
15121592
return ERR_PTR(-ENOMEM);
@@ -1515,15 +1595,16 @@ static struct regmap *gen_raw_regmap(struct kunit *test,
15151595

15161596
*data = kzalloc(sizeof(**data), GFP_KERNEL);
15171597
if (!(*data))
1518-
return ERR_PTR(-ENOMEM);
1598+
goto out_free;
15191599
(*data)->vals = (void *)buf;
15201600

15211601
config->num_reg_defaults = config->max_register + 1;
1522-
defaults = kcalloc(config->num_reg_defaults,
1523-
sizeof(struct reg_default),
1524-
GFP_KERNEL);
1602+
defaults = kunit_kcalloc(test,
1603+
config->num_reg_defaults,
1604+
sizeof(struct reg_default),
1605+
GFP_KERNEL);
15251606
if (!defaults)
1526-
return ERR_PTR(-ENOMEM);
1607+
goto out_free;
15271608
config->reg_defaults = defaults;
15281609

15291610
for (i = 0; i < config->num_reg_defaults; i++) {
@@ -1536,7 +1617,8 @@ static struct regmap *gen_raw_regmap(struct kunit *test,
15361617
defaults[i].def = be16_to_cpu(buf[i]);
15371618
break;
15381619
default:
1539-
return ERR_PTR(-EINVAL);
1620+
ret = ERR_PTR(-EINVAL);
1621+
goto out_free;
15401622
}
15411623
}
15421624

@@ -1548,12 +1630,19 @@ static struct regmap *gen_raw_regmap(struct kunit *test,
15481630
config->num_reg_defaults = 0;
15491631

15501632
ret = regmap_init_raw_ram(priv->dev, config, *data);
1551-
if (IS_ERR(ret)) {
1552-
kfree(buf);
1553-
kfree(*data);
1554-
} else {
1555-
kunit_add_action(test, regmap_exit_action, ret);
1556-
}
1633+
if (IS_ERR(ret))
1634+
goto out_free;
1635+
1636+
/* This calls regmap_exit() on failure, which frees buf and *data */
1637+
error = kunit_add_action_or_reset(test, regmap_exit_action, ret);
1638+
if (error)
1639+
ret = ERR_PTR(error);
1640+
1641+
return ret;
1642+
1643+
out_free:
1644+
kfree(buf);
1645+
kfree(*data);
15571646

15581647
return ret;
15591648
}
@@ -1597,7 +1686,7 @@ static void raw_read_defaults(struct kunit *test)
15971686
if (IS_ERR(map))
15981687
return;
15991688

1600-
val_len = sizeof(*rval) * (config.max_register + 1);
1689+
val_len = array_size(sizeof(*rval), config.max_register + 1);
16011690
rval = kunit_kmalloc(test, val_len, GFP_KERNEL);
16021691
KUNIT_ASSERT_TRUE(test, rval != NULL);
16031692
if (!rval)
@@ -1887,6 +1976,8 @@ static struct kunit_case regmap_test_cases[] = {
18871976
KUNIT_CASE_PARAM(read_bypassed_volatile, real_cache_types_gen_params),
18881977
KUNIT_CASE_PARAM(bulk_write, regcache_types_gen_params),
18891978
KUNIT_CASE_PARAM(bulk_read, regcache_types_gen_params),
1979+
KUNIT_CASE_PARAM(multi_write, regcache_types_gen_params),
1980+
KUNIT_CASE_PARAM(multi_read, regcache_types_gen_params),
18901981
KUNIT_CASE_PARAM(write_readonly, regcache_types_gen_params),
18911982
KUNIT_CASE_PARAM(read_writeonly, regcache_types_gen_params),
18921983
KUNIT_CASE_PARAM(reg_defaults, regcache_types_gen_params),
@@ -1958,4 +2049,5 @@ static struct kunit_suite regmap_test_suite = {
19582049
};
19592050
kunit_test_suite(regmap_test_suite);
19602051

2052+
MODULE_DESCRIPTION("Regmap KUnit tests");
19612053
MODULE_LICENSE("GPL v2");

drivers/base/regmap/regmap-ram.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,5 @@ struct regmap *__regmap_init_ram(struct device *dev,
8383
}
8484
EXPORT_SYMBOL_GPL(__regmap_init_ram);
8585

86+
MODULE_DESCRIPTION("Register map access API - Memory region");
8687
MODULE_LICENSE("GPL v2");

drivers/base/regmap/regmap-raw-ram.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,4 +142,5 @@ struct regmap *__regmap_init_raw_ram(struct device *dev,
142142
}
143143
EXPORT_SYMBOL_GPL(__regmap_init_raw_ram);
144144

145+
MODULE_DESCRIPTION("Register map access API - Memory region with raw access");
145146
MODULE_LICENSE("GPL v2");

drivers/base/regmap/regmap-sccb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,5 @@ struct regmap *__devm_regmap_init_sccb(struct i2c_client *i2c,
125125
}
126126
EXPORT_SYMBOL_GPL(__devm_regmap_init_sccb);
127127

128+
MODULE_DESCRIPTION("Register map access API - SCCB support");
128129
MODULE_LICENSE("GPL v2");

drivers/base/regmap/regmap-slimbus.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,5 @@ struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus,
6868
}
6969
EXPORT_SYMBOL_GPL(__devm_regmap_init_slimbus);
7070

71+
MODULE_DESCRIPTION("Register map access API - SLIMbus support");
7172
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)