[PATCH v2 1/2] regmap: Remove debugfs before cache teardown

From: Michael Reeves via B4 Relay

Date: Sun Oct 04 2026 - 08:38:48 EST


From: Michael Reeves <michael.reeves077@xxxxxxxxx>

regmap_exit() and regmap_reinit_cache() destroy the register cache before
removing debugfs. A concurrent debugfs cache operation can therefore
access cache state after the backend exit callback starts freeing it.

Remove debugfs before cache teardown, and clear the debugfs pointer after
removal. During cache reinitialization, recreate debugfs only after the
new cache initializes successfully.

Signed-off-by: Michael Reeves <michael.reeves077@xxxxxxxxx>
---
drivers/base/regmap/regmap-debugfs.c | 1 +
drivers/base/regmap/regmap.c | 15 +++++++++------
2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 18f1c60749..9a09df2ba8 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -664,6 +664,7 @@ void regmap_debugfs_exit(struct regmap *map)
{
if (map->debugfs) {
debugfs_remove_recursive(map->debugfs);
+ map->debugfs = NULL;
mutex_lock(&map->cache_lock);
regmap_debugfs_free_dump_cache(map);
mutex_unlock(&map->cache_lock);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index e6e022b026..8e50a05ff0 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1422,8 +1422,8 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
{
int ret;

- regcache_exit(map);
regmap_debugfs_exit(map);
+ regcache_exit(map);

map->max_register = config->max_register;
map->max_register_is_set = map->max_register ?: config->max_register_is_0;
@@ -1440,12 +1440,16 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
if (ret)
return ret;

- regmap_debugfs_init(map);
-
map->cache_bypass = false;
map->cache_only = false;

- return regcache_init(map, config);
+ ret = regcache_init(map, config);
+ if (ret)
+ return ret;
+
+ regmap_debugfs_init(map);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(regmap_reinit_cache);

@@ -1459,9 +1463,8 @@ void regmap_exit(struct regmap *map)
struct regmap_async *async;

regmap_detach_dev(map->dev, map);
- regcache_exit(map);
-
regmap_debugfs_exit(map);
+ regcache_exit(map);
regmap_range_exit(map);
if (map->bus && map->bus->free_context)
map->bus->free_context(map->bus_context);

--
2.55.0