[PATCH net v8 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus
From: Aleksei Sviridkin
Date: Thu Sep 17 2026 - 22:03:51 EST
The interrupt this driver maps for its PHY is written only into
phydev->irq, while the bus table mdiobus->irq[] keeps reading PHY_POLL
for the same address. That table is where phylib records what the bus
described - phy_device_create() seeds phydev->irq from it - so the
number lives only as long as nothing else writes that one field.
Put it where the bus keeps it and take phydev->irq from there. What the
PHY is attached with does not change.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@xxxxxx>
---
Notes:
Compile-tested only; I have no LAN78xx device.
No Fixes: tag on this one. On its own it fixes nothing - nothing reads the
bus table back until patch 3 - which is also why it sorts ahead of that
patch rather than after it.
The else branch that forced PHY_POLL is dropped rather than moved to the
table, for two reasons. It cannot run: lan78xx_setup_irq_domain() returns
-EINVAL when it cannot create the mapping, lan78xx_bind() gives up on that
return, and lan78xx_phy_init() only runs afterwards, so phyirq is always
positive by the time this code is reached. And if it could run it would be
wrong in the other direction: this bus is registered with
of_mdiobus_register(), so the table may already hold an interrupt the
devicetree described, and forcing PHY_POLL over it would invert what
patches 3 and 4 are for.
Teardown order keeps the number live for as long as it is read:
lan78xx_disconnect() detaches the PHY through phylink_disconnect_phy(), and
lan78xx_unbind() calls lan78xx_remove_irq_domain() only afterwards.
drivers/net/usb/lan78xx.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index cb782d81d84f..d02e4ffcbbc1 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2892,11 +2892,10 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
return 0;
}
- /* if phyirq is not set, use polling mode in phylib */
if (dev->domain_data.phyirq > 0)
- phydev->irq = dev->domain_data.phyirq;
- else
- phydev->irq = PHY_POLL;
+ dev->mdiobus->irq[phydev->mdio.addr] = dev->domain_data.phyirq;
+
+ phydev->irq = dev->mdiobus->irq[phydev->mdio.addr];
netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq);
ret = phylink_connect_phy(dev->phylink, phydev);
--
2.53.0