[3.8.y.z extended stable] Patch "can: sja1000: fix {pre, post}_irq() handling and IRQ handler return" has been added to staging queue

Kamal Mostafa kamal at canonical.com
Fri Dec 20 20:21:06 UTC 2013


This is a note to let you know that I have just added a patch titled

    can: sja1000: fix {pre,post}_irq() handling and IRQ handler return

to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue

This patch is scheduled to be released in version 3.8.13.15.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

>From 4fc40d8e76d0c4b2319f4a6ef1baf6a47e8a4f2c Mon Sep 17 00:00:00 2001
From: Oliver Hartkopp <socketcan at hartkopp.net>
Date: Thu, 21 Nov 2013 18:03:07 +0100
Subject: can: sja1000: fix {pre,post}_irq() handling and IRQ handler return
 value

commit 2fea6cd303c0d0cd9067da31d873b6a6d5bd75e7 upstream.

This patch fixes the issue that the sja1000_interrupt() function may have
returned IRQ_NONE without processing the optional pre_irq() and post_irq()
function before. Further the irq processing counter 'n' is moved to the end of
the while statement to return correct IRQ_[NONE|HANDLED] values at error
conditions.

Reported-by: Wolfgang Grandegger <wg at grandegger.com>
Acked-by: Wolfgang Grandegger <wg at grandegger.com>
Signed-off-by: Oliver Hartkopp <socketcan at hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
[ kamal: backport to 3.8 (renamed constant) ]
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
 drivers/net/can/sja1000/sja1000.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 43921f9..8eb5a32 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -490,19 +490,19 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 	uint8_t isrc, status;
 	int n = 0;

+	if (priv->pre_irq)
+		priv->pre_irq(priv);
+
 	/* Shared interrupts and IRQ off? */
 	if (priv->read_reg(priv, REG_IER) == IRQ_OFF)
 		return IRQ_NONE;

-	if (priv->pre_irq)
-		priv->pre_irq(priv);
-
 	while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
-		n++;
+
 		status = priv->read_reg(priv, SJA1000_REG_SR);
 		/* check for absent controller due to hw unplug */
 		if (status == 0xFF && sja1000_is_absent(priv))
-			return IRQ_NONE;
+			goto out;

 		if (isrc & IRQ_WUI)
 			netdev_warn(dev, "wakeup interrupt\n");
@@ -529,7 +529,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 				status = priv->read_reg(priv, SJA1000_REG_SR);
 				/* check for absent controller */
 				if (status == 0xFF && sja1000_is_absent(priv))
-					return IRQ_NONE;
+					goto out;
 			}
 		}
 		if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
@@ -537,8 +537,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 			if (sja1000_err(dev, isrc, status))
 				break;
 		}
+		n++;
 	}
-
+out:
 	if (priv->post_irq)
 		priv->post_irq(priv);

--
1.8.3.2





More information about the kernel-team mailing list