summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiner Kallweit <hkallweit1@gmail.com>2019-05-30 15:10:06 +0200
committerDavid S. Miller <davem@davemloft.net>2019-05-30 15:02:33 -0700
commit49644e68f472c6480e015253fa4d7448c6cfa2aa (patch)
treed47976e1630e2a72dee58c18c2c084dd5ca0bdfc
parent07b0928918c694c845a387cc16256a8b63ced4fc (diff)
net: phy: add callback for custom interrupt handler to struct phy_driver
The phylib interrupt handler handles link change events only currently. However PHY drivers may want to use other interrupt sources too, e.g. to report temperature monitoring events. Therefore add a callback to struct phy_driver allowing PHY drivers to implement a custom interrupt handler. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Suggested-by: Russell King - ARM Linux admin <linux@armlinux.org.uk> Acked-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/phy.c9
-rw-r--r--include/linux/phy.h3
2 files changed, 10 insertions, 2 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 4ba71dc3aee7..c6b0010a6d20 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -772,8 +772,13 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
if (phydev->drv->did_interrupt && !phydev->drv->did_interrupt(phydev))
return IRQ_NONE;
- /* reschedule state queue work to run as soon as possible */
- phy_trigger_machine(phydev);
+ 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);
+ }
if (phy_clear_interrupt(phydev))
goto phy_err;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 72e1196f9799..16cd33915496 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -537,6 +537,9 @@ struct phy_driver {
*/
int (*did_interrupt)(struct phy_device *phydev);
+ /* Override default interrupt handling */
+ int (*handle_interrupt)(struct phy_device *phydev);
+
/* Clears up any memory if needed */
void (*remove)(struct phy_device *phydev);