Commit b324c6e5 authored by Horatiu Vultur's avatar Horatiu Vultur Committed by Jakub Kicinski

net: phy: micrel: Add interrupts support for LAN8804 PHY

Add support for interrupts for LAN8804 PHY.

Tested-by: Michael Walle <michael@walle.cc> # on kontron-kswitch-d10
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarHoratiu Vultur <horatiu.vultur@microchip.com>
Link: https://lore.kernel.org/r/20220913142926.816746-1-horatiu.vultur@microchip.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c3188dba
...@@ -2761,6 +2761,66 @@ static int lan8804_config_init(struct phy_device *phydev) ...@@ -2761,6 +2761,66 @@ static int lan8804_config_init(struct phy_device *phydev)
return 0; return 0;
} }
static irqreturn_t lan8804_handle_interrupt(struct phy_device *phydev)
{
int status;
status = phy_read(phydev, LAN8814_INTS);
if (status < 0) {
phy_error(phydev);
return IRQ_NONE;
}
if (status > 0)
phy_trigger_machine(phydev);
return IRQ_HANDLED;
}
#define LAN8804_OUTPUT_CONTROL 25
#define LAN8804_OUTPUT_CONTROL_INTR_BUFFER BIT(14)
#define LAN8804_CONTROL 31
#define LAN8804_CONTROL_INTR_POLARITY BIT(14)
static int lan8804_config_intr(struct phy_device *phydev)
{
int err;
/* This is an internal PHY of lan966x and is not possible to change the
* polarity on the GIC found in lan966x, therefore change the polarity
* of the interrupt in the PHY from being active low instead of active
* high.
*/
phy_write(phydev, LAN8804_CONTROL, LAN8804_CONTROL_INTR_POLARITY);
/* By default interrupt buffer is open-drain in which case the interrupt
* can be active only low. Therefore change the interrupt buffer to be
* push-pull to be able to change interrupt polarity
*/
phy_write(phydev, LAN8804_OUTPUT_CONTROL,
LAN8804_OUTPUT_CONTROL_INTR_BUFFER);
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
err = phy_read(phydev, LAN8814_INTS);
if (err < 0)
return err;
err = phy_write(phydev, LAN8814_INTC, LAN8814_INT_LINK);
if (err)
return err;
} else {
err = phy_write(phydev, LAN8814_INTC, 0);
if (err)
return err;
err = phy_read(phydev, LAN8814_INTS);
if (err < 0)
return err;
}
return 0;
}
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;
...@@ -3225,6 +3285,8 @@ static struct phy_driver ksphy_driver[] = { ...@@ -3225,6 +3285,8 @@ static struct phy_driver ksphy_driver[] = {
.get_stats = kszphy_get_stats, .get_stats = kszphy_get_stats,
.suspend = genphy_suspend, .suspend = genphy_suspend,
.resume = kszphy_resume, .resume = kszphy_resume,
.config_intr = lan8804_config_intr,
.handle_interrupt = lan8804_handle_interrupt,
}, { }, {
.phy_id = PHY_ID_KSZ9131, .phy_id = PHY_ID_KSZ9131,
.phy_id_mask = MICREL_PHY_ID_MASK, .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