Skip to content

Commit d40e1d9

Browse files
committed
Merge remote-tracking branch 'regmap/for-6.19' into regmap-next
2 parents 6146a0f + 6985def commit d40e1d9

File tree

9 files changed

+186
-65
lines changed

9 files changed

+186
-65
lines changed

drivers/base/regmap/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ struct regcache_ops {
186186
enum regcache_type type;
187187
int (*init)(struct regmap *map);
188188
int (*exit)(struct regmap *map);
189+
int (*populate)(struct regmap *map);
189190
#ifdef CONFIG_DEBUG_FS
190191
void (*debugfs_init)(struct regmap *map);
191192
#endif
@@ -288,6 +289,7 @@ enum regmap_endian regmap_get_val_endian(struct device *dev,
288289
const struct regmap_bus *bus,
289290
const struct regmap_config *config);
290291

292+
extern struct regcache_ops regcache_flat_sparse_ops;
291293
extern struct regcache_ops regcache_rbtree_ops;
292294
extern struct regcache_ops regcache_maple_ops;
293295
extern struct regcache_ops regcache_flat_ops;

drivers/base/regmap/regcache-flat.c

Lines changed: 91 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
//
77
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
88

9+
#include <linux/bitmap.h>
10+
#include <linux/bitops.h>
911
#include <linux/device.h>
12+
#include <linux/limits.h>
13+
#include <linux/overflow.h>
1014
#include <linux/seq_file.h>
1115
#include <linux/slab.h>
1216

@@ -18,57 +22,116 @@ static inline unsigned int regcache_flat_get_index(const struct regmap *map,
1822
return regcache_get_index_by_order(map, reg);
1923
}
2024

25+
struct regcache_flat_data {
26+
unsigned long *valid;
27+
unsigned int data[];
28+
};
29+
2130
static int regcache_flat_init(struct regmap *map)
2231
{
23-
int i;
24-
unsigned int *cache;
32+
unsigned int cache_size;
33+
struct regcache_flat_data *cache;
2534

2635
if (!map || map->reg_stride_order < 0 || !map->max_register_is_set)
2736
return -EINVAL;
2837

29-
map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)
30-
+ 1, sizeof(unsigned int), map->alloc_flags);
31-
if (!map->cache)
38+
cache_size = regcache_flat_get_index(map, map->max_register) + 1;
39+
cache = kzalloc(struct_size(cache, data, cache_size), map->alloc_flags);
40+
if (!cache)
3241
return -ENOMEM;
3342

34-
cache = map->cache;
43+
cache->valid = bitmap_zalloc(cache_size, map->alloc_flags);
44+
if (!cache->valid)
45+
goto err_free;
46+
47+
map->cache = cache;
48+
49+
return 0;
50+
51+
err_free:
52+
kfree(cache);
53+
return -ENOMEM;
54+
}
55+
56+
static int regcache_flat_exit(struct regmap *map)
57+
{
58+
struct regcache_flat_data *cache = map->cache;
59+
60+
if (cache)
61+
bitmap_free(cache->valid);
62+
63+
kfree(cache);
64+
map->cache = NULL;
65+
66+
return 0;
67+
}
68+
69+
static int regcache_flat_populate(struct regmap *map)
70+
{
71+
struct regcache_flat_data *cache = map->cache;
72+
unsigned int i;
3573

3674
for (i = 0; i < map->num_reg_defaults; i++) {
3775
unsigned int reg = map->reg_defaults[i].reg;
3876
unsigned int index = regcache_flat_get_index(map, reg);
3977

40-
cache[index] = map->reg_defaults[i].def;
78+
cache->data[index] = map->reg_defaults[i].def;
79+
__set_bit(index, cache->valid);
4180
}
4281

4382
return 0;
4483
}
4584

46-
static int regcache_flat_exit(struct regmap *map)
85+
static int regcache_flat_read(struct regmap *map,
86+
unsigned int reg, unsigned int *value)
4787
{
48-
kfree(map->cache);
49-
map->cache = NULL;
88+
struct regcache_flat_data *cache = map->cache;
89+
unsigned int index = regcache_flat_get_index(map, reg);
90+
91+
/* legacy behavior: ignore validity, but warn the user */
92+
if (unlikely(!test_bit(index, cache->valid)))
93+
dev_warn_once(map->dev,
94+
"using zero-initialized flat cache, this may cause unexpected behavior");
95+
96+
*value = cache->data[index];
5097

5198
return 0;
5299
}
53100

54-
static int regcache_flat_read(struct regmap *map,
55-
unsigned int reg, unsigned int *value)
101+
static int regcache_flat_sparse_read(struct regmap *map,
102+
unsigned int reg, unsigned int *value)
56103
{
57-
unsigned int *cache = map->cache;
104+
struct regcache_flat_data *cache = map->cache;
58105
unsigned int index = regcache_flat_get_index(map, reg);
59106

60-
*value = cache[index];
107+
if (unlikely(!test_bit(index, cache->valid)))
108+
return -ENOENT;
109+
110+
*value = cache->data[index];
61111

62112
return 0;
63113
}
64114

65115
static int regcache_flat_write(struct regmap *map, unsigned int reg,
66116
unsigned int value)
67117
{
68-
unsigned int *cache = map->cache;
118+
struct regcache_flat_data *cache = map->cache;
69119
unsigned int index = regcache_flat_get_index(map, reg);
70120

71-
cache[index] = value;
121+
cache->data[index] = value;
122+
__set_bit(index, cache->valid);
123+
124+
return 0;
125+
}
126+
127+
static int regcache_flat_drop(struct regmap *map, unsigned int min,
128+
unsigned int max)
129+
{
130+
struct regcache_flat_data *cache = map->cache;
131+
unsigned int bitmap_min = regcache_flat_get_index(map, min);
132+
unsigned int bitmap_max = regcache_flat_get_index(map, max);
133+
134+
bitmap_clear(cache->valid, bitmap_min, bitmap_max + 1 - bitmap_min);
72135

73136
return 0;
74137
}
@@ -78,6 +141,18 @@ struct regcache_ops regcache_flat_ops = {
78141
.name = "flat",
79142
.init = regcache_flat_init,
80143
.exit = regcache_flat_exit,
144+
.populate = regcache_flat_populate,
81145
.read = regcache_flat_read,
82146
.write = regcache_flat_write,
83147
};
148+
149+
struct regcache_ops regcache_flat_sparse_ops = {
150+
.type = REGCACHE_FLAT_S,
151+
.name = "flat-sparse",
152+
.init = regcache_flat_init,
153+
.exit = regcache_flat_exit,
154+
.populate = regcache_flat_populate,
155+
.read = regcache_flat_sparse_read,
156+
.write = regcache_flat_write,
157+
.drop = regcache_flat_drop,
158+
};

drivers/base/regmap/regcache-maple.c

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,23 @@ static int regcache_maple_sync(struct regmap *map, unsigned int min,
289289
return ret;
290290
}
291291

292+
static int regcache_maple_init(struct regmap *map)
293+
{
294+
struct maple_tree *mt;
295+
296+
mt = kmalloc(sizeof(*mt), map->alloc_flags);
297+
if (!mt)
298+
return -ENOMEM;
299+
map->cache = mt;
300+
301+
mt_init(mt);
302+
303+
if (!mt_external_lock(mt) && map->lock_key)
304+
lockdep_set_class_and_subclass(&mt->ma_lock, map->lock_key, 1);
305+
306+
return 0;
307+
}
308+
292309
static int regcache_maple_exit(struct regmap *map)
293310
{
294311
struct maple_tree *mt = map->cache;
@@ -340,26 +357,12 @@ static int regcache_maple_insert_block(struct regmap *map, int first,
340357
return ret;
341358
}
342359

343-
static int regcache_maple_init(struct regmap *map)
360+
static int regcache_maple_populate(struct regmap *map)
344361
{
345-
struct maple_tree *mt;
346362
int i;
347363
int ret;
348364
int range_start;
349365

350-
mt = kmalloc(sizeof(*mt), map->alloc_flags);
351-
if (!mt)
352-
return -ENOMEM;
353-
map->cache = mt;
354-
355-
mt_init(mt);
356-
357-
if (!mt_external_lock(mt) && map->lock_key)
358-
lockdep_set_class_and_subclass(&mt->ma_lock, map->lock_key, 1);
359-
360-
if (!map->num_reg_defaults)
361-
return 0;
362-
363366
range_start = 0;
364367

365368
/* Scan for ranges of contiguous registers */
@@ -369,30 +372,22 @@ static int regcache_maple_init(struct regmap *map)
369372
ret = regcache_maple_insert_block(map, range_start,
370373
i - 1);
371374
if (ret != 0)
372-
goto err;
375+
return ret;
373376

374377
range_start = i;
375378
}
376379
}
377380

378381
/* Add the last block */
379-
ret = regcache_maple_insert_block(map, range_start,
380-
map->num_reg_defaults - 1);
381-
if (ret != 0)
382-
goto err;
383-
384-
return 0;
385-
386-
err:
387-
regcache_maple_exit(map);
388-
return ret;
382+
return regcache_maple_insert_block(map, range_start, map->num_reg_defaults - 1);
389383
}
390384

391385
struct regcache_ops regcache_maple_ops = {
392386
.type = REGCACHE_MAPLE,
393387
.name = "maple",
394388
.init = regcache_maple_init,
395389
.exit = regcache_maple_exit,
390+
.populate = regcache_maple_populate,
396391
.read = regcache_maple_read,
397392
.write = regcache_maple_write,
398393
.drop = regcache_maple_drop,

drivers/base/regmap/regcache-rbtree.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,6 @@ static void rbtree_debugfs_init(struct regmap *map)
184184
static int regcache_rbtree_init(struct regmap *map)
185185
{
186186
struct regcache_rbtree_ctx *rbtree_ctx;
187-
int i;
188-
int ret;
189187

190188
map->cache = kmalloc(sizeof *rbtree_ctx, map->alloc_flags);
191189
if (!map->cache)
@@ -195,19 +193,7 @@ static int regcache_rbtree_init(struct regmap *map)
195193
rbtree_ctx->root = RB_ROOT;
196194
rbtree_ctx->cached_rbnode = NULL;
197195

198-
for (i = 0; i < map->num_reg_defaults; i++) {
199-
ret = regcache_rbtree_write(map,
200-
map->reg_defaults[i].reg,
201-
map->reg_defaults[i].def);
202-
if (ret)
203-
goto err;
204-
}
205-
206196
return 0;
207-
208-
err:
209-
regcache_rbtree_exit(map);
210-
return ret;
211197
}
212198

213199
static int regcache_rbtree_exit(struct regmap *map)
@@ -239,6 +225,22 @@ static int regcache_rbtree_exit(struct regmap *map)
239225
return 0;
240226
}
241227

228+
static int regcache_rbtree_populate(struct regmap *map)
229+
{
230+
unsigned int i;
231+
int ret;
232+
233+
for (i = 0; i < map->num_reg_defaults; i++) {
234+
ret = regcache_rbtree_write(map,
235+
map->reg_defaults[i].reg,
236+
map->reg_defaults[i].def);
237+
if (ret)
238+
return ret;
239+
}
240+
241+
return 0;
242+
}
243+
242244
static int regcache_rbtree_read(struct regmap *map,
243245
unsigned int reg, unsigned int *value)
244246
{
@@ -546,6 +548,7 @@ struct regcache_ops regcache_rbtree_ops = {
546548
.name = "rbtree",
547549
.init = regcache_rbtree_init,
548550
.exit = regcache_rbtree_exit,
551+
.populate = regcache_rbtree_populate,
549552
#ifdef CONFIG_DEBUG_FS
550553
.debugfs_init = rbtree_debugfs_init,
551554
#endif

drivers/base/regmap/regcache.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "internal.h"
1717

1818
static const struct regcache_ops *cache_types[] = {
19+
&regcache_flat_sparse_ops,
1920
&regcache_rbtree_ops,
2021
&regcache_maple_ops,
2122
&regcache_flat_ops,
@@ -221,8 +222,24 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
221222
if (ret)
222223
goto err_free;
223224
}
225+
226+
if (map->num_reg_defaults && map->cache_ops->populate) {
227+
dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name);
228+
map->lock(map->lock_arg);
229+
ret = map->cache_ops->populate(map);
230+
map->unlock(map->lock_arg);
231+
if (ret)
232+
goto err_exit;
233+
}
224234
return 0;
225235

236+
err_exit:
237+
if (map->cache_ops->exit) {
238+
dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name);
239+
map->lock(map->lock_arg);
240+
ret = map->cache_ops->exit(map);
241+
map->unlock(map->lock_arg);
242+
}
226243
err_free:
227244
kfree(map->reg_defaults);
228245
if (map->cache_free)

drivers/base/regmap/regmap-i3c.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22
// Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
33

4+
#include <linux/array_size.h>
45
#include <linux/regmap.h>
56
#include <linux/i3c/device.h>
67
#include <linux/i3c/master.h>
@@ -18,7 +19,7 @@ static int regmap_i3c_write(void *context, const void *data, size_t count)
1819
},
1920
};
2021

21-
return i3c_device_do_priv_xfers(i3c, xfers, 1);
22+
return i3c_device_do_priv_xfers(i3c, xfers, ARRAY_SIZE(xfers));
2223
}
2324

2425
static int regmap_i3c_read(void *context,
@@ -37,7 +38,7 @@ static int regmap_i3c_read(void *context,
3738
xfers[1].len = val_size;
3839
xfers[1].data.in = val;
3940

40-
return i3c_device_do_priv_xfers(i3c, xfers, 2);
41+
return i3c_device_do_priv_xfers(i3c, xfers, ARRAY_SIZE(xfers));
4142
}
4243

4344
static const struct regmap_bus regmap_i3c = {

0 commit comments

Comments
 (0)