RE: [PATCH] irqchip/renesas-rzg2l: Fix loss of interrupt
Biju Das <[email protected]>
| Newsgroups | org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <TY3PR01MB1134658D087DDE1106CA0DF2E86DB2@TY3PR01MB11346.jpnprd01.prod.outlook.com> |
Hi All, > -----Original Message----- > From: Biju <[email protected]> > Sent: 13 August 2026 17:48 > Subject: [PATCH] irqchip/renesas-rzg2l: Fix loss of interrupt > > From: Biju Das <[email protected]> > > Read modify write on rzg2l_clear_{tint,irq}_int() is causing loss of interrupts when multiple interrupts > are triggered, for example with: > > gpioset -c gpiochip0 355=0 353=0 328=0 352=0 > > The ISCR/TSCR status registers are write-1-to-clear per bit, so any bit written as 0 is left unchanged by Typo here. Write 0 to clear the status bit and any bit written as 1 is ignored. Hardware manual mentions 1 as "Invalid to write". According to the hardware engineer, "Invalid to write" means that the write operation is invalid. Even if a '1' is written to the target bit of the TSCR/ISCR, the write is ignored, and the interrupt status remains unchanged.( so, it is "No effect".) > hardware. The current code reads the register, clears only the handled bit in software, and writes back > the whole value. If another interrupt's status bit gets set between the read and the write, that set bit > is written back as 1, clearing an interrupt that hasn't been serviced yet, so it gets lost. back as 0 > > Fix this by writing back only the bit being cleared (all other bits as 0) instead of read-modify-writing (all other bits as 1) I will update the commit description in the next version. Cheers, Biju > the whole register, so that concurrently-set status bits for other interrupts are left intact. > > Fixes: 3fed09559cd8 ("irqchip: Add RZ/G2L IA55 Interrupt Controller driver") > Signed-off-by: Biju Das <[email protected]> > --- > drivers/irqchip/irq-renesas-rzg2l.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c > index f6b2e69a2f4e..b3774f82855a 100644 > --- a/drivers/irqchip/irq-renesas-rzg2l.c > +++ b/drivers/irqchip/irq-renesas-rzg2l.c > @@ -161,7 +161,7 @@ static void rzg2l_clear_irq_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq > * falling/rising-edge. > */ > if ((iscr & bit) && (iitsr & IITSR_IITSEL_MASK(hw_irq))) { > - writel_relaxed(iscr & ~bit, priv->base + ISCR); > + writel_relaxed(~bit, priv->base + ISCR); > /* > * Enforce that the posted write is flushed to prevent that the > * just handled interrupt is raised again. > @@ -177,7 +177,7 @@ static void rzg2l_clear_tint_int(struct rzg2l_irqc_priv *priv, unsigned int hwir > > reg = readl_relaxed(priv->base + TSCR); > if (reg & bit) { > - writel_relaxed(reg & ~bit, priv->base + TSCR); > + writel_relaxed(~bit, priv->base + TSCR); > /* > * Enforce that the posted write is flushed to prevent that the > * just handled interrupt is raised again. > -- > 2.43.0 >