diff options
author | Shaohui Xie <Shaohui.Xie@freescale.com> | 2015-08-21 09:29:29 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-24 08:14:14 +0200 |
commit | 54cf7be992fe86571a3f07b96446cd5334b014ab (patch) | |
tree | 178c7e8ec240dc34696619d9569f11d04db025f1 /drivers/net/phy/aquantia.c | |
parent | Merge tag 'nfc-next-4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s... (diff) | |
download | linux-54cf7be992fe86571a3f07b96446cd5334b014ab.tar.xz linux-54cf7be992fe86571a3f07b96446cd5334b014ab.zip |
net: phy: add interrupt support for aquantia phy
By implementing config_intr & ack_interrupt, now the phy can support
link connect/disconnect interrupt.
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/aquantia.c')
-rw-r--r-- | drivers/net/phy/aquantia.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c index 73d347d7cb04..d6111affbcb6 100644 --- a/drivers/net/phy/aquantia.c +++ b/drivers/net/phy/aquantia.c @@ -44,6 +44,43 @@ static int aquantia_aneg_done(struct phy_device *phydev) return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE); } +static int aquantia_config_intr(struct phy_device *phydev) +{ + int err; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { + err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 1); + if (err < 0) + return err; + + err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 1); + if (err < 0) + return err; + + err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0x1001); + } else { + err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 0); + if (err < 0) + return err; + + err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 0); + if (err < 0) + return err; + + err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0); + } + + return err; +} + +static int aquantia_ack_interrupt(struct phy_device *phydev) +{ + int reg; + + reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xcc01); + return (reg < 0) ? reg : 0; +} + static int aquantia_read_status(struct phy_device *phydev) { int reg; @@ -85,8 +122,11 @@ static struct phy_driver aquantia_driver[] = { .phy_id_mask = 0xfffffff0, .name = "Aquantia AQ1202", .features = PHY_AQUANTIA_FEATURES, + .flags = PHY_HAS_INTERRUPT, .aneg_done = aquantia_aneg_done, .config_aneg = aquantia_config_aneg, + .config_intr = aquantia_config_intr, + .ack_interrupt = aquantia_ack_interrupt, .read_status = aquantia_read_status, .driver = { .owner = THIS_MODULE,}, }, @@ -95,8 +135,11 @@ static struct phy_driver aquantia_driver[] = { .phy_id_mask = 0xfffffff0, .name = "Aquantia AQ2104", .features = PHY_AQUANTIA_FEATURES, + .flags = PHY_HAS_INTERRUPT, .aneg_done = aquantia_aneg_done, .config_aneg = aquantia_config_aneg, + .config_intr = aquantia_config_intr, + .ack_interrupt = aquantia_ack_interrupt, .read_status = aquantia_read_status, .driver = { .owner = THIS_MODULE,}, }, @@ -105,8 +148,11 @@ static struct phy_driver aquantia_driver[] = { .phy_id_mask = 0xfffffff0, .name = "Aquantia AQR105", .features = PHY_AQUANTIA_FEATURES, + .flags = PHY_HAS_INTERRUPT, .aneg_done = aquantia_aneg_done, .config_aneg = aquantia_config_aneg, + .config_intr = aquantia_config_intr, + .ack_interrupt = aquantia_ack_interrupt, .read_status = aquantia_read_status, .driver = { .owner = THIS_MODULE,}, }, @@ -115,8 +161,11 @@ static struct phy_driver aquantia_driver[] = { .phy_id_mask = 0xfffffff0, .name = "Aquantia AQR405", .features = PHY_AQUANTIA_FEATURES, + .flags = PHY_HAS_INTERRUPT, .aneg_done = aquantia_aneg_done, .config_aneg = aquantia_config_aneg, + .config_intr = aquantia_config_intr, + .ack_interrupt = aquantia_ack_interrupt, .read_status = aquantia_read_status, .driver = { .owner = THIS_MODULE,}, }, |