summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArseniy Krasnov <avkrasnov@salutedevices.com>2024-07-29 16:18:50 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-08-19 05:41:19 +0200
commit227d455e6cec2404fec6b4e3a8c6a37c4120d187 (patch)
treedbd03718a62e0a8b76482137dc1d65242bd3b7dc
parent7dddf560e2381eb3e1d6fcc890cd082dbf255ee1 (diff)
downloadlinux-stable-227d455e6cec2404fec6b4e3a8c6a37c4120d187.tar.gz
linux-stable-227d455e6cec2404fec6b4e3a8c6a37c4120d187.tar.bz2
linux-stable-227d455e6cec2404fec6b4e3a8c6a37c4120d187.zip
irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to 'raw_spinlock_t'
[ Upstream commit f872d4af79fe8c71ae291ce8875b477e1669a6c7 ] This lock is acquired under irq_desc::lock with interrupts disabled. When PREEMPT_RT is enabled, 'spinlock_t' becomes preemptible, which results in invalid lock acquire context; [ BUG: Invalid wait context ] 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: _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 Fixes: 215f4cc0fb20 ("irqchip/meson: Add support for gpio interrupt controller") Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20240729131850.3015508-1-avkrasnov@salutedevices.com Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/irqchip/irq-meson-gpio.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index 89dab14406e6..6a3d18d5ba2f 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -141,7 +141,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,
@@ -150,14 +150,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)
@@ -207,12 +207,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;
}
@@ -220,7 +220,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
@@ -488,7 +488,7 @@ static int __init meson_gpio_irq_of_init(struct device_node *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) {