Skip to content

Commit

Permalink
irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to 'raw_s…
Browse files Browse the repository at this point in the history
…pinlock_t'

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: 215f4cc ("irqchip/meson: Add support for gpio interrupt controller")
Signed-off-by: Arseniy Krasnov <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: https://lore.kernel.org/all/[email protected]
  • Loading branch information
Arseniy Krasnov authored and KAGA-KOKO committed Jul 29, 2024
1 parent a4765eb commit f872d4a
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions drivers/irqchip/irq-meson-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -244,20 +244,20 @@ 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;
}

/* 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
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit f872d4a

Please sign in to comment.