diff options
| author | Marc Kleine-Budde <mkl@pengutronix.de> | 2025-11-16 16:55:26 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-12-07 06:08:23 +0900 |
| commit | 6dfc11c4df38a218e77684b1e72c4f7252069d6a (patch) | |
| tree | e6bcf23f4a52dceaa6171341ad782bf1bc604180 | |
| parent | 259192ecbe93453eaa0e4fafab056c1bb91afbf4 (diff) | |
can: sun4i_can: sun4i_can_interrupt(): fix max irq loop handling
commit 76544beea7cfe5bcce6d60f53811657b88ec8be1 upstream.
Reading the interrupt register `SUN4I_REG_INT_ADDR` causes all of its bits
to be reset. If we ever reach the condition of handling more than
`SUN4I_CAN_MAX_IRQ` IRQs, we will have read the register and reset all its
bits but without actually handling the interrupt inside of the loop body.
This may, among other issues, cause us to never `netif_wake_queue()` again
after a transmission interrupt.
Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
Cc: stable@vger.kernel.org
Co-developed-by: Thomas Mühlbacher <tmuehlbacher@posteo.net>
Signed-off-by: Thomas Mühlbacher <tmuehlbacher@posteo.net>
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Link: https://patch.msgid.link/20251116-sun4i-fix-loop-v1-1-3d76d3f81950@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/net/can/sun4i_can.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index 1f2402f02774..f1f0121fba4c 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -644,8 +644,8 @@ static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id) u8 isrc, status; int n = 0; - while ((isrc = readl(priv->base + SUN4I_REG_INT_ADDR)) && - (n < SUN4I_CAN_MAX_IRQ)) { + while ((n < SUN4I_CAN_MAX_IRQ) && + (isrc = readl(priv->base + SUN4I_REG_INT_ADDR))) { n++; status = readl(priv->base + SUN4I_REG_STA_ADDR); |
