[PATCH] flexcan: fix flood of irq's after error condition triggered
From: Reuben Dowle <hidden>
Date: 2011-10-12 03:53:03
On my i.MX28 development kit board, I am able to use the flexcan module without problems, until I introduce a bus error by disconnecting the cable. As soon as this is done, the cpu usage goes to 100% percent due to the irq handler being called constantly. It seems this error can be traced to the irq handler not clearing the irq flags. The flexcan driver is enabling several interrupts, but only clearing one of them.
From the user manual:
25.6.8 Error and Status Register (HW_CAN_ESR) This register reflects various error conditions, some general status of the device and it is the source of four interrupts to the ARM. The reported error conditions are those that occurred since the last time the ARM read this register. The ARM read action clears bits. Bits are status bits. Most bits in this register are read-only, except TWRN_INT, RWRN_INT, BOFF_INT, WAK_INT and ERR_INT, which are interrupt flags that can be cleared by writing 1 to them (writing 0 has no effect). This is ambiguous. It says that reading clears the bits, but then says that some of the bits can be cleared by writing 1 to them. In practice it seems that all the ones listed above as being able to be cleared by writing 1 to them MUST be cleared by writing 1 to them. Signed-off-by: Reuben Dowle <redacted> --- drivers/net/can/flexcan.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 1767811..9bcc2e2 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c@@ -553,7 +553,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) reg_iflag1 = readl(®s->iflag1); reg_esr = readl(®s->esr); - writel(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */ + writel(reg_esr & (FLEXCAN_ESR_TWRN_INT|FLEXCAN_ESR_RWRN_INT|FLEXCAN_ESR_BOFF_INT|FLEXCAN_ESR_ERR_INT), ®s->esr); /* ACK err IRQ */ /* * schedule NAPI in case of: