summaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2023-06-16 15:45:52 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2023-06-22 09:41:32 +0200
commitaf7647a0b4b50c3f988a76b05dea5e6bf20c858a (patch)
tree6dd10147678bce4cfd35d765cdf72050a10c7a41 /drivers/net/can
parentcf8462a8008a0dec9580f939d1b3bd11ab5c3a53 (diff)
downloadlinux-stable-af7647a0b4b50c3f988a76b05dea5e6bf20c858a.tar.gz
linux-stable-af7647a0b4b50c3f988a76b05dea5e6bf20c858a.tar.bz2
linux-stable-af7647a0b4b50c3f988a76b05dea5e6bf20c858a.zip
can: sja1000: Prepare the use of a threaded handler
In order to support a flavor of the sja1000 which sometimes freezes, it will be needed upon certain interrupts to perform a soft reset. The soft reset operation takes a bit of time, so better not do it within the hard interrupt handler but rather in a threaded handler. Let's prepare the possibility for sja1000_err() to request "interrupting" the current flow and request the threaded handler to be run while keeping the interrupt line low. There is no functional change. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/all/20230616134553.2786391-1-miquel.raynal@bootlin.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/sja1000/sja1000.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index aac5956e4a53..4719806e3a9f 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -501,7 +501,8 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
struct sja1000_priv *priv = netdev_priv(dev);
struct net_device_stats *stats = &dev->stats;
uint8_t isrc, status;
- int n = 0;
+ irqreturn_t ret = 0;
+ int n = 0, err;
if (priv->pre_irq)
priv->pre_irq(priv);
@@ -546,19 +547,23 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
}
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
/* error interrupt */
- if (sja1000_err(dev, isrc, status))
+ err = sja1000_err(dev, isrc, status);
+ if (err)
break;
}
n++;
}
out:
+ if (!ret)
+ ret = (n) ? IRQ_HANDLED : IRQ_NONE;
+
if (priv->post_irq)
priv->post_irq(priv);
if (n >= SJA1000_MAX_IRQ)
netdev_dbg(dev, "%d messages handled in ISR", n);
- return (n) ? IRQ_HANDLED : IRQ_NONE;
+ return ret;
}
EXPORT_SYMBOL_GPL(sja1000_interrupt);