Commit b3ec7248 authored by Divya Koppera's avatar Divya Koppera Committed by Jakub Kicinski

net: phy: micrel: Adding interrupt support for Link up/Link down in LAN8814 Quad phy

This patch add support for Link up or Link down
interrupt support in LAN8814 Quad phy
Signed-off-by: default avatarDivya Koppera <Divya.Koppera@microchip.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20211221112217.9502-1-Divya.Koppera@microchip.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 294e70c9
......@@ -66,6 +66,19 @@
#define KSZ8081_LMD_SHORT_INDICATOR BIT(12)
#define KSZ8081_LMD_DELTA_TIME_MASK GENMASK(8, 0)
/* Lan8814 general Interrupt control/status reg in GPHY specific block. */
#define LAN8814_INTC 0x18
#define LAN8814_INTS 0x1B
#define LAN8814_INT_LINK_DOWN BIT(2)
#define LAN8814_INT_LINK_UP BIT(0)
#define LAN8814_INT_LINK (LAN8814_INT_LINK_UP |\
LAN8814_INT_LINK_DOWN)
#define LAN8814_INTR_CTRL_REG 0x34
#define LAN8814_INTR_CTRL_REG_POLARITY BIT(1)
#define LAN8814_INTR_CTRL_REG_INTR_ENABLE BIT(0)
/* PHY Control 1 */
#define MII_KSZPHY_CTRL_1 0x1e
#define KSZ8081_CTRL1_MDIX_STAT BIT(4)
......@@ -1620,6 +1633,58 @@ static int lan8804_config_init(struct phy_device *phydev)
return 0;
}
static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
{
int irq_status;
irq_status = phy_read(phydev, LAN8814_INTS);
if (irq_status < 0)
return IRQ_NONE;
if (!(irq_status & LAN8814_INT_LINK))
return IRQ_NONE;
phy_trigger_machine(phydev);
return IRQ_HANDLED;
}
static int lan8814_ack_interrupt(struct phy_device *phydev)
{
/* bit[12..0] int status, which is a read and clear register. */
int rc;
rc = phy_read(phydev, LAN8814_INTS);
return (rc < 0) ? rc : 0;
}
static int lan8814_config_intr(struct phy_device *phydev)
{
int err;
lanphy_write_page_reg(phydev, 4, LAN8814_INTR_CTRL_REG,
LAN8814_INTR_CTRL_REG_POLARITY |
LAN8814_INTR_CTRL_REG_INTR_ENABLE);
/* enable / disable interrupts */
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
err = lan8814_ack_interrupt(phydev);
if (err)
return err;
err = phy_write(phydev, LAN8814_INTC, LAN8814_INT_LINK);
} else {
err = phy_write(phydev, LAN8814_INTC, 0);
if (err)
return err;
err = lan8814_ack_interrupt(phydev);
}
return err;
}
static struct phy_driver ksphy_driver[] = {
{
.phy_id = PHY_ID_KS8737,
......@@ -1802,6 +1867,8 @@ static struct phy_driver ksphy_driver[] = {
.get_stats = kszphy_get_stats,
.suspend = genphy_suspend,
.resume = kszphy_resume,
.config_intr = lan8814_config_intr,
.handle_interrupt = lan8814_handle_interrupt,
}, {
.phy_id = PHY_ID_LAN8804,
.phy_id_mask = MICREL_PHY_ID_MASK,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment