]> git.itanic.dy.fi Git - linux-stable/commitdiff
net: phy: allow a phy to opt-out of interrupt handling
authorMichael Walle <michael@walle.cc>
Mon, 9 Jan 2023 12:30:12 +0000 (13:30 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 10 Jan 2023 12:38:37 +0000 (13:38 +0100)
Until now, it is not possible for a PHY driver to disable interrupts
during runtime. If a driver offers the .config_intr() as well as the
.handle_interrupt() ops, it is eligible for interrupt handling.
Introduce a new flag for the dev_flags property of struct phy_device, which
can be set by PHY driver to skip interrupt setup and fall back to polling
mode.

At the moment, this is used for the MaxLinear PHY which has broken
interrupt handling and there is a need to disable interrupts in some
cases.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/phy/phy_device.c
include/linux/phy.h

index 716870a4499c557eb616389739dc17376f0cefe4..e4562859ac001b041f6681190acedf3f97de2b06 100644 (file)
@@ -1487,6 +1487,13 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 
        phydev->interrupts = PHY_INTERRUPT_DISABLED;
 
+       /* PHYs can request to use poll mode even though they have an
+        * associated interrupt line. This could be the case if they
+        * detect a broken interrupt handling.
+        */
+       if (phydev->dev_flags & PHY_F_NO_IRQ)
+               phydev->irq = PHY_POLL;
+
        /* Port is set to PORT_TP by default and the actual PHY driver will set
         * it to different value depending on the PHY configuration. If we have
         * the generic PHY driver we can't figure it out, thus set the old
index 6378c997ded56c9c4c5999a2c45da2c0600614e9..742754d72fc0a6515edb15895bf1a13325ec8caf 100644 (file)
@@ -739,6 +739,9 @@ struct phy_device {
 #endif
 };
 
+/* Generic phy_device::dev_flags */
+#define PHY_F_NO_IRQ           0x80000000
+
 static inline struct phy_device *to_phy_device(const struct device *dev)
 {
        return container_of(to_mdio_device(dev), struct phy_device, mdio);