Skip to content

Commit e7662bc

Browse files
andy-shevbroonie
authored andcommitted
regcache: Move HW readback after cache initialisation
Make sure that cache is initialised before calling any IO using regmap, this makes sure that we won't access NULL or invalid pointers in the cache which hasn't been initialised. As a side effect it also makes the ordering of cleaning up the resources in regcache_exit() to be the same (and correct) as in the error path of regcache_init(). This is not a problem right now as they do not have dependencies, but it makes code robust against potential changes in the future. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://patch.msgid.link/20260305085449.3184020-4-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 0cb7ae9 commit e7662bc

1 file changed

Lines changed: 15 additions & 12 deletions

File tree

drivers/base/regmap/regcache.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,6 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
200200
map->reg_defaults = kmalloc_objs(struct reg_default, count);
201201
if (!map->reg_defaults)
202202
return -ENOMEM;
203-
204-
/* Some devices such as PMICs don't have cache defaults,
205-
* we cope with this by reading back the HW registers and
206-
* crafting the cache defaults by hand.
207-
*/
208-
ret = regcache_hw_init(map);
209-
if (ret < 0)
210-
goto err_free_reg_defaults;
211203
}
212204

213205
if (!map->max_register_is_set && map->num_reg_defaults_raw) {
@@ -222,7 +214,18 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
222214
ret = map->cache_ops->init(map);
223215
map->unlock(map->lock_arg);
224216
if (ret)
225-
goto err_free;
217+
goto err_free_reg_defaults;
218+
}
219+
220+
/*
221+
* Some devices such as PMICs don't have cache defaults,
222+
* we cope with this by reading back the HW registers and
223+
* crafting the cache defaults by hand.
224+
*/
225+
if (count) {
226+
ret = regcache_hw_init(map);
227+
if (ret)
228+
goto err_exit;
226229
}
227230

228231
if (map->cache_ops->populate &&
@@ -232,19 +235,19 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
232235
ret = map->cache_ops->populate(map);
233236
map->unlock(map->lock_arg);
234237
if (ret)
235-
goto err_exit;
238+
goto err_free;
236239
}
237240
return 0;
238241

242+
err_free:
243+
regcache_hw_exit(map);
239244
err_exit:
240245
if (map->cache_ops->exit) {
241246
dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name);
242247
map->lock(map->lock_arg);
243248
ret = map->cache_ops->exit(map);
244249
map->unlock(map->lock_arg);
245250
}
246-
err_free:
247-
regcache_hw_exit(map);
248251
err_free_reg_defaults:
249252
kfree(map->reg_defaults);
250253

0 commit comments

Comments
 (0)