Re: [PATCH v2] irqchip/renesas-rzg2l: Fix loss of interrupt

Radu Rendec <[email protected]>
Newsgroups org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Tue, 2026-08-18 at 12:09 +0100, Biju wrote:
> From: Biju Das <[email protected]>
> 
> rzg2l_clear_irq_int() and rzg2l_clear_tint_int() perform a
> read-modify-write on the ISCR/TSCR status registers to clear the bit
> for the interrupt just handled. Since these registers are
> write-0-to-clear per bit, this is racy: if another interrupt's status
> bit gets set between the read and the write, that bit is written back
> as 0 by the software-constructed value, clearing an interrupt that
> hasn't been serviced yet and losing it. This can be reproduced by
> triggering multiple interrupts at once, e.g.:
> 
>   gpioset -c gpiochip0 355=0 353=0 328=0 352=0
> 
> Fix this by writing back only the bit being cleared, with all other
> bits set to 1, instead of read-modify-writing the whole register.
> Since 1-bits are left unchanged by hardware, concurrently-set status
> bits for other interrupts are preserved.
> 
> Fixes: 3fed09559cd8 ("irqchip: Add RZ/G2L IA55 Interrupt Controller driver")
> Signed-off-by: Biju Das <[email protected]>
> ---
> v1->v2:
>  * Updated the commit description.
> ---
>  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.

Reviewed-by: Radu Rendec <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.