Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

regmap: Add reg_default_cb callback for flat cache defaults

Commit e062bdfdd6ad ("regmap: warn users about uninitialized flat cache")
warns when REGCACHE_FLAT is used without full defaults. This causes
false positives on hardware where many registers reset to zero but are
not listed in reg_defaults, forcing drivers to maintain large tables
just to silence the warning.

Add a reg_default_cb() hook so drivers can supply defaults for registers
not present in reg_defaults when populating REGCACHE_FLAT. This keeps
the warning quiet for known zero-reset registers without bloating
tables. Provide a generic regmap_default_zero_cb() helper for drivers
that need zero defaults.

The hook is only used for REGCACHE_FLAT; the core does not
check readable/writeable access, so drivers must provide readable_reg/
writeable_reg callbacks and handle holes in the register map.

Signed-off-by: Sheetal <sheetal@nvidia.com>
Link: https://patch.msgid.link/20260123095346.1258556-3-sheetal@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Sheetal and committed by
Mark Brown
dc65b1ed 63804fed

+40 -1
+3
drivers/base/regmap/internal.h
··· 117 117 void *val_buf, size_t val_size); 118 118 int (*write)(void *context, const void *data, size_t count); 119 119 120 + int (*reg_default_cb)(struct device *dev, unsigned int reg, 121 + unsigned int *val); 122 + 120 123 unsigned long read_flag_mask; 121 124 unsigned long write_flag_mask; 122 125
+19
drivers/base/regmap/regcache-flat.c
··· 79 79 __set_bit(index, cache->valid); 80 80 } 81 81 82 + if (map->reg_default_cb) { 83 + dev_dbg(map->dev, 84 + "Populating regcache_flat using reg_default_cb callback\n"); 85 + 86 + for (i = 0; i <= map->max_register; i += map->reg_stride) { 87 + unsigned int index = regcache_flat_get_index(map, i); 88 + unsigned int value; 89 + 90 + if (test_bit(index, cache->valid)) 91 + continue; 92 + 93 + if (map->reg_default_cb(map->dev, i, &value)) 94 + continue; 95 + 96 + cache->data[index] = value; 97 + __set_bit(index, cache->valid); 98 + } 99 + } 100 + 82 101 return 0; 83 102 } 84 103
+2 -1
drivers/base/regmap/regcache.c
··· 223 223 goto err_free; 224 224 } 225 225 226 - if (map->num_reg_defaults && map->cache_ops->populate) { 226 + if (map->cache_ops->populate && 227 + (map->num_reg_defaults || map->reg_default_cb)) { 227 228 dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name); 228 229 map->lock(map->lock_arg); 229 230 ret = map->cache_ops->populate(map);
+2
drivers/base/regmap/regmap.c
··· 813 813 map->precious_reg = config->precious_reg; 814 814 map->writeable_noinc_reg = config->writeable_noinc_reg; 815 815 map->readable_noinc_reg = config->readable_noinc_reg; 816 + map->reg_default_cb = config->reg_default_cb; 816 817 map->cache_type = config->cache_type; 817 818 818 819 spin_lock_init(&map->async_lock); ··· 1436 1435 map->precious_reg = config->precious_reg; 1437 1436 map->writeable_noinc_reg = config->writeable_noinc_reg; 1438 1437 map->readable_noinc_reg = config->readable_noinc_reg; 1438 + map->reg_default_cb = config->reg_default_cb; 1439 1439 map->cache_type = config->cache_type; 1440 1440 1441 1441 ret = regmap_set_name(map, config);
+14
include/linux/regmap.h
··· 359 359 * @reg_defaults: Power on reset values for registers (for use with 360 360 * register cache support). 361 361 * @num_reg_defaults: Number of elements in reg_defaults. 362 + * @reg_default_cb: Optional callback to return default values for registers 363 + * not listed in reg_defaults. This is only used for 364 + * REGCACHE_FLAT population; drivers must ensure the readable_reg/ 365 + * writeable_reg callbacks are defined to handle holes. 362 366 * 363 367 * @read_flag_mask: Mask to be set in the top bytes of the register when doing 364 368 * a read. ··· 453 449 const struct regmap_access_table *rd_noinc_table; 454 450 const struct reg_default *reg_defaults; 455 451 unsigned int num_reg_defaults; 452 + int (*reg_default_cb)(struct device *dev, unsigned int reg, 453 + unsigned int *def); 456 454 enum regcache_type cache_type; 457 455 const void *reg_defaults_raw; 458 456 unsigned int num_reg_defaults_raw; ··· 1353 1347 unsigned int mask, unsigned int val) 1354 1348 { 1355 1349 return regmap_update_bits_base(map, reg, mask, val, NULL, false, true); 1350 + } 1351 + 1352 + static inline int regmap_default_zero_cb(struct device *dev, 1353 + unsigned int reg, 1354 + unsigned int *def) 1355 + { 1356 + *def = 0; 1357 + return 0; 1356 1358 } 1357 1359 1358 1360 int regmap_get_val_bytes(struct regmap *map);