diff options
| author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2026-03-05 09:53:01 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-03-05 15:23:00 +0000 |
| commit | 0cb7ae981894ff1fd0283813a17253250a747cf5 (patch) | |
| tree | 8ae9f71eadadc88c0484e4af75d9f5762893c0bc /drivers/base/regmap | |
| parent | 8e2d279724944f788edc633e4888107eae666a37 (diff) | |
regcache: Allocate and free reg_defaults on the same level
Currently reg_defaults buffer may be allocated on two different
levels when the user provided them and we duplicate it in regcache_init()
or when user wants us to read back from HW in regcache_hw_init().
This inconsistency makes code harder to follow and maintain. Allocate
and free reg_defaults on the same level in regcache_init() to improve
the readability and maintenance efforts.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260305085449.3184020-3-andriy.shevchenko@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/base/regmap')
| -rw-r--r-- | drivers/base/regmap/regcache.c | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index b73de70bbf3f..e9d95aa63938 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -56,17 +56,12 @@ static int regcache_count_cacheable_registers(struct regmap *map) return count; } -static int regcache_hw_init(struct regmap *map, int count) +static int regcache_hw_init(struct regmap *map) { int ret; unsigned int reg, val; void *tmp_buf; - map->num_reg_defaults = count; - map->reg_defaults = kmalloc_objs(struct reg_default, count); - if (!map->reg_defaults) - return -ENOMEM; - if (!map->reg_defaults_raw) { bool cache_bypass = map->cache_bypass; dev_dbg(map->dev, "No cache defaults, reading back from HW\n"); @@ -74,10 +69,8 @@ static int regcache_hw_init(struct regmap *map, int count) /* Bypass the cache access till data read from HW */ map->cache_bypass = true; tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL); - if (!tmp_buf) { - ret = -ENOMEM; - goto err_free; - } + if (!tmp_buf) + return -ENOMEM; ret = regmap_raw_read(map, 0, tmp_buf, map->cache_size_raw); map->cache_bypass = cache_bypass; @@ -110,7 +103,7 @@ static int regcache_hw_init(struct regmap *map, int count) if (ret != 0) { dev_err(map->dev, "Failed to read %x: %d\n", reg, ret); - goto err_free; + return ret; } } @@ -120,16 +113,10 @@ static int regcache_hw_init(struct regmap *map, int count) } return 0; - -err_free: - kfree(map->reg_defaults); - - return ret; } static void regcache_hw_exit(struct regmap *map) { - kfree(map->reg_defaults); if (map->cache_free) kfree(map->reg_defaults_raw); } @@ -209,13 +196,18 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) if (map->cache_bypass) return 0; + map->num_reg_defaults = count; + map->reg_defaults = kmalloc_objs(struct reg_default, count); + if (!map->reg_defaults) + return -ENOMEM; + /* Some devices such as PMICs don't have cache defaults, * we cope with this by reading back the HW registers and * crafting the cache defaults by hand. */ - ret = regcache_hw_init(map, count); + ret = regcache_hw_init(map); if (ret < 0) - return ret; + goto err_free_reg_defaults; } if (!map->max_register_is_set && map->num_reg_defaults_raw) { @@ -253,6 +245,8 @@ err_exit: } err_free: regcache_hw_exit(map); +err_free_reg_defaults: + kfree(map->reg_defaults); return ret; } @@ -273,6 +267,8 @@ void regcache_exit(struct regmap *map) map->cache_ops->exit(map); map->unlock(map->lock_arg); } + + kfree(map->reg_defaults); } /** |
