Commit e069034b authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-macb-fix-two-lock-warnings-when-wol-is-used'

Kevin Hao says:

====================
net: macb: Fix two lock warnings when WOL is used

This patch series addresses two lock warnings that occur when using WOL as a
wakeup source on my AMD ZynqMP board.
====================

Link: https://patch.msgid.link/20260318-macb-irq-v2-0-f1179768ab24@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7c770dad baa35a69
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -5776,9 +5776,9 @@ static int __maybe_unused macb_suspend(struct device *dev)
	struct macb_queue *queue;
	struct in_device *idev;
	unsigned long flags;
	u32 tmp, ifa_local;
	unsigned int q;
	int err;
	u32 tmp;

	if (!device_may_wakeup(&bp->dev->dev))
		phy_exit(bp->phy);
@@ -5787,14 +5787,21 @@ static int __maybe_unused macb_suspend(struct device *dev)
		return 0;

	if (bp->wol & MACB_WOL_ENABLED) {
		if (bp->wolopts & WAKE_ARP) {
			/* Check for IP address in WOL ARP mode */
			rcu_read_lock();
			idev = __in_dev_get_rcu(bp->dev);
			if (idev)
				ifa = rcu_dereference(idev->ifa_list);
		if ((bp->wolopts & WAKE_ARP) && !ifa) {
			if (!ifa) {
				rcu_read_unlock();
				netdev_err(netdev, "IP address not assigned as required by WoL walk ARP\n");
				return -EOPNOTSUPP;
			}
			ifa_local = be32_to_cpu(ifa->ifa_local);
			rcu_read_unlock();
		}

		spin_lock_irqsave(&bp->lock, flags);

		/* Disable Tx and Rx engines before  disabling the queues,
@@ -5833,8 +5840,9 @@ static int __maybe_unused macb_suspend(struct device *dev)
		if (bp->wolopts & WAKE_ARP) {
			tmp |= MACB_BIT(ARP);
			/* write IP address into register */
			tmp |= MACB_BFEXT(IP, be32_to_cpu(ifa->ifa_local));
			tmp |= MACB_BFEXT(IP, ifa_local);
		}
		spin_unlock_irqrestore(&bp->lock, flags);

		/* Change interrupt handler and
		 * Enable WoL IRQ on queue 0
@@ -5847,11 +5855,12 @@ static int __maybe_unused macb_suspend(struct device *dev)
				dev_err(dev,
					"Unable to request IRQ %d (error %d)\n",
					bp->queues[0].irq, err);
				spin_unlock_irqrestore(&bp->lock, flags);
				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);
@@ -5859,13 +5868,13 @@ static int __maybe_unused macb_suspend(struct device *dev)
				dev_err(dev,
					"Unable to request IRQ %d (error %d)\n",
					bp->queues[0].irq, err);
				spin_unlock_irqrestore(&bp->lock, flags);
				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);
		}

		enable_irq_wake(bp->queues[0].irq);
	}
@@ -5932,6 +5941,8 @@ static int __maybe_unused macb_resume(struct device *dev)
		queue_readl(bp->queues, ISR);
		if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
			queue_writel(bp->queues, ISR, -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,
@@ -5940,10 +5951,8 @@ static int __maybe_unused macb_resume(struct device *dev)
			dev_err(dev,
				"Unable to request IRQ %d (error %d)\n",
				bp->queues[0].irq, err);
			spin_unlock_irqrestore(&bp->lock, flags);
			return err;
		}
		spin_unlock_irqrestore(&bp->lock, flags);

		disable_irq_wake(bp->queues[0].irq);