can: flexcan: fix irq flooding by clearing all interrupt sources
authorWolfgang Grandegger <wg@grandegger.com>
Mon, 12 Dec 2011 15:09:28 +0000 (16:09 +0100)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 2 Feb 2012 23:24:50 +0000 (00:24 +0100)
As pointed out by Reuben Dowle and Lothar Waßmann, the TWRN_INT,
RWRN_INT, BOFF_INT interrupt sources need to be cleared as well
to avoid interrupt flooding, at least for the Flexcan on i.MX28
SOCs. Furthermore, the interrupts are only cleared, if really one
of those interrupt sources are pending (which is not the case for
rx and tx done).

Cc: Reuben Dowle <Reuben.Dowle@navico.com>
Cc: Lothar Waßmann <LW@KARO-electronics.de>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/flexcan.c

index 7fd8089..96d2357 100644 (file)
        (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT)
 #define FLEXCAN_ESR_ERR_ALL \
        (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE)
+#define FLEXCAN_ESR_ALL_INT \
+       (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
+        FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
 
 /* FLEXCAN interrupt flag register (IFLAG) bits */
 #define FLEXCAN_TX_BUF_ID              8
@@ -577,7 +580,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 
        reg_iflag1 = flexcan_read(&regs->iflag1);
        reg_esr = flexcan_read(&regs->esr);
-       flexcan_write(FLEXCAN_ESR_ERR_INT, &regs->esr); /* ACK err IRQ */
+       /* ACK all bus error and state change IRQ sources */
+       if (reg_esr & FLEXCAN_ESR_ALL_INT)
+               flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
 
        /*
         * schedule NAPI in case of: