Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / can / sja1000 / sja1000.c
index ebbcfcafe29b7c177a01f59651c6a7803bef42e8..5e10472371eda2db2764e5976b55e58d9f70f044 100644 (file)
@@ -95,11 +95,16 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
        spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
 }
 
+static int sja1000_is_absent(struct sja1000_priv *priv)
+{
+       return (priv->read_reg(priv, REG_MOD) == 0xFF);
+}
+
 static int sja1000_probe_chip(struct net_device *dev)
 {
        struct sja1000_priv *priv = netdev_priv(dev);
 
-       if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
+       if (priv->reg_base && sja1000_is_absent(priv)) {
                printk(KERN_INFO "%s: probing @0x%lX failed\n",
                       DRV_NAME, dev->base_addr);
                return 0;
@@ -492,6 +497,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
        while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
                n++;
                status = priv->read_reg(priv, REG_SR);
+               /* check for absent controller due to hw unplug */
+               if (status == 0xFF && sja1000_is_absent(priv))
+                       return IRQ_NONE;
 
                if (isrc & IRQ_WUI)
                        netdev_warn(dev, "wakeup interrupt\n");
@@ -508,6 +516,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
                        while (status & SR_RBS) {
                                sja1000_rx(dev);
                                status = priv->read_reg(priv, REG_SR);
+                               /* check for absent controller */
+                               if (status == 0xFF && sja1000_is_absent(priv))
+                                       return IRQ_NONE;
                        }
                }
                if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {