diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 36c8950dbd2d..cabbe227bb98 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -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); diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h index 07ee0f84a46c..a27604f99ed0 100644 --- a/include/linux/u64_stats_sync.h +++ b/include/linux/u64_stats_sync.h @@ -112,20 +112,6 @@ u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp, #endif } -static inline void u64_stats_update_begin_raw(struct u64_stats_sync *syncp) -{ -#if BITS_PER_LONG==32 && defined(CONFIG_SMP) - raw_write_seqcount_begin(&syncp->seq); -#endif -} - -static inline void u64_stats_update_end_raw(struct u64_stats_sync *syncp) -{ -#if BITS_PER_LONG==32 && defined(CONFIG_SMP) - raw_write_seqcount_end(&syncp->seq); -#endif -} - static inline unsigned int __u64_stats_fetch_begin(const struct u64_stats_sync *syncp) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP)