From: Oliver Hartkopp <socketcan@hartkopp.net>
To: "linux-can@vger.kernel.org" <linux-can@vger.kernel.org>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Subject: [PATCH v3] can: fix sja1000 pre_irq/post_irq handling
Date: Mon, 18 Nov 2013 14:01:14 +0100 [thread overview]
Message-ID: <528A0F9A.6070305@hartkopp.net> (raw)
The SJA1000 driver provides optional function pointers to handle specific
hardware setups at interrupt time.
This patch fixes the issue that the sja1000_interrupt() function may have
returned IRQ_NONE without processing the post_irq function. Additionally
an introduced and documented return value from the pre_irq function is
checked to skip the entire interrupt handling on pre_irq function errors.
Reported-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
v2: move irq processing counter 'n' to the end of the while statement to
return correct IRQ_[NONE|HANDLED] values at error conditions.
v3: added comments about the pre_irq() return values.
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 7164a99..f7733d6 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -494,20 +494,21 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
uint8_t isrc, status;
int n = 0;
+ /* skip irq handling if the optional pre_irq() returns non-zero */
+ if (priv->pre_irq && priv->pre_irq(priv))
+ goto out;
+
/* Shared interrupts and IRQ off? */
if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
- return IRQ_NONE;
-
- if (priv->pre_irq)
- priv->pre_irq(priv);
+ goto out;
while ((isrc = priv->read_reg(priv, SJA1000_IR)) &&
(n < SJA1000_MAX_IRQ)) {
- n++;
+
status = priv->read_reg(priv, SJA1000_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");
@@ -535,7 +536,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
status = priv->read_reg(priv, SJA1000_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)) {
@@ -543,8 +544,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);
diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h
index 9d46398..d7aaa42 100644
--- a/drivers/net/can/sja1000/sja1000.h
+++ b/drivers/net/can/sja1000/sja1000.h
@@ -157,7 +157,13 @@ struct sja1000_priv {
/* the lower-layer is responsible for appropriate locking */
u8 (*read_reg) (const struct sja1000_priv *priv, int reg);
void (*write_reg) (const struct sja1000_priv *priv, int reg, u8 val);
- void (*pre_irq) (const struct sja1000_priv *priv);
+
+ /*
+ * Hardware specific optional pre_irq() and post_irq() hooks.
+ * When pre_irq() returns a non-zero value the sja1000 irq register
+ * handling is skipped but post_irq() is still called.
+ */
+ int (*pre_irq) (const struct sja1000_priv *priv);
void (*post_irq) (const struct sja1000_priv *priv);
void *priv; /* for board-specific data */
next reply other threads:[~2013-11-18 13:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-18 13:01 Oliver Hartkopp [this message]
2013-11-18 19:38 ` [PATCH v3] can: fix sja1000 pre_irq/post_irq handling Wolfgang Grandegger
2013-11-18 21:15 ` Kurt Van Dijck
2013-11-20 6:33 ` Oliver Hartkopp
2013-11-20 9:28 ` Kurt Van Dijck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=528A0F9A.6070305@hartkopp.net \
--to=socketcan@hartkopp.net \
--cc=linux-can@vger.kernel.org \
--cc=wg@grandegger.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox