Merge tag 'mlx5-updates-2018-05-17' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / 3com / 3c59x.c
index 36c8950dbd2d80699f396f217f0f438479f68355..cabbe227bb9864f0c0c32b52b62e02a3495c70f5 100644 (file)
@@ -765,8 +765,9 @@ static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb,
                                        struct net_device *dev);
 static int vortex_rx(struct net_device *dev);
 static int boomerang_rx(struct net_device *dev);
-static irqreturn_t vortex_interrupt(int irq, void *dev_id);
-static irqreturn_t boomerang_interrupt(int irq, void *dev_id);
+static irqreturn_t vortex_boomerang_interrupt(int irq, void *dev_id);
+static irqreturn_t _vortex_interrupt(int irq, struct net_device *dev);
+static irqreturn_t _boomerang_interrupt(int irq, struct net_device *dev);
 static int vortex_close(struct net_device *dev);
 static void dump_tx_ring(struct net_device *dev);
 static void update_stats(void __iomem *ioaddr, struct net_device *dev);
@@ -838,11 +839,7 @@ MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_vortex(struct net_device *dev)
 {
-       struct vortex_private *vp = netdev_priv(dev);
-       unsigned long flags;
-       local_irq_save(flags);
-       (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev);
-       local_irq_restore(flags);
+       vortex_boomerang_interrupt(dev->irq, dev);
 }
 #endif
 
@@ -1729,8 +1726,7 @@ vortex_open(struct net_device *dev)
        dma_addr_t dma;
 
        /* Use the now-standard shared IRQ implementation. */
-       if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
-                               boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
+       if ((retval = request_irq(dev->irq, vortex_boomerang_interrupt, IRQF_SHARED, dev->name, dev))) {
                pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
                goto err;
        }
@@ -1905,18 +1901,7 @@ static void vortex_tx_timeout(struct net_device *dev)
                pr_err("%s: Interrupt posted but not delivered --"
                           " IRQ blocked by another device?\n", dev->name);
                /* Bad idea here.. but we might as well handle a few events. */
-               {
-                       /*
-                        * Block interrupts because vortex_interrupt does a bare spin_lock()
-                        */
-                       unsigned long flags;
-                       local_irq_save(flags);
-                       if (vp->full_bus_master_tx)
-                               boomerang_interrupt(dev->irq, dev);
-                       else
-                               vortex_interrupt(dev->irq, dev);
-                       local_irq_restore(flags);
-               }
+               vortex_boomerang_interrupt(dev->irq, dev);
        }
 
        if (vortex_debug > 0)
@@ -2267,9 +2252,8 @@ out_dma_err:
  */
 
 static irqreturn_t
-vortex_interrupt(int irq, void *dev_id)
+_vortex_interrupt(int irq, struct net_device *dev)
 {
-       struct net_device *dev = dev_id;
        struct vortex_private *vp = netdev_priv(dev);
        void __iomem *ioaddr;
        int status;
@@ -2278,7 +2262,6 @@ vortex_interrupt(int irq, void *dev_id)
        unsigned int bytes_compl = 0, pkts_compl = 0;
 
        ioaddr = vp->ioaddr;
-       spin_lock(&vp->lock);
 
        status = ioread16(ioaddr + EL3_STATUS);
 
@@ -2376,7 +2359,6 @@ vortex_interrupt(int irq, void *dev_id)
                pr_debug("%s: exiting interrupt, status %4.4x.\n",
                           dev->name, status);
 handler_exit:
-       spin_unlock(&vp->lock);
        return IRQ_RETVAL(handled);
 }
 
@@ -2386,9 +2368,8 @@ handler_exit:
  */
 
 static irqreturn_t
-boomerang_interrupt(int irq, void *dev_id)
+_boomerang_interrupt(int irq, struct net_device *dev)
 {
-       struct net_device *dev = dev_id;
        struct vortex_private *vp = netdev_priv(dev);
        void __iomem *ioaddr;
        int status;
@@ -2398,12 +2379,6 @@ boomerang_interrupt(int irq, void *dev_id)
 
        ioaddr = vp->ioaddr;
 
-
-       /*
-        * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
-        * and boomerang_start_xmit
-        */
-       spin_lock(&vp->lock);
        vp->handling_irq = 1;
 
        status = ioread16(ioaddr + EL3_STATUS);
@@ -2522,10 +2497,29 @@ boomerang_interrupt(int irq, void *dev_id)
                           dev->name, status);
 handler_exit:
        vp->handling_irq = 0;
-       spin_unlock(&vp->lock);
        return IRQ_RETVAL(handled);
 }
 
+static irqreturn_t
+vortex_boomerang_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct vortex_private *vp = netdev_priv(dev);
+       unsigned long flags;
+       irqreturn_t ret;
+
+       spin_lock_irqsave(&vp->lock, flags);
+
+       if (vp->full_bus_master_rx)
+               ret = _boomerang_interrupt(dev->irq, dev);
+       else
+               ret = _vortex_interrupt(dev->irq, dev);
+
+       spin_unlock_irqrestore(&vp->lock, flags);
+
+       return ret;
+}
+
 static int vortex_rx(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);