From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001 From: Jianhui Zhao Date: Sun, 24 Sep 2023 22:15:00 +0800 Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B This commit introduces interrupt support for RTL8221B. Signed-off-by: Jianhui Zhao --- drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -1282,6 +1282,51 @@ static irqreturn_t rtl9000a_handle_inter return IRQ_HANDLED; } +static int rtl8221b_ack_interrupt(struct phy_device *phydev) +{ + int err; + + err = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa4d4); + + return (err < 0) ? err : 0; +} + +static int rtl8221b_config_intr(struct phy_device *phydev) +{ + int err; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { + err = rtl8221b_ack_interrupt(phydev); + if (err) + return err; + + err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff); + } else { + err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0); + if (err) + return err; + + err = rtl8221b_ack_interrupt(phydev); + } + + return err; +} + +static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev) +{ + int err; + + err = rtl8221b_ack_interrupt(phydev); + if (err) { + phy_error(phydev); + return IRQ_NONE; + } + + phy_trigger_machine(phydev); + + return IRQ_HANDLED; +} + static struct phy_driver realtek_drvs[] = { { PHY_ID_MATCH_EXACT(0x00008201), @@ -1448,6 +1493,8 @@ static struct phy_driver realtek_drvs[] }, { .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device, .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)", + .config_intr = rtl8221b_config_intr, + .handle_interrupt = rtl8221b_handle_interrupt, .probe = rtl822x_probe, .soft_reset = genphy_soft_reset, .get_features = rtl822x_get_features, @@ -1462,6 +1509,8 @@ static struct phy_driver realtek_drvs[] }, { .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device, .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)", + .config_intr = rtl8221b_config_intr, + .handle_interrupt = rtl8221b_handle_interrupt, .probe = rtl822x_probe, .soft_reset = genphy_soft_reset, .config_init = rtl822xb_config_init, @@ -1474,6 +1523,8 @@ static struct phy_driver realtek_drvs[] }, { .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device, .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", + .config_intr = rtl8221b_config_intr, + .handle_interrupt = rtl8221b_handle_interrupt, .probe = rtl822x_probe, .soft_reset = genphy_soft_reset, .get_features = rtl822x_get_features, @@ -1488,6 +1539,8 @@ static struct phy_driver realtek_drvs[] }, { .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device, .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)", + .config_intr = rtl8221b_config_intr, + .handle_interrupt = rtl8221b_handle_interrupt, .probe = rtl822x_probe, .soft_reset = genphy_soft_reset, .config_init = rtl822xb_config_init,