diff mbox series

[v1] irqchip/meson-gpio: replace 'spinlock_t' with 'raw_spinlock_t'

Message ID 20240729131850.3015508-1-avkrasnov@salutedevices.com (mailing list archive)
State New, archived
Headers show
Series [v1] irqchip/meson-gpio: replace 'spinlock_t' with 'raw_spinlock_t' | expand

Commit Message

Arseniy Krasnov July 29, 2024, 1:18 p.m. UTC
This lock is acquired under 'lock' of 'struct irq_desc' which has
type 'raw_spinlock_t'. When PREEMPT_RT is enabled, 'spinlock_t'
become preemptible, so we will lock preemptible lock under raw
spinlock. Found by lockdep:

[] =============================
[] [ BUG: Invalid wait context ]
[] 6.9.9-sdkernel #1 Not tainted
[] -----------------------------
[] swapper/0/1 is trying to lock:
[] ffff0000008fed30 (&ctl->lock){....}-{3:3}, at: meson_gpio_irq_update_bits0
[] other info that might help us debug this:
[] context-{5:5}
[] 3 locks held by swapper/0/1:
[]  #0: ffff0000003cd0f8 (&dev->mutex){....}-{4:4}, at: __driver_attach+0x90c
[]  #1: ffff000004714650 (&desc->request_mutex){+.+.}-{4:4}, at: __setup_irq0
[]  #2: ffff0000047144c8 (&irq_desc_lock_class){-.-.}-{2:2}, at: __setup_irq0
[] stack backtrace:
[] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.9.9-sdkernel #1
[] Call trace:
[]  dump_backtrace+0x98/0xf0
[]  show_stack+0x18/0x24
[]  dump_stack_lvl+0x90/0xd0
[]  dump_stack+0x18/0x24
[]  __lock_acquire+0x9dc/0x1f10
[]  lock_acquire.part.0+0xe8/0x228
[]  lock_acquire+0x68/0x84
[]  _raw_spin_lock_irqsave+0x60/0x88
[]  meson_gpio_irq_update_bits+0x34/0x70
[]  meson8_gpio_irq_set_type+0x78/0xc4
[]  meson_gpio_irq_set_type+0x30/0x60
[]  __irq_set_trigger+0x60/0x180
[]  __setup_irq+0x30c/0x6e0
[]  request_threaded_irq+0xec/0x1a4
[]  request_any_context_irq+0x64/0xc4
[]  devm_request_any_context_irq+0x78/0x110
[]  gpio_keys_probe+0x374/0xa6c
[]  platform_probe+0x68/0xc0
[]  really_probe+0xbc/0x2a4
[]  __driver_probe_device+0x78/0x12c
[]  driver_probe_device+0xd8/0x160
[]  __driver_attach+0x9c/0x1ac
[]  bus_for_each_dev+0x78/0xd8
[]  driver_attach+0x24/0x30
[]  bus_add_driver+0xe4/0x208
[]  driver_register+0x60/0x128
[]  __platform_driver_register+0x28/0x34
[]  gpio_keys_init+0x1c/0x28
[]  do_one_initcall+0x88/0x34c
[]  kernel_init_freeable+0x240/0x334
[]  kernel_init+0x20/0x1d8
[]  ret_from_fork+0x10/0x20

Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com>
---
 drivers/irqchip/irq-meson-gpio.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index 9a1791908598d..a4c3b57098ba0 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -178,7 +178,7 @@  struct meson_gpio_irq_controller {
 	void __iomem *base;
 	u32 channel_irqs[MAX_NUM_CHANNEL];
 	DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL);
-	spinlock_t lock;
+	raw_spinlock_t lock;
 };
 
 static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
@@ -187,14 +187,14 @@  static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
 	unsigned long flags;
 	u32 tmp;
 
-	spin_lock_irqsave(&ctl->lock, flags);
+	raw_spin_lock_irqsave(&ctl->lock, flags);
 
 	tmp = readl_relaxed(ctl->base + reg);
 	tmp &= ~mask;
 	tmp |= val;
 	writel_relaxed(tmp, ctl->base + reg);
 
-	spin_unlock_irqrestore(&ctl->lock, flags);
+	raw_spin_unlock_irqrestore(&ctl->lock, flags);
 }
 
 static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
@@ -244,12 +244,12 @@  meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 	unsigned long flags;
 	unsigned int idx;
 
-	spin_lock_irqsave(&ctl->lock, flags);
+	raw_spin_lock_irqsave(&ctl->lock, flags);
 
 	/* Find a free channel */
 	idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
 	if (idx >= ctl->params->nr_channels) {
-		spin_unlock_irqrestore(&ctl->lock, flags);
+		raw_spin_unlock_irqrestore(&ctl->lock, flags);
 		pr_err("No channel available\n");
 		return -ENOSPC;
 	}
@@ -257,7 +257,7 @@  meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 	/* Mark the channel as used */
 	set_bit(idx, ctl->channel_map);
 
-	spin_unlock_irqrestore(&ctl->lock, flags);
+	raw_spin_unlock_irqrestore(&ctl->lock, flags);
 
 	/*
 	 * Setup the mux of the channel to route the signal of the pad
@@ -567,7 +567,7 @@  static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
 	if (!ctl)
 		return -ENOMEM;
 
-	spin_lock_init(&ctl->lock);
+	raw_spin_lock_init(&ctl->lock);
 
 	ctl->base = of_iomap(node, 0);
 	if (!ctl->base) {