diff options
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0065-can-sja1000-fix-isr-hang-when-hw-is-unplugged-under-.patch')
-rw-r--r-- | recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0065-can-sja1000-fix-isr-hang-when-hw-is-unplugged-under-.patch | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0065-can-sja1000-fix-isr-hang-when-hw-is-unplugged-under-.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0065-can-sja1000-fix-isr-hang-when-hw-is-unplugged-under-.patch new file mode 100644 index 00000000..49156d35 --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.9/0065-can-sja1000-fix-isr-hang-when-hw-is-unplugged-under-.patch | |||
@@ -0,0 +1,67 @@ | |||
1 | From 9bda01cc81b40639565e63223d7c5413bb15b99a Mon Sep 17 00:00:00 2001 | ||
2 | From: Oliver Hartkopp <socketcan@hartkopp.net> | ||
3 | Date: Wed, 15 Feb 2012 17:51:56 +0100 | ||
4 | Subject: [PATCH 65/73] can: sja1000: fix isr hang when hw is unplugged under | ||
5 | load | ||
6 | |||
7 | commit a7762b10c12a70c5dbf2253142764b728ac88c3a upstream. | ||
8 | |||
9 | In the case of hotplug enabled devices (PCMCIA/PCIeC) the removal of the | ||
10 | hardware can cause an infinite loop in the common sja1000 isr. | ||
11 | |||
12 | Use the already retrieved status register to indicate a possible hardware | ||
13 | removal and double check by reading the mode register in sja1000_is_absent. | ||
14 | |||
15 | Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> | ||
16 | Acked-by: Wolfgang Grandegger <wg@grandegger.com> | ||
17 | Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> | ||
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
19 | --- | ||
20 | drivers/net/can/sja1000/sja1000.c | 13 ++++++++++++- | ||
21 | 1 files changed, 12 insertions(+), 1 deletions(-) | ||
22 | |||
23 | diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c | ||
24 | index 04a3f1b..192b0d1 100644 | ||
25 | --- a/drivers/net/can/sja1000/sja1000.c | ||
26 | +++ b/drivers/net/can/sja1000/sja1000.c | ||
27 | @@ -95,11 +95,16 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) | ||
28 | spin_unlock_irqrestore(&priv->cmdreg_lock, flags); | ||
29 | } | ||
30 | |||
31 | +static int sja1000_is_absent(struct sja1000_priv *priv) | ||
32 | +{ | ||
33 | + return (priv->read_reg(priv, REG_MOD) == 0xFF); | ||
34 | +} | ||
35 | + | ||
36 | static int sja1000_probe_chip(struct net_device *dev) | ||
37 | { | ||
38 | struct sja1000_priv *priv = netdev_priv(dev); | ||
39 | |||
40 | - if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) { | ||
41 | + if (priv->reg_base && sja1000_is_absent(priv)) { | ||
42 | printk(KERN_INFO "%s: probing @0x%lX failed\n", | ||
43 | DRV_NAME, dev->base_addr); | ||
44 | return 0; | ||
45 | @@ -493,6 +498,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) | ||
46 | while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { | ||
47 | n++; | ||
48 | status = priv->read_reg(priv, REG_SR); | ||
49 | + /* check for absent controller due to hw unplug */ | ||
50 | + if (status == 0xFF && sja1000_is_absent(priv)) | ||
51 | + return IRQ_NONE; | ||
52 | |||
53 | if (isrc & IRQ_WUI) | ||
54 | dev_warn(dev->dev.parent, "wakeup interrupt\n"); | ||
55 | @@ -509,6 +517,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) | ||
56 | while (status & SR_RBS) { | ||
57 | sja1000_rx(dev); | ||
58 | status = priv->read_reg(priv, REG_SR); | ||
59 | + /* check for absent controller */ | ||
60 | + if (status == 0xFF && sja1000_is_absent(priv)) | ||
61 | + return IRQ_NONE; | ||
62 | } | ||
63 | } | ||
64 | if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) { | ||
65 | -- | ||
66 | 1.7.7.4 | ||
67 | |||