Commit 2002fbac authored by Michael Walle's avatar Michael Walle Committed by Jakub Kicinski

net: phy: micrel: fix shared interrupt on LAN8814

Since commit ece19502 ("net: phy: micrel: 1588 support for LAN8814
phy") the handler always returns IRQ_HANDLED, except in an error case.
Before that commit, the interrupt status register was checked and if
it was empty, IRQ_NONE was returned. Restore that behavior to play nice
with the interrupt line being shared with others.

Fixes: ece19502 ("net: phy: micrel: 1588 support for LAN8814 phy")
Signed-off-by: default avatarMichael Walle <michael@walle.cc>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarHoratiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: default avatarDivya Koppera <Divya.Koppera@microchip.com>
Link: https://lore.kernel.org/r/20220920141619.808117-1-michael@walle.ccSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e738455b
...@@ -2679,16 +2679,19 @@ static int lan8804_config_init(struct phy_device *phydev) ...@@ -2679,16 +2679,19 @@ static int lan8804_config_init(struct phy_device *phydev)
static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev) static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
{ {
int irq_status, tsu_irq_status; int irq_status, tsu_irq_status;
int ret = IRQ_NONE;
irq_status = phy_read(phydev, LAN8814_INTS); irq_status = phy_read(phydev, LAN8814_INTS);
if (irq_status > 0 && (irq_status & LAN8814_INT_LINK))
phy_trigger_machine(phydev);
if (irq_status < 0) { if (irq_status < 0) {
phy_error(phydev); phy_error(phydev);
return IRQ_NONE; return IRQ_NONE;
} }
if (irq_status & LAN8814_INT_LINK) {
phy_trigger_machine(phydev);
ret = IRQ_HANDLED;
}
while (1) { while (1) {
tsu_irq_status = lanphy_read_page_reg(phydev, 4, tsu_irq_status = lanphy_read_page_reg(phydev, 4,
LAN8814_INTR_STS_REG); LAN8814_INTR_STS_REG);
...@@ -2697,12 +2700,15 @@ static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev) ...@@ -2697,12 +2700,15 @@ static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
(tsu_irq_status & (LAN8814_INTR_STS_REG_1588_TSU0_ | (tsu_irq_status & (LAN8814_INTR_STS_REG_1588_TSU0_ |
LAN8814_INTR_STS_REG_1588_TSU1_ | LAN8814_INTR_STS_REG_1588_TSU1_ |
LAN8814_INTR_STS_REG_1588_TSU2_ | LAN8814_INTR_STS_REG_1588_TSU2_ |
LAN8814_INTR_STS_REG_1588_TSU3_))) LAN8814_INTR_STS_REG_1588_TSU3_))) {
lan8814_handle_ptp_interrupt(phydev); lan8814_handle_ptp_interrupt(phydev);
else ret = IRQ_HANDLED;
} else {
break; break;
}
} }
return IRQ_HANDLED;
return ret;
} }
static int lan8814_ack_interrupt(struct phy_device *phydev) static int lan8814_ack_interrupt(struct phy_device *phydev)
......
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