net: phy: broadcom: Register dummy IRQ handler
authorFlorian Fainelli <florian.fainelli@broadcom.com>
Thu, 25 May 2023 17:59:15 +0000 (10:59 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 May 2023 11:17:06 +0000 (12:17 +0100)
In order to have our interrupt descriptor fully setup and in particular
the action, ensure that we register a full fledged interrupt handler.
This also allow us to set the interrupt polarity and flow through the
same call.

This is specifically necessary for kernel/irq/pm.c::suspend_device_irq
to set the interrupt descriptor to the IRQD_WAKEUP_ARMED state and
enable the interrupt for wake-up since it was still in a disabled state.

Without an interrupt descriptor we would have ran into cases where the
wake-up interrupt is not capable of waking up the system, specifically
if we resumed the system ACPI S5 using the Ethernet PHY. In that case
the Ethernet PHY interrupt would be pending by the time the kernel
booted, which it would acknowledge but then we could never use it as
a wake-up source again.

Fixes: 8baddaa9d4ba ("net: phy: broadcom: Add support for Wake-on-LAN")
Suggested-by: Doug Berger <doug.berger@broadcom.com>
Debugged-by: Doug Berger <doug.berger@broadcom.com>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/bcm-phy-lib.c
drivers/net/phy/bcm-phy-lib.h
drivers/net/phy/broadcom.c

index 27c57f6ab2112f03c12560c599c7faa8680445cd..5603d0a9ce960b8d1abc73d36874e664577ea444 100644 (file)
@@ -1028,6 +1028,12 @@ void bcm_phy_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
 }
 EXPORT_SYMBOL_GPL(bcm_phy_get_wol);
 
+irqreturn_t bcm_phy_wol_isr(int irq, void *dev_id)
+{
+       return IRQ_HANDLED;
+}
+EXPORT_SYMBOL_GPL(bcm_phy_wol_isr);
+
 MODULE_DESCRIPTION("Broadcom PHY Library");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Broadcom Corporation");
index c6fed43ec913002bf9a26bd1602aae1134499161..2f30ce0cab0e358889a130eac17ff67740f6e1c7 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/brcmphy.h>
 #include <linux/phy.h>
+#include <linux/interrupt.h>
 
 struct ethtool_wolinfo;
 
@@ -115,5 +116,6 @@ static inline void bcm_ptp_stop(struct bcm_ptp_private *priv)
 
 int bcm_phy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
 void bcm_phy_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
+irqreturn_t bcm_phy_wol_isr(int irq, void *dev_id);
 
 #endif /* _LINUX_BCM_PHY_LIB_H */
index 418e6bc0e9981f39fe17edadee428b59a6336df4..822c8b01dc53c0f798e28bf2ed86533accaa9b32 100644 (file)
@@ -927,7 +927,14 @@ static int bcm54xx_phy_probe(struct phy_device *phydev)
 
        if (!IS_ERR(wakeup_gpio)) {
                priv->wake_irq = gpiod_to_irq(wakeup_gpio);
-               ret = irq_set_irq_type(priv->wake_irq, IRQ_TYPE_LEVEL_LOW);
+
+               /* Dummy interrupt handler which is not enabled but is provided
+                * in order for the interrupt descriptor to be fully set-up.
+                */
+               ret = devm_request_irq(&phydev->mdio.dev, priv->wake_irq,
+                                      bcm_phy_wol_isr,
+                                      IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
+                                      dev_name(&phydev->mdio.dev), phydev);
                if (ret)
                        return ret;
        }