[PATCH v2 05/10] regmap: factor out regmap_set_lock()

From: Peng Fan

Date: Fri Nov 13 2026 - 14:55:51 EST


From: Peng Fan <peng.fan@xxxxxxx>

The locking scheme selection in __regmap_init() is a self contained
~60 line if/else ladder covering six cases: locking disabled, caller
supplied callbacks, hardware spinlock, raw spinlock, spinlock and
mutex. It has no interaction with the rest of the initialisation
sequence beyond the map and config pointers.

Move it into regmap_set_lock(). The only error case, a failed
hwspin_lock_request_specific(), now returns -ENXIO to the caller
instead of jumping to err_name directly, and each branch returns
early rather than falling through the ladder.

No functional change intended.

Signed-off-by: Peng Fan <peng.fan@xxxxxxx>
---
drivers/base/regmap/regmap.c | 138 +++++++++++++++++++++++++------------------
1 file changed, 79 insertions(+), 59 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index c123bae8bd66..aca63b0d03e0 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -673,53 +673,33 @@ enum regmap_endian regmap_get_val_endian(struct device *dev,
}
EXPORT_SYMBOL_GPL(regmap_get_val_endian);

-struct regmap *__regmap_init(struct device *dev,
- const struct regmap_bus *bus,
- void *bus_context,
- const struct regmap_config *config,
- struct lock_class_key *lock_key,
- const char *lock_name)
+/*
+ * Select the locking scheme for the map. The fast_io argument tells whether
+ * the map has to be usable from atomic context.
+ */
+static int regmap_set_lock(struct regmap *map, const struct regmap_config *config,
+ bool fast_io, struct lock_class_key *lock_key,
+ const char *lock_name)
{
- struct regmap *map;
- enum regmap_endian reg_endian, val_endian;
- bool fast_io;
- int i, j;
- int ret;
-
- if (!config) {
- ret = -EINVAL;
- goto err;
- }
-
- map = kzalloc_obj(*map);
- if (map == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- ret = regmap_set_name(map, config);
- if (ret)
- goto err_map;
-
- ret = -EINVAL; /* Later error paths rely on this */
-
- fast_io = (bus && bus->fast_io) || config->fast_io;
-
if (config->disable_locking) {
map->lock = map->unlock = regmap_lock_unlock_none;
map->can_sleep = config->can_sleep;
regmap_debugfs_disable(map);
- } else if (config->lock && config->unlock) {
+ return 0;
+ }
+
+ if (config->lock && config->unlock) {
map->lock = config->lock;
map->unlock = config->unlock;
map->lock_arg = config->lock_arg;
map->can_sleep = config->can_sleep;
- } else if (config->use_hwlock) {
+ return 0;
+ }
+
+ if (config->use_hwlock) {
map->hwlock = hwspin_lock_request_specific(config->hwlock_id);
- if (!map->hwlock) {
- ret = -ENXIO;
- goto err_name;
- }
+ if (!map->hwlock)
+ return -ENXIO;

switch (config->hwlock_mode) {
case HWLOCK_IRQSTATE:
@@ -737,33 +717,73 @@ struct regmap *__regmap_init(struct device *dev,
}

map->lock_arg = map;
- } else {
- if (fast_io) {
- if (config->use_raw_spinlock) {
- raw_spin_lock_init(&map->raw_spinlock);
- map->lock = regmap_lock_raw_spinlock;
- map->unlock = regmap_unlock_raw_spinlock;
- lockdep_set_class_and_name(&map->raw_spinlock,
- lock_key, lock_name);
- } 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);
- }
+ return 0;
+ }
+
+ if (fast_io) {
+ if (config->use_raw_spinlock) {
+ raw_spin_lock_init(&map->raw_spinlock);
+ map->lock = regmap_lock_raw_spinlock;
+ map->unlock = regmap_unlock_raw_spinlock;
+ lockdep_set_class_and_name(&map->raw_spinlock,
+ lock_key, lock_name);
} else {
- mutex_init(&map->mutex);
- map->lock = regmap_lock_mutex;
- map->unlock = regmap_unlock_mutex;
- map->can_sleep = true;
- lockdep_set_class_and_name(&map->mutex,
+ 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);
}
- map->lock_arg = map;
- map->lock_key = lock_key;
+ } else {
+ mutex_init(&map->mutex);
+ map->lock = regmap_lock_mutex;
+ map->unlock = regmap_unlock_mutex;
+ map->can_sleep = true;
+ lockdep_set_class_and_name(&map->mutex, lock_key, lock_name);
}

+ map->lock_arg = map;
+ map->lock_key = lock_key;
+
+ return 0;
+}
+
+struct regmap *__regmap_init(struct device *dev,
+ const struct regmap_bus *bus,
+ void *bus_context,
+ const struct regmap_config *config,
+ struct lock_class_key *lock_key,
+ const char *lock_name)
+{
+ struct regmap *map;
+ enum regmap_endian reg_endian, val_endian;
+ bool fast_io;
+ int i, j;
+ int ret;
+
+ if (!config) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ map = kzalloc_obj(*map);
+ if (map == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = regmap_set_name(map, config);
+ if (ret)
+ goto err_map;
+
+ fast_io = (bus && bus->fast_io) || config->fast_io;
+
+ ret = regmap_set_lock(map, config, fast_io, lock_key, lock_name);
+ if (ret)
+ goto err_name;
+
+ ret = -EINVAL; /* Later error paths rely on this */
+
/*
* When we write in fast-paths with regmap_bulk_write() don't allocate
* scratch buffers with sleeping allocations.

--
2.56.0