Merge tag 'regmap-fix-v7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Merge commit. Changes below are compared with the first parent: 72732cbe.
Changes
6 files changed · +22 −15
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| drivers/base/regmap/regcache-maple.c | modified | +7 | −2 | View file |
| drivers/base/regmap/regcache.c | modified | +0 | −6 | View file |
| drivers/base/regmap/regmap-debugfs.c | modified | +1 | −0 | View file |
| drivers/base/regmap/regmap-irq.c | modified | +1 | −1 | View file |
| drivers/base/regmap/regmap.c | modified | +9 | −6 | View file |
| include/linux/maple_tree.h | modified | +4 | −0 | View file |
drivers/base/regmap/regcache-maple.c
View filediff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c
index e46fe5c..16e488d 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;
drivers/base/regmap/regcache.c
View filediff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 0d58d90..b137ded 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 @@ err_free:
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);
drivers/base/regmap/regmap-debugfs.c
View filediff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 18f1c60..9a09df2 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);
drivers/base/regmap/regmap-irq.c
View filediff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 99b55b1..715eb9e 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);
drivers/base/regmap/regmap.c
View filediff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index e6e022b..8e50a05 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);
include/linux/maple_tree.h
View filediff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h
index e595ae5..f6491a9 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.