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

regmap: rework ->max_register handling

When regmap consists of single register, 'regmap' subsystem is unable to
understand whether ->max_register is set or not, because in both cases it
is equal to zero. It leads to that the logic based on value of
->max_register doesn't work. For example using of REGCACHE_FLAT fails.

This patch introduces an extra parameter to regmap config, indicating
that zero value in ->max_register is authentic.

Signed-off-by: Jan Dakinevich <jan.dakinevich@salutedevices.com>
Link: https://lore.kernel.org/r/20240126200836.1829995-1-jan.dakinevich@salutedevices.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Jan Dakinevich and committed by
Mark Brown
0ec74ad3 6613476e

+16 -6
+1
drivers/base/regmap/internal.h
··· 93 93 #endif 94 94 95 95 unsigned int max_register; 96 + bool max_register_is_set; 96 97 bool (*writeable_reg)(struct device *dev, unsigned int reg); 97 98 bool (*readable_reg)(struct device *dev, unsigned int reg); 98 99 bool (*volatile_reg)(struct device *dev, unsigned int reg);
+1 -1
drivers/base/regmap/regcache-flat.c
··· 23 23 int i; 24 24 unsigned int *cache; 25 25 26 - if (!map || map->reg_stride_order < 0 || !map->max_register) 26 + if (!map || map->reg_stride_order < 0 || !map->max_register_is_set) 27 27 return -EINVAL; 28 28 29 29 map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)
+3 -1
drivers/base/regmap/regcache.c
··· 187 187 return 0; 188 188 } 189 189 190 - if (!map->max_register && map->num_reg_defaults_raw) 190 + if (!map->max_register_is_set && map->num_reg_defaults_raw) { 191 191 map->max_register = (map->num_reg_defaults_raw - 1) * map->reg_stride; 192 + map->max_register_is_set = true; 193 + } 192 194 193 195 if (map->cache_ops->init) { 194 196 dev_dbg(map->dev, "Initializing %s cache\n",
+6 -4
drivers/base/regmap/regmap.c
··· 89 89 90 90 bool regmap_writeable(struct regmap *map, unsigned int reg) 91 91 { 92 - if (map->max_register && reg > map->max_register) 92 + if (map->max_register_is_set && reg > map->max_register) 93 93 return false; 94 94 95 95 if (map->writeable_reg) ··· 112 112 if (!map->cache_ops) 113 113 return false; 114 114 115 - if (map->max_register && reg > map->max_register) 115 + if (map->max_register_is_set && reg > map->max_register) 116 116 return false; 117 117 118 118 map->lock(map->lock_arg); ··· 129 129 if (!map->reg_read) 130 130 return false; 131 131 132 - if (map->max_register && reg > map->max_register) 132 + if (map->max_register_is_set && reg > map->max_register) 133 133 return false; 134 134 135 135 if (map->format.format_write) ··· 787 787 map->bus = bus; 788 788 map->bus_context = bus_context; 789 789 map->max_register = config->max_register; 790 + map->max_register_is_set = map->max_register ?: config->max_register_is_0; 790 791 map->wr_table = config->wr_table; 791 792 map->rd_table = config->rd_table; 792 793 map->volatile_table = config->volatile_table; ··· 1413 1412 regmap_debugfs_exit(map); 1414 1413 1415 1414 map->max_register = config->max_register; 1415 + map->max_register_is_set = map->max_register ?: config->max_register_is_0; 1416 1416 map->writeable_reg = config->writeable_reg; 1417 1417 map->readable_reg = config->readable_reg; 1418 1418 map->volatile_reg = config->volatile_reg; ··· 3385 3383 */ 3386 3384 int regmap_get_max_register(struct regmap *map) 3387 3385 { 3388 - return map->max_register ? map->max_register : -EINVAL; 3386 + return map->max_register_is_set ? map->max_register : -EINVAL; 3389 3387 } 3390 3388 EXPORT_SYMBOL_GPL(regmap_get_max_register); 3391 3389
+5
include/linux/regmap.h
··· 332 332 * @io_port: Support IO port accessors. Makes sense only when MMIO vs. IO port 333 333 * access can be distinguished. 334 334 * @max_register: Optional, specifies the maximum valid register address. 335 + * @max_register_is_0: Optional, specifies that zero value in @max_register 336 + * should be taken into account. This is a workaround to 337 + * apply handling of @max_register for regmap that contains 338 + * only one register. 335 339 * @wr_table: Optional, points to a struct regmap_access_table specifying 336 340 * valid ranges for write access. 337 341 * @rd_table: As above, for read access. ··· 426 422 bool io_port; 427 423 428 424 unsigned int max_register; 425 + bool max_register_is_0; 429 426 const struct regmap_access_table *wr_table; 430 427 const struct regmap_access_table *rd_table; 431 428 const struct regmap_access_table *volatile_table;