@@ -59,6 +59,9 @@ struct regmap {
unsigned long raw_spinlock_flags;
};
};
+#ifdef CONFIG_LOCKDEP
+ struct lockdep_map *lockdep;
+#endif
regmap_lock lock;
regmap_unlock unlock;
void *lock_arg; /* This is passed to lock/unlock functions */
@@ -344,4 +347,13 @@ struct regmap *__regmap_init_raw_ram(struct device *dev,
#define regmap_init_raw_ram(dev, config, data) \
__regmap_lockdep_wrapper(__regmap_init_raw_ram, #dev, dev, config, data)
+#ifdef CONFIG_LOCKDEP
+static inline void regmap_set_lockdep(struct regmap *m, struct lockdep_map *l)
+{
+ m->lockdep = l;
+}
+#else
+#define regmap_set_lockdep(m, l)
+#endif
+
#endif
@@ -365,7 +365,16 @@ static int regcache_maple_init(struct regmap *map)
return -ENOMEM;
map->cache = mt;
+#ifdef CONFIG_LOCKDEP
+ if (map->lockdep) {
+ mt_init_flags(mt, MT_FLAGS_LOCK_EXTERN);
+ mt_set_external_lock_dep_map(mt, map->lockdep);
+ } else {
+ mt_init(mt);
+ }
+#else
mt_init(mt);
+#endif
if (!map->num_reg_defaults)
return 0;
@@ -729,12 +729,15 @@ struct regmap *__regmap_init(struct device *dev,
map->unlock = regmap_unlock_raw_spinlock;
lockdep_set_class_and_name(&map->raw_spinlock,
lock_key, lock_name);
+ regmap_set_lockdep(map,
+ &map->raw_spinlock.dep_map);
} else {
spin_lock_init(&map->spinlock);
map->lock = regmap_lock_spinlock;
map->unlock = regmap_unlock_spinlock;
lockdep_set_class_and_name(&map->spinlock,
lock_key, lock_name);
+ regmap_set_lockdep(map, &map->spinlock.dep_map);
}
} else {
mutex_init(&map->mutex);
@@ -743,6 +746,7 @@ struct regmap *__regmap_init(struct device *dev,
map->can_sleep = true;
lockdep_set_class_and_name(&map->mutex,
lock_key, lock_name);
+ regmap_set_lockdep(map, &map->mutex.dep_map);
}
map->lock_arg = map;
}
It is not possible to use the maple tree without holding a lock of some kind, by default the maple tree incorporates a lock but it does have support for registering an external lock which will be asserted against instead. At present regmap uses the maple tree's internal lock which is unfortunate since there is also regmap level locking above the cache which protects the cache data structure and things like read/modify/write operations. Let's reduce the overhead here by telling the maple tree about the regmap level lock for cases where regmap does it's own locking. We also support external and custom locking for regmap, neither of which will benefit from this, but this will cover the vast majority of users. Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/base/regmap/internal.h | 12 ++++++++++++ drivers/base/regmap/regcache-maple.c | 9 +++++++++ drivers/base/regmap/regmap.c | 4 ++++ 3 files changed, 25 insertions(+)