summaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy.c
diff options
context:
space:
mode:
authorHeiner Kallweit <hkallweit1@gmail.com>2020-03-16 22:32:33 +0100
committerDavid S. Miller <davem@davemloft.net>2020-03-18 04:58:22 +0100
commit9010f9deb000edce823cb79345f137742ccffa19 (patch)
tree52169d22cd01474d5d4e3a4398c981f37847c98f /drivers/net/phy/phy.c
parentMerge branch 'ethtool-consolidate-irq-coalescing-last-part' (diff)
downloadlinux-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.c26
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;
}
/**