Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

pinctrl: renesas: rzt2h: Fix invalid wait context

The rzt2h_gpio_get_direction() function is called from
gpiod_get_direction(), which ends up being used within the __setup_irq()
call stack when requesting an interrupt.

__setup_irq() holds a raw_spinlock_t with IRQs disabled, which creates
an atomic context. spinlock_t cannot be used within atomic context
when PREEMPT_RT is enabled, since it may become a sleeping lock.

An "[ BUG: Invalid wait context ]" splat is observed when running with
CONFIG_PROVE_LOCKING enabled, describing exactly the aforementioned call
stack.

__setup_irq() needs to hold a raw_spinlock_t with IRQs disabled to
serialize access against a concurrent hard interrupt.

Switch to raw_spinlock_t to fix this.

Fixes: 829dde3369a9 ("pinctrl: renesas: rzt2h: Add GPIO IRQ chip to handle interrupts")
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260205103930.666051-1-cosmin-gabriel.tanislav.xa@renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

authored by

Cosmin Tanislav and committed by
Geert Uytterhoeven
ebe7561e e825c79e

+7 -7
+7 -7
drivers/pinctrl/renesas/pinctrl-rzt2h.c
··· 85 85 struct gpio_chip gpio_chip; 86 86 struct pinctrl_gpio_range gpio_range; 87 87 DECLARE_BITMAP(used_irqs, RZT2H_INTERRUPTS_NUM); 88 - spinlock_t lock; /* lock read/write registers */ 88 + raw_spinlock_t lock; /* lock read/write registers */ 89 89 struct mutex mutex; /* serialize adding groups and functions */ 90 90 bool safety_port_enabled; 91 91 atomic_t wakeup_path; ··· 145 145 u64 reg64; 146 146 u16 reg16; 147 147 148 - guard(spinlock_irqsave)(&pctrl->lock); 148 + guard(raw_spinlock_irqsave)(&pctrl->lock); 149 149 150 150 /* Set pin to 'Non-use (Hi-Z input protection)' */ 151 151 reg16 = rzt2h_pinctrl_readw(pctrl, port, PM(port)); ··· 474 474 if (ret) 475 475 return ret; 476 476 477 - guard(spinlock_irqsave)(&pctrl->lock); 477 + guard(raw_spinlock_irqsave)(&pctrl->lock); 478 478 479 479 /* Select GPIO mode in PMC Register */ 480 480 rzt2h_pinctrl_set_gpio_en(pctrl, port, bit, true); ··· 487 487 { 488 488 u16 reg; 489 489 490 - guard(spinlock_irqsave)(&pctrl->lock); 490 + guard(raw_spinlock_irqsave)(&pctrl->lock); 491 491 492 492 reg = rzt2h_pinctrl_readw(pctrl, port, PM(port)); 493 493 reg &= ~PM_PIN_MASK(bit); ··· 509 509 if (ret) 510 510 return ret; 511 511 512 - guard(spinlock_irqsave)(&pctrl->lock); 512 + guard(raw_spinlock_irqsave)(&pctrl->lock); 513 513 514 514 if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) { 515 515 /* ··· 547 547 u8 bit = RZT2H_PIN_ID_TO_PIN(offset); 548 548 u8 reg; 549 549 550 - guard(spinlock_irqsave)(&pctrl->lock); 550 + guard(raw_spinlock_irqsave)(&pctrl->lock); 551 551 552 552 reg = rzt2h_pinctrl_readb(pctrl, port, P(port)); 553 553 if (value) ··· 965 965 if (ret) 966 966 return ret; 967 967 968 - spin_lock_init(&pctrl->lock); 968 + raw_spin_lock_init(&pctrl->lock); 969 969 mutex_init(&pctrl->mutex); 970 970 platform_set_drvdata(pdev, pctrl); 971 971