net: phy: avoid clearing PHY interrupts twice in irq handler
authorHeiner Kallweit <hkallweit1@gmail.com>
Sun, 1 Mar 2020 20:36:09 +0000 (21:36 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 2 Mar 2020 03:04:19 +0000 (19:04 -0800)
On all PHY drivers that implement did_interrupt() reading the interrupt
status bits clears them. This means we may loose an interrupt that
is triggered between calling did_interrupt() and phy_clear_interrupt().
As part of the fix make it a requirement that did_interrupt() clears
the interrupt.

The Fixes tag refers to the first commit where the patch applies
cleanly.

Fixes: 49644e68f472 ("net: phy: add callback for custom interrupt handler to struct phy_driver")
Reported-by: Michael Walle <michael@walle.cc>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/phy.c
include/linux/phy.h

index d76e038cf2cb5f7972cd0e375f7fab8d93bc13fe..355bfdef48d2b1f6c276e51bab37d3ee995a213e 100644 (file)
@@ -727,7 +727,8 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
                phy_trigger_machine(phydev);
        }
 
-       if (phy_clear_interrupt(phydev))
+       /* did_interrupt() may have cleared the interrupt already */
+       if (!phydev->drv->did_interrupt && phy_clear_interrupt(phydev))
                goto phy_err;
        return IRQ_HANDLED;
 
index c570e162e05e58745d613325b0d93a6bbabf3ace..22f5e763e8941ae7ee6897cef0f674c87f3b33b9 100644 (file)
@@ -557,6 +557,7 @@ struct phy_driver {
        /*
         * Checks if the PHY generated an interrupt.
         * For multi-PHY devices with shared PHY interrupt pin
+        * Set interrupt bits have to be cleared.
         */
        int (*did_interrupt)(struct phy_device *phydev);