* [PATCH 1/2] regmap: irq: Free the regmap-irq mutex
2025-07-31 20:38 [PATCH 0/2] regmap: Fix lockdep warnings for nested regmap-irqs Mark Brown
@ 2025-07-31 20:38 ` Mark Brown
2025-08-01 12:27 ` Russell King (Oracle)
2025-08-01 12:29 ` Russell King (Oracle)
2025-07-31 20:38 ` [PATCH 2/2] regmap: irq: Avoid lockdep warnings with nested regmap-irq chips Mark Brown
2025-08-01 18:14 ` [PATCH 0/2] regmap: Fix lockdep warnings for nested regmap-irqs Mark Brown
2 siblings, 2 replies; 7+ messages in thread
From: Mark Brown @ 2025-07-31 20:38 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Russell King (Oracle), linux-kernel, Mark Brown
We do not currently free the mutex allocated by regmap-irq, do so.
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/base/regmap/regmap-irq.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index d1585f073776..4aac12d38215 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -816,7 +816,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
d->mask_buf[i],
chip->irq_drv_data);
if (ret)
- goto err_alloc;
+ goto err_mutex;
}
if (chip->mask_base && !chip->handle_mask_sync) {
@@ -827,7 +827,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
if (ret) {
dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
reg, ret);
- goto err_alloc;
+ goto err_mutex;
}
}
@@ -838,7 +838,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
if (ret) {
dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
reg, ret);
- goto err_alloc;
+ goto err_mutex;
}
}
@@ -855,7 +855,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
if (ret != 0) {
dev_err(map->dev, "Failed to read IRQ status: %d\n",
ret);
- goto err_alloc;
+ goto err_mutex;
}
}
@@ -879,7 +879,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
if (ret != 0) {
dev_err(map->dev, "Failed to ack 0x%x: %d\n",
reg, ret);
- goto err_alloc;
+ goto err_mutex;
}
}
}
@@ -901,7 +901,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
if (ret != 0) {
dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
reg, ret);
- goto err_alloc;
+ goto err_mutex;
}
}
}
@@ -910,7 +910,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
if (chip->status_is_level) {
ret = read_irq_data(d);
if (ret < 0)
- goto err_alloc;
+ goto err_mutex;
memcpy(d->prev_status_buf, d->status_buf,
array_size(d->chip->num_regs, sizeof(d->prev_status_buf[0])));
@@ -918,7 +918,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
ret = regmap_irq_create_domain(fwnode, irq_base, chip, d);
if (ret)
- goto err_alloc;
+ goto err_mutex;
ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
irq_flags | IRQF_ONESHOT,
@@ -935,6 +935,8 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
err_domain:
/* Should really dispose of the domain but... */
+err_mutex:
+ mutex_destroy(&d->lock);
err_alloc:
kfree(d->type_buf);
kfree(d->type_buf_def);
@@ -1027,6 +1029,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
kfree(d->config_buf[i]);
kfree(d->config_buf);
}
+ mutex_destroy(&d->lock);
kfree(d);
}
EXPORT_SYMBOL_GPL(regmap_del_irq_chip);
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] regmap: irq: Avoid lockdep warnings with nested regmap-irq chips
2025-07-31 20:38 [PATCH 0/2] regmap: Fix lockdep warnings for nested regmap-irqs Mark Brown
2025-07-31 20:38 ` [PATCH 1/2] regmap: irq: Free the regmap-irq mutex Mark Brown
@ 2025-07-31 20:38 ` Mark Brown
2025-08-01 12:28 ` Russell King (Oracle)
2025-08-01 18:14 ` [PATCH 0/2] regmap: Fix lockdep warnings for nested regmap-irqs Mark Brown
2 siblings, 1 reply; 7+ messages in thread
From: Mark Brown @ 2025-07-31 20:38 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich
Cc: Russell King (Oracle), linux-kernel, Mark Brown
While handling interrupts through regmap-irq we use a mutex to protect the
updates we are caching while genirq runs in atomic context. Russell King
reported that while running on the nVidia Jetson Xavier NX this generates
lockdep warnings since that platform has a regmap-irq for the max77686 RTC
which is a child of a max77620 which also uses regmap-irq.
[ 46.723127] rtcwake/3984 is trying to acquire lock:
[ 46.723235] ffff0000813b2c68 (&d->lock){+.+.}-{4:4}, at: regmap_irq_lock+0x18/0x24
[ 46.723452]
but task is already holding lock:
[ 46.723556] ffff00008504dc68 (&d->lock){+.+.}-{4:4}, at: regmap_irq_lock+0x18/0x24
This happens because by default lockdep uses a single lockdep class for all
mutexes initialised from a single mutex_init() call and is unable to tell
that two distinct mutex are being taken and verify that the ordering of
operations is safe. This should be a very rare situation since normally
anything using regmap-irq will be a leaf interrupt controller due to being
on a slow bus like I2C.
We can avoid these warnings by providing the lockdep key for the regmap-irq
explicitly, allocating one for each chip so that lockdep can distinguish
between them.
Thanks to Russell for the report and analysis.
Reported-by: "Russell King (Oracle)" <linux@armlinux.org.uk>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/base/regmap/regmap-irq.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 4aac12d38215..6112d942499b 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -21,6 +21,7 @@
struct regmap_irq_chip_data {
struct mutex lock;
+ struct lock_class_key lock_key;
struct irq_chip irq_chip;
struct regmap *map;
@@ -801,7 +802,13 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
goto err_alloc;
}
- mutex_init(&d->lock);
+ /*
+ * If one regmap-irq is the parent of another then we'll try
+ * to lock the child with the parent locked, use an explicit
+ * lock_key so lockdep can figure out what's going on.
+ */
+ lockdep_register_key(&d->lock_key);
+ mutex_init_with_key(&d->lock, &d->lock_key);
for (i = 0; i < chip->num_irqs; i++)
d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride]
@@ -937,6 +944,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
/* Should really dispose of the domain but... */
err_mutex:
mutex_destroy(&d->lock);
+ lockdep_unregister_key(&d->lock_key);
err_alloc:
kfree(d->type_buf);
kfree(d->type_buf_def);
@@ -1030,6 +1038,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
kfree(d->config_buf);
}
mutex_destroy(&d->lock);
+ lockdep_unregister_key(&d->lock_key);
kfree(d);
}
EXPORT_SYMBOL_GPL(regmap_del_irq_chip);
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] regmap: Fix lockdep warnings for nested regmap-irqs
2025-07-31 20:38 [PATCH 0/2] regmap: Fix lockdep warnings for nested regmap-irqs Mark Brown
2025-07-31 20:38 ` [PATCH 1/2] regmap: irq: Free the regmap-irq mutex Mark Brown
2025-07-31 20:38 ` [PATCH 2/2] regmap: irq: Avoid lockdep warnings with nested regmap-irq chips Mark Brown
@ 2025-08-01 18:14 ` Mark Brown
2 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2025-08-01 18:14 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Mark Brown
Cc: Russell King (Oracle), linux-kernel
On Thu, 31 Jul 2025 21:38:17 +0100, Mark Brown wrote:
> Russell King reported that lockdep warns when it sees nested regmap-irq
> interrupt controllers since it defaults to using a single lock class for
> all mutexes allocated from a single place in the code. We end up with
> both the parent and child regmap-irq locked simultaneously. The second
> patch here uses an explicit lockdep key to disambiguate things for
> regmap, the first adds missing mutex cleanup which I noticed while
> writing that patch.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next
Thanks!
[1/2] regmap: irq: Free the regmap-irq mutex
commit: 1da33858af6250184d2ef907494d698af03283de
[2/2] regmap: irq: Avoid lockdep warnings with nested regmap-irq chips
commit: 76b6e14aa7b081337d118a82397d919b5e072bb4
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 7+ messages in thread