diff options
author | Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com> | 2021-04-23 18:00:50 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-04-23 14:13:16 -0700 |
commit | b2f0ca00e6b34bd57c9298a869ea133699e8ec39 (patch) | |
tree | bed3e70b1380bbf25cad130f991ecc156eb1b402 /drivers/net/phy/nxp-c45-tja11xx.c | |
parent | cbbd21a47f83023665dff171a696d2af70c6e51e (diff) |
phy: nxp-c45-tja11xx: add interrupt support
Added .config_intr and .handle_interrupt callbacks.
Link event interrupt will trigger an interrupt every time when the link
goes up or down.
Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/nxp-c45-tja11xx.c')
-rw-r--r-- | drivers/net/phy/nxp-c45-tja11xx.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c index 95307097ebff..26b9c0d7cb9d 100644 --- a/drivers/net/phy/nxp-c45-tja11xx.c +++ b/drivers/net/phy/nxp-c45-tja11xx.c @@ -28,6 +28,11 @@ #define DEVICE_CONTROL_CONFIG_GLOBAL_EN BIT(14) #define DEVICE_CONTROL_CONFIG_ALL_EN BIT(13) +#define VEND1_PHY_IRQ_ACK 0x80A0 +#define VEND1_PHY_IRQ_EN 0x80A1 +#define VEND1_PHY_IRQ_STATUS 0x80A2 +#define PHY_IRQ_LINK_EVENT BIT(1) + #define VEND1_PHY_CONTROL 0x8100 #define PHY_CONFIG_EN BIT(14) #define PHY_START_OP BIT(0) @@ -188,6 +193,32 @@ static int nxp_c45_start_op(struct phy_device *phydev) PHY_START_OP); } +static int nxp_c45_config_intr(struct phy_device *phydev) +{ + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, + VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT); + else + return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, + VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT); +} + +static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev) +{ + irqreturn_t ret = IRQ_NONE; + int irq; + + irq = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_IRQ_STATUS); + if (irq & PHY_IRQ_LINK_EVENT) { + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_IRQ_ACK, + PHY_IRQ_LINK_EVENT); + phy_trigger_machine(phydev); + ret = IRQ_HANDLED; + } + + return ret; +} + static int nxp_c45_soft_reset(struct phy_device *phydev) { int ret; @@ -560,6 +591,8 @@ static struct phy_driver nxp_c45_driver[] = { .soft_reset = nxp_c45_soft_reset, .config_aneg = nxp_c45_config_aneg, .config_init = nxp_c45_config_init, + .config_intr = nxp_c45_config_intr, + .handle_interrupt = nxp_c45_handle_interrupt, .read_status = nxp_c45_read_status, .suspend = genphy_c45_pma_suspend, .resume = genphy_c45_pma_resume, |