Skip to content

Commit 5603cdc

Browse files
committed
regmap: irq: Avoid lockdep warnings with nested regmap-irq chips
JIRA: https://issues.redhat.com/browse/RHEL-109251 commit 76b6e14 Author: Mark Brown <broonie@kernel.org> Date: Fri, 01 Aug 2025 13:37:07 +0000 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) <rmk+kernel@armlinux.org.uk> Tested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://patch.msgid.link/20250731-regmap-irq-nesting-v1-2-98b4d1bf20f0@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
1 parent dd57cd5 commit 5603cdc

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

drivers/base/regmap/regmap-irq.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
struct regmap_irq_chip_data {
2121
struct mutex lock;
22+
struct lock_class_key lock_key;
2223
struct irq_chip irq_chip;
2324

2425
struct regmap *map;
@@ -752,7 +753,13 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
752753
goto err_alloc;
753754
}
754755

755-
mutex_init(&d->lock);
756+
/*
757+
* If one regmap-irq is the parent of another then we'll try
758+
* to lock the child with the parent locked, use an explicit
759+
* lock_key so lockdep can figure out what's going on.
760+
*/
761+
lockdep_register_key(&d->lock_key);
762+
mutex_init_with_key(&d->lock, &d->lock_key);
756763

757764
for (i = 0; i < chip->num_irqs; i++)
758765
d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride]
@@ -887,6 +894,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
887894
/* Should really dispose of the domain but... */
888895
err_mutex:
889896
mutex_destroy(&d->lock);
897+
lockdep_unregister_key(&d->lock_key);
890898
err_alloc:
891899
kfree(d->type_buf);
892900
kfree(d->type_buf_def);
@@ -978,6 +986,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
978986
kfree(d->config_buf);
979987
}
980988
mutex_destroy(&d->lock);
989+
lockdep_unregister_key(&d->lock_key);
981990
kfree(d);
982991
}
983992
EXPORT_SYMBOL_GPL(regmap_del_irq_chip);

0 commit comments

Comments
 (0)