Commit 0ec74ad3 authored by Jan Dakinevich's avatar Jan Dakinevich Committed by Mark Brown

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: default avatarJan Dakinevich <jan.dakinevich@salutedevices.com>
Link: https://lore.kernel.org/r/20240126200836.1829995-1-jan.dakinevich@salutedevices.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 6613476e
......@@ -93,6 +93,7 @@ struct regmap {
#endif
unsigned int max_register;
bool max_register_is_set;
bool (*writeable_reg)(struct device *dev, unsigned int reg);
bool (*readable_reg)(struct device *dev, unsigned int reg);
bool (*volatile_reg)(struct device *dev, unsigned int reg);
......
......@@ -23,7 +23,7 @@ static int regcache_flat_init(struct regmap *map)
int i;
unsigned int *cache;
if (!map || map->reg_stride_order < 0 || !map->max_register)
if (!map || map->reg_stride_order < 0 || !map->max_register_is_set)
return -EINVAL;
map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)
......
......@@ -187,8 +187,10 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
return 0;
}
if (!map->max_register && map->num_reg_defaults_raw)
if (!map->max_register_is_set && map->num_reg_defaults_raw) {
map->max_register = (map->num_reg_defaults_raw - 1) * map->reg_stride;
map->max_register_is_set = true;
}
if (map->cache_ops->init) {
dev_dbg(map->dev, "Initializing %s cache\n",
......
......@@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(regmap_check_range_table);
bool regmap_writeable(struct regmap *map, unsigned int reg)
{
if (map->max_register && reg > map->max_register)
if (map->max_register_is_set && reg > map->max_register)
return false;
if (map->writeable_reg)
......@@ -112,7 +112,7 @@ bool regmap_cached(struct regmap *map, unsigned int reg)
if (!map->cache_ops)
return false;
if (map->max_register && reg > map->max_register)
if (map->max_register_is_set && reg > map->max_register)
return false;
map->lock(map->lock_arg);
......@@ -129,7 +129,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg)
if (!map->reg_read)
return false;
if (map->max_register && reg > map->max_register)
if (map->max_register_is_set && reg > map->max_register)
return false;
if (map->format.format_write)
......@@ -787,6 +787,7 @@ struct regmap *__regmap_init(struct device *dev,
map->bus = bus;
map->bus_context = bus_context;
map->max_register = config->max_register;
map->max_register_is_set = map->max_register ?: config->max_register_is_0;
map->wr_table = config->wr_table;
map->rd_table = config->rd_table;
map->volatile_table = config->volatile_table;
......@@ -1412,6 +1413,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
regmap_debugfs_exit(map);
map->max_register = config->max_register;
map->max_register_is_set = map->max_register ?: config->max_register_is_0;
map->writeable_reg = config->writeable_reg;
map->readable_reg = config->readable_reg;
map->volatile_reg = config->volatile_reg;
......@@ -3383,7 +3385,7 @@ EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
*/
int regmap_get_max_register(struct regmap *map)
{
return map->max_register ? map->max_register : -EINVAL;
return map->max_register_is_set ? map->max_register : -EINVAL;
}
EXPORT_SYMBOL_GPL(regmap_get_max_register);
......
......@@ -332,6 +332,10 @@ typedef void (*regmap_unlock)(void *);
* @io_port: Support IO port accessors. Makes sense only when MMIO vs. IO port
* access can be distinguished.
* @max_register: Optional, specifies the maximum valid register address.
* @max_register_is_0: Optional, specifies that zero value in @max_register
* should be taken into account. This is a workaround to
* apply handling of @max_register for regmap that contains
* only one register.
* @wr_table: Optional, points to a struct regmap_access_table specifying
* valid ranges for write access.
* @rd_table: As above, for read access.
......@@ -422,6 +426,7 @@ struct regmap_config {
bool io_port;
unsigned int max_register;
bool max_register_is_0;
const struct regmap_access_table *wr_table;
const struct regmap_access_table *rd_table;
const struct regmap_access_table *volatile_table;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment