diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2020-03-16 22:32:33 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-03-18 04:58:22 +0100 |
commit | 9010f9deb000edce823cb79345f137742ccffa19 (patch) | |
tree | 52169d22cd01474d5d4e3a4398c981f37847c98f /drivers/net/phy/phy.c | |
parent | Merge branch 'ethtool-consolidate-irq-coalescing-last-part' (diff) | |
download | linux-9010f9deb000edce823cb79345f137742ccffa19.tar.xz linux-9010f9deb000edce823cb79345f137742ccffa19.zip |
net: phy: improve phy_driver callback handle_interrupt
did_interrupt() clears the interrupt, therefore handle_interrupt() can
not check which event triggered the interrupt. To overcome this
constraint and allow more flexibility for customer interrupt handlers,
let's decouple handle_interrupt() from parts of the phylib interrupt
handling. Custom interrupt handlers now have to implement the
did_interrupt() functionality in handle_interrupt() if needed.
Fortunately we have just one custom interrupt handler so far (in the
mscc PHY driver), convert it to the changed API.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/phy.c')
-rw-r--r-- | drivers/net/phy/phy.c | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 355bfdef48d2..d71212a418f3 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -715,26 +715,24 @@ static int phy_disable_interrupts(struct phy_device *phydev) static irqreturn_t phy_interrupt(int irq, void *phy_dat) { struct phy_device *phydev = phy_dat; + struct phy_driver *drv = phydev->drv; - if (phydev->drv->did_interrupt && !phydev->drv->did_interrupt(phydev)) + if (drv->handle_interrupt) + return drv->handle_interrupt(phydev); + + if (drv->did_interrupt && !drv->did_interrupt(phydev)) return IRQ_NONE; - if (phydev->drv->handle_interrupt) { - if (phydev->drv->handle_interrupt(phydev)) - goto phy_err; - } else { - /* reschedule state queue work to run as soon as possible */ - phy_trigger_machine(phydev); - } + /* reschedule state queue work to run as soon as possible */ + phy_trigger_machine(phydev); /* did_interrupt() may have cleared the interrupt already */ - if (!phydev->drv->did_interrupt && phy_clear_interrupt(phydev)) - goto phy_err; - return IRQ_HANDLED; + if (!drv->did_interrupt && phy_clear_interrupt(phydev)) { + phy_error(phydev); + return IRQ_NONE; + } -phy_err: - phy_error(phydev); - return IRQ_NONE; + return IRQ_HANDLED; } /** |