From dc3bd465ea36af7fd6f9197c05353effc616145c Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Thu, 2 Apr 2026 21:41:22 +0800 Subject: [PATCH 1/4] net: macb: Replace open-coded implementation with napi_schedule() The driver currently duplicates the logic of napi_schedule() primarily to include additional debug information. However, these debug details are not essential for a specific driver and can be effectively obtained through existing tracepoints in the networking core, such as /sys/kernel/tracing/events/napi/napi_poll. Therefore, this patch replaces the open-coded implementation with napi_schedule() to simplify the driver's code. Signed-off-by: Kevin Hao Link: https://patch.msgid.link/20260402-macb-irq-v2-1-942d98ab1154@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/cadence/macb_main.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 7f061d7c95af..8983e2f5b04a 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2120,10 +2120,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) queue_writel(queue, ISR, MACB_BIT(RCOMP)); - if (napi_schedule_prep(&queue->napi_rx)) { - netdev_vdbg(bp->dev, "scheduling RX softirq\n"); - __napi_schedule(&queue->napi_rx); - } + napi_schedule(&queue->napi_rx); } if (status & (MACB_BIT(TCOMP) | @@ -2138,10 +2135,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) wmb(); // ensure softirq can see update } - if (napi_schedule_prep(&queue->napi_tx)) { - netdev_vdbg(bp->dev, "scheduling TX softirq\n"); - __napi_schedule(&queue->napi_tx); - } + napi_schedule(&queue->napi_tx); } if (unlikely(status & (MACB_TX_ERR_FLAGS))) { From 5986ff6e4136105f16d481bd0532b7da2c6344ae Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Thu, 2 Apr 2026 21:41:23 +0800 Subject: [PATCH 2/4] net: macb: Introduce macb_queue_isr_clear() helper function The current implementation includes several occurrences of the following pattern: if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) queue_writel(queue, ISR, value); Introduces a helper function to consolidate these repeated code segments. No functional changes are made. Suggested-by: Jakub Kicinski Signed-off-by: Kevin Hao Link: https://patch.msgid.link/20260402-macb-irq-v2-2-942d98ab1154@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/cadence/macb.h | 7 ++++ drivers/net/ethernet/cadence/macb_main.c | 51 +++++++----------------- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 16527dbab875..2de56017ee0d 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -1474,6 +1474,13 @@ static inline bool macb_dma_ptp(struct macb *bp) bp->caps & MACB_CAPS_DMA_PTP; } +static inline void macb_queue_isr_clear(struct macb *bp, + struct macb_queue *queue, u32 value) +{ + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, value); +} + /** * struct macb_platform_data - platform data for MACB Ethernet used for PCI registration * @pclk: platform clock diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 8983e2f5b04a..248b82af8d3a 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1887,8 +1887,7 @@ static int macb_rx_poll(struct napi_struct *napi, int budget) */ if (macb_rx_pending(queue)) { queue_writel(queue, IDR, bp->rx_intr_mask); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(RCOMP)); + macb_queue_isr_clear(bp, queue, MACB_BIT(RCOMP)); netdev_vdbg(bp->dev, "poll: packets pending, reschedule\n"); napi_schedule(napi); } @@ -1975,8 +1974,7 @@ static int macb_tx_poll(struct napi_struct *napi, int budget) */ if (macb_tx_complete_pending(queue)) { queue_writel(queue, IDR, MACB_BIT(TCOMP)); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(TCOMP)); + macb_queue_isr_clear(bp, queue, MACB_BIT(TCOMP)); netdev_vdbg(bp->dev, "TX poll: packets pending, reschedule\n"); napi_schedule(napi); } @@ -2043,8 +2041,7 @@ static irqreturn_t macb_wol_interrupt(int irq, void *dev_id) netdev_vdbg(bp->dev, "MACB WoL: queue = %u, isr = 0x%08lx\n", (unsigned int)(queue - bp->queues), (unsigned long)status); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(WOL)); + macb_queue_isr_clear(bp, queue, MACB_BIT(WOL)); pm_wakeup_event(&bp->pdev->dev, 0); } @@ -2072,8 +2069,7 @@ static irqreturn_t gem_wol_interrupt(int irq, void *dev_id) netdev_vdbg(bp->dev, "GEM WoL: queue = %u, isr = 0x%08lx\n", (unsigned int)(queue - bp->queues), (unsigned long)status); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, GEM_BIT(WOL)); + macb_queue_isr_clear(bp, queue, GEM_BIT(WOL)); pm_wakeup_event(&bp->pdev->dev, 0); } @@ -2100,8 +2096,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) /* close possible race with dev_close */ if (unlikely(!netif_running(dev))) { queue_writel(queue, IDR, -1); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, -1); + macb_queue_isr_clear(bp, queue, -1); break; } @@ -2117,19 +2112,15 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) * now. */ queue_writel(queue, IDR, bp->rx_intr_mask); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(RCOMP)); - + macb_queue_isr_clear(bp, queue, MACB_BIT(RCOMP)); napi_schedule(&queue->napi_rx); } if (status & (MACB_BIT(TCOMP) | MACB_BIT(TXUBR))) { queue_writel(queue, IDR, MACB_BIT(TCOMP)); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(TCOMP) | - MACB_BIT(TXUBR)); - + macb_queue_isr_clear(bp, queue, MACB_BIT(TCOMP) | + MACB_BIT(TXUBR)); if (status & MACB_BIT(TXUBR)) { queue->txubr_pending = true; wmb(); // ensure softirq can see update @@ -2141,10 +2132,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) if (unlikely(status & (MACB_TX_ERR_FLAGS))) { queue_writel(queue, IDR, MACB_TX_INT_FLAGS); schedule_work(&queue->tx_error_task); - - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_TX_ERR_FLAGS); - + macb_queue_isr_clear(bp, queue, MACB_TX_ERR_FLAGS); break; } @@ -2164,9 +2152,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); wmb(); macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); - - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(RXUBR)); + macb_queue_isr_clear(bp, queue, MACB_BIT(RXUBR)); } if (status & MACB_BIT(ISR_ROVR)) { @@ -2177,17 +2163,13 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) else bp->hw_stats.macb.rx_overruns++; spin_unlock(&bp->stats_lock); - - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(ISR_ROVR)); + macb_queue_isr_clear(bp, queue, MACB_BIT(ISR_ROVR)); } if (status & MACB_BIT(HRESP)) { queue_work(system_bh_wq, &bp->hresp_err_bh_work); netdev_err(dev, "DMA bus error: HRESP not OK\n"); - - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, MACB_BIT(HRESP)); + macb_queue_isr_clear(bp, queue, MACB_BIT(HRESP)); } status = queue_readl(queue, ISR); } @@ -2883,8 +2865,7 @@ static void macb_reset_hw(struct macb *bp) for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { queue_writel(queue, IDR, -1); queue_readl(queue, ISR); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, -1); + macb_queue_isr_clear(bp, queue, -1); } } @@ -6053,8 +6034,7 @@ static int __maybe_unused macb_suspend(struct device *dev) /* Disable all interrupts */ queue_writel(queue, IDR, -1); queue_readl(queue, ISR); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(queue, ISR, -1); + macb_queue_isr_clear(bp, queue, -1); } /* Enable Receive engine */ macb_writel(bp, NCR, tmp | MACB_BIT(RE)); @@ -6165,8 +6145,7 @@ static int __maybe_unused macb_resume(struct device *dev) } /* Clear ISR on queue 0 */ queue_readl(bp->queues, ISR); - if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) - queue_writel(bp->queues, ISR, -1); + macb_queue_isr_clear(bp, bp->queues, -1); spin_unlock_irqrestore(&bp->lock, flags); /* Replace interrupt handler on queue 0 */ From 6d55ce805b267400e682aa335787775bf253e5d8 Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Thu, 2 Apr 2026 21:41:24 +0800 Subject: [PATCH 3/4] net: macb: Factor out the handling of non-hot IRQ events into a separate function In the current code, the IRQ handler checks each IRQ event sequentially. Since most IRQ events are related to TX/RX operations, while other events occur infrequently, this approach introduces unnecessary overhead in the hot path for TX/RX processing. This patch reduces such overhead by extracting the handling of all non-TX/RX events into a new function and consolidating these events under a new flag. As a result, only a single check is required to determine whether any non-TX/RX events have occurred. If such events exist, the handler jumps to the new function. This optimization reduces four conditional checks to one and prevents the instruction cache from being polluted with rarely used code in the hot path. Signed-off-by: Kevin Hao Link: https://patch.msgid.link/20260402-macb-irq-v2-3-942d98ab1154@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/cadence/macb_main.c | 103 ++++++++++++++--------- 1 file changed, 61 insertions(+), 42 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 248b82af8d3a..4fa75e6ed6d6 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -70,6 +70,9 @@ struct sifive_fu540_macb_mgmt { #define MACB_TX_INT_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(TCOMP) \ | MACB_BIT(TXUBR)) +#define MACB_INT_MISC_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(RXUBR) | \ + MACB_BIT(ISR_ROVR) | MACB_BIT(HRESP)) + /* Max length of transmit frame must be a multiple of 8 bytes */ #define MACB_TX_LEN_ALIGN 8 #define MACB_MAX_TX_LEN ((unsigned int)((1 << MACB_TX_FRMLEN_SIZE) - 1) & ~((unsigned int)(MACB_TX_LEN_ALIGN - 1))) @@ -2078,12 +2081,66 @@ static irqreturn_t gem_wol_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static int macb_interrupt_misc(struct macb_queue *queue, u32 status) +{ + struct macb *bp = queue->bp; + struct net_device *dev; + u32 ctrl; + + dev = bp->dev; + + if (unlikely(status & (MACB_TX_ERR_FLAGS))) { + queue_writel(queue, IDR, MACB_TX_INT_FLAGS); + schedule_work(&queue->tx_error_task); + macb_queue_isr_clear(bp, queue, MACB_TX_ERR_FLAGS); + return -1; + } + + /* Link change detection isn't possible with RMII, so we'll + * add that if/when we get our hands on a full-blown MII PHY. + */ + + /* There is a hardware issue under heavy load where DMA can + * stop, this causes endless "used buffer descriptor read" + * interrupts but it can be cleared by re-enabling RX. See + * the at91rm9200 manual, section 41.3.1 or the Zynq manual + * section 16.7.4 for details. RXUBR is only enabled for + * these two versions. + */ + if (status & MACB_BIT(RXUBR)) { + ctrl = macb_readl(bp, NCR); + macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); + wmb(); + macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); + macb_queue_isr_clear(bp, queue, MACB_BIT(RXUBR)); + } + + if (status & MACB_BIT(ISR_ROVR)) { + /* We missed at least one packet */ + spin_lock(&bp->stats_lock); + if (macb_is_gem(bp)) + bp->hw_stats.gem.rx_overruns++; + else + bp->hw_stats.macb.rx_overruns++; + spin_unlock(&bp->stats_lock); + macb_queue_isr_clear(bp, queue, MACB_BIT(ISR_ROVR)); + } + + if (status & MACB_BIT(HRESP)) { + queue_work(system_bh_wq, &bp->hresp_err_bh_work); + netdev_err(dev, "DMA bus error: HRESP not OK\n"); + macb_queue_isr_clear(bp, queue, MACB_BIT(HRESP)); + } + + return 0; +} + static irqreturn_t macb_interrupt(int irq, void *dev_id) { struct macb_queue *queue = dev_id; struct macb *bp = queue->bp; struct net_device *dev = bp->dev; - u32 status, ctrl; + u32 status; status = queue_readl(queue, ISR); @@ -2129,48 +2186,10 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) napi_schedule(&queue->napi_tx); } - if (unlikely(status & (MACB_TX_ERR_FLAGS))) { - queue_writel(queue, IDR, MACB_TX_INT_FLAGS); - schedule_work(&queue->tx_error_task); - macb_queue_isr_clear(bp, queue, MACB_TX_ERR_FLAGS); - break; - } + if (unlikely(status & MACB_INT_MISC_FLAGS)) + if (macb_interrupt_misc(queue, status)) + break; - /* Link change detection isn't possible with RMII, so we'll - * add that if/when we get our hands on a full-blown MII PHY. - */ - - /* There is a hardware issue under heavy load where DMA can - * stop, this causes endless "used buffer descriptor read" - * interrupts but it can be cleared by re-enabling RX. See - * the at91rm9200 manual, section 41.3.1 or the Zynq manual - * section 16.7.4 for details. RXUBR is only enabled for - * these two versions. - */ - if (status & MACB_BIT(RXUBR)) { - ctrl = macb_readl(bp, NCR); - macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); - wmb(); - macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); - macb_queue_isr_clear(bp, queue, MACB_BIT(RXUBR)); - } - - if (status & MACB_BIT(ISR_ROVR)) { - /* We missed at least one packet */ - spin_lock(&bp->stats_lock); - if (macb_is_gem(bp)) - bp->hw_stats.gem.rx_overruns++; - else - bp->hw_stats.macb.rx_overruns++; - spin_unlock(&bp->stats_lock); - macb_queue_isr_clear(bp, queue, MACB_BIT(ISR_ROVR)); - } - - if (status & MACB_BIT(HRESP)) { - queue_work(system_bh_wq, &bp->hresp_err_bh_work); - netdev_err(dev, "DMA bus error: HRESP not OK\n"); - macb_queue_isr_clear(bp, queue, MACB_BIT(HRESP)); - } status = queue_readl(queue, ISR); } From 6637c03f35fa75447d5c2c31db610929cff05813 Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Thu, 2 Apr 2026 21:41:25 +0800 Subject: [PATCH 4/4] net: macb: Remove dedicated IRQ handler for WoL In the current implementation, the suspend/resume path frees the existing IRQ handler and sets up a dedicated WoL IRQ handler, then restores the original handler upon resume. This approach is not used by any other Ethernet driver and unnecessarily complicates the suspend/resume process. After adjusting the IRQ handler in the previous patches, we can now handle WoL interrupts without introducing any overhead in the TX/RX hot path. Therefore, the dedicated WoL IRQ handler is removed. I have verified WoL functionality on my AMD ZynqMP board using the following steps: root@amd-zynqmp:~# ifconfig end0 192.168.3.3 root@amd-zynqmp:~# ethtool -s end0 wol a root@amd-zynqmp:~# echo mem >/sys/power/state Signed-off-by: Kevin Hao Link: https://patch.msgid.link/20260402-macb-irq-v2-4-942d98ab1154@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/cadence/macb_main.c | 112 ++++++----------------- 1 file changed, 27 insertions(+), 85 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 4fa75e6ed6d6..6ec7b110dc72 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -71,7 +71,8 @@ struct sifive_fu540_macb_mgmt { | MACB_BIT(TXUBR)) #define MACB_INT_MISC_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(RXUBR) | \ - MACB_BIT(ISR_ROVR) | MACB_BIT(HRESP)) + MACB_BIT(ISR_ROVR) | MACB_BIT(HRESP) | \ + GEM_BIT(WOL) | MACB_BIT(WOL)) /* Max length of transmit frame must be a multiple of 8 bytes */ #define MACB_TX_LEN_ALIGN 8 @@ -2025,60 +2026,30 @@ static void macb_hresp_error_task(struct work_struct *work) netif_tx_start_all_queues(dev); } -static irqreturn_t macb_wol_interrupt(int irq, void *dev_id) +static void macb_wol_interrupt(struct macb_queue *queue, u32 status) { - struct macb_queue *queue = dev_id; struct macb *bp = queue->bp; - u32 status; - status = queue_readl(queue, ISR); - - if (unlikely(!status)) - return IRQ_NONE; - - spin_lock(&bp->lock); - - if (status & MACB_BIT(WOL)) { - queue_writel(queue, IDR, MACB_BIT(WOL)); - macb_writel(bp, WOL, 0); - netdev_vdbg(bp->dev, "MACB WoL: queue = %u, isr = 0x%08lx\n", - (unsigned int)(queue - bp->queues), - (unsigned long)status); - macb_queue_isr_clear(bp, queue, MACB_BIT(WOL)); - pm_wakeup_event(&bp->pdev->dev, 0); - } - - spin_unlock(&bp->lock); - - return IRQ_HANDLED; + queue_writel(queue, IDR, MACB_BIT(WOL)); + macb_writel(bp, WOL, 0); + netdev_vdbg(bp->dev, "MACB WoL: queue = %u, isr = 0x%08lx\n", + (unsigned int)(queue - bp->queues), + (unsigned long)status); + macb_queue_isr_clear(bp, queue, MACB_BIT(WOL)); + pm_wakeup_event(&bp->pdev->dev, 0); } -static irqreturn_t gem_wol_interrupt(int irq, void *dev_id) +static void gem_wol_interrupt(struct macb_queue *queue, u32 status) { - struct macb_queue *queue = dev_id; struct macb *bp = queue->bp; - u32 status; - status = queue_readl(queue, ISR); - - if (unlikely(!status)) - return IRQ_NONE; - - spin_lock(&bp->lock); - - if (status & GEM_BIT(WOL)) { - queue_writel(queue, IDR, GEM_BIT(WOL)); - gem_writel(bp, WOL, 0); - netdev_vdbg(bp->dev, "GEM WoL: queue = %u, isr = 0x%08lx\n", - (unsigned int)(queue - bp->queues), - (unsigned long)status); - macb_queue_isr_clear(bp, queue, GEM_BIT(WOL)); - pm_wakeup_event(&bp->pdev->dev, 0); - } - - spin_unlock(&bp->lock); - - return IRQ_HANDLED; + queue_writel(queue, IDR, GEM_BIT(WOL)); + gem_writel(bp, WOL, 0); + netdev_vdbg(bp->dev, "GEM WoL: queue = %u, isr = 0x%08lx\n", + (unsigned int)(queue - bp->queues), + (unsigned long)status); + macb_queue_isr_clear(bp, queue, GEM_BIT(WOL)); + pm_wakeup_event(&bp->pdev->dev, 0); } static int macb_interrupt_misc(struct macb_queue *queue, u32 status) @@ -2132,6 +2103,14 @@ static int macb_interrupt_misc(struct macb_queue *queue, u32 status) macb_queue_isr_clear(bp, queue, MACB_BIT(HRESP)); } + if (macb_is_gem(bp)) { + if (status & GEM_BIT(WOL)) + gem_wol_interrupt(queue, status); + } else { + if (status & MACB_BIT(WOL)) + macb_wol_interrupt(queue, status); + } + return 0; } @@ -6004,7 +5983,6 @@ static int __maybe_unused macb_suspend(struct device *dev) unsigned long flags; u32 tmp, ifa_local; unsigned int q; - int err; if (!device_may_wakeup(&bp->dev->dev)) phy_exit(bp->phy); @@ -6067,39 +6045,15 @@ static int __maybe_unused macb_suspend(struct device *dev) /* write IP address into register */ tmp |= MACB_BFEXT(IP, ifa_local); } - spin_unlock_irqrestore(&bp->lock, flags); - /* Change interrupt handler and - * Enable WoL IRQ on queue 0 - */ - devm_free_irq(dev, bp->queues[0].irq, bp->queues); if (macb_is_gem(bp)) { - err = devm_request_irq(dev, bp->queues[0].irq, gem_wol_interrupt, - IRQF_SHARED, netdev->name, bp->queues); - if (err) { - dev_err(dev, - "Unable to request IRQ %d (error %d)\n", - bp->queues[0].irq, err); - return err; - } - spin_lock_irqsave(&bp->lock, flags); queue_writel(bp->queues, IER, GEM_BIT(WOL)); gem_writel(bp, WOL, tmp); - spin_unlock_irqrestore(&bp->lock, flags); } else { - err = devm_request_irq(dev, bp->queues[0].irq, macb_wol_interrupt, - IRQF_SHARED, netdev->name, bp->queues); - if (err) { - dev_err(dev, - "Unable to request IRQ %d (error %d)\n", - bp->queues[0].irq, err); - return err; - } - spin_lock_irqsave(&bp->lock, flags); queue_writel(bp->queues, IER, MACB_BIT(WOL)); macb_writel(bp, WOL, tmp); - spin_unlock_irqrestore(&bp->lock, flags); } + spin_unlock_irqrestore(&bp->lock, flags); enable_irq_wake(bp->queues[0].irq); } @@ -6141,7 +6095,6 @@ static int __maybe_unused macb_resume(struct device *dev) struct macb_queue *queue; unsigned long flags; unsigned int q; - int err; if (!device_may_wakeup(&bp->dev->dev)) phy_init(bp->phy); @@ -6167,17 +6120,6 @@ static int __maybe_unused macb_resume(struct device *dev) macb_queue_isr_clear(bp, bp->queues, -1); spin_unlock_irqrestore(&bp->lock, flags); - /* Replace interrupt handler on queue 0 */ - devm_free_irq(dev, bp->queues[0].irq, bp->queues); - err = devm_request_irq(dev, bp->queues[0].irq, macb_interrupt, - IRQF_SHARED, netdev->name, bp->queues); - if (err) { - dev_err(dev, - "Unable to request IRQ %d (error %d)\n", - bp->queues[0].irq, err); - return err; - } - disable_irq_wake(bp->queues[0].irq); /* Now make sure we disable phy before moving