diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c index e46fe5c32b7f..16e488da5f23 100644 --- a/drivers/base/regmap/regcache-maple.c +++ b/drivers/base/regmap/regcache-maple.c @@ -312,16 +312,21 @@ static void regcache_maple_exit(struct regmap *map) struct maple_tree *mt = map->cache; MA_STATE(mas, mt, 0, UINT_MAX); unsigned int *entry; + unsigned long flags; /* if we've already been called then just return */ if (!mt) return; - mas_lock(&mas); + /* + * Register access may take the Maple lock from hard IRQ context, so + * preserve its IRQ-safe lockdep state during teardown. + */ + mas_lock_irqsave(&mas, flags); mas_for_each(&mas, entry, UINT_MAX) kfree(entry); __mt_destroy(mt); - mas_unlock(&mas); + mas_unlock_irqrestore(&mas, flags); kfree(mt); map->cache = NULL; diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 0d58d900a2ca..b137ded7fdd4 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -225,9 +225,7 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) if (map->cache_ops->init) { dev_dbg(map->dev, "Initializing %s cache\n", map->cache_ops->name); - map->lock(map->lock_arg); ret = map->cache_ops->init(map); - map->unlock(map->lock_arg); if (ret) goto err_free_reg_defaults; } @@ -259,9 +257,7 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) err_exit: if (map->cache_ops->exit) { dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name); - map->lock(map->lock_arg); map->cache_ops->exit(map); - map->unlock(map->lock_arg); } err_free_reg_defaults: kfree(map->reg_defaults); @@ -281,9 +277,7 @@ void regcache_exit(struct regmap *map) if (map->cache_ops->exit) { dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name); - map->lock(map->lock_arg); map->cache_ops->exit(map); - map->unlock(map->lock_arg); } kfree(map->reg_defaults); diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 18f1c60749fe..9a09df2ba847 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-irq.c b/drivers/base/regmap/regmap-irq.c index 99b55b1053ee..715eb9e7aa2a 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -963,7 +963,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, return 0; err_domain: - /* Should really dispose of the domain but... */ + irq_domain_remove(d->domain); err_mutex: mutex_destroy(&d->lock); lockdep_unregister_key(&d->lock_key); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e6e022b02637..8e50a05ff087 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); diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h index e595ae5cd0ee..f6491a92ead1 100644 --- a/include/linux/maple_tree.h +++ b/include/linux/maple_tree.h @@ -507,9 +507,13 @@ struct ma_wr_state { }; #define mas_lock(mas) spin_lock(&((mas)->tree->ma_lock)) +#define mas_lock_irqsave(mas, flags) \ + spin_lock_irqsave(&((mas)->tree->ma_lock), flags) #define mas_lock_nested(mas, subclass) \ spin_lock_nested(&((mas)->tree->ma_lock), subclass) #define mas_unlock(mas) spin_unlock(&((mas)->tree->ma_lock)) +#define mas_unlock_irqrestore(mas, flags) \ + spin_unlock_irqrestore(&((mas)->tree->ma_lock), flags) /* * Special values for ma_state.node.