diff options
author | Shaohui Xie <Shaohui.Xie@freescale.com> | 2015-08-21 03:29:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-24 02:14:14 -0400 |
commit | 54cf7be992fe86571a3f07b96446cd5334b014ab (patch) | |
tree | 178c7e8ec240dc34696619d9569f11d04db025f1 | |
parent | d9893d1351e11f565940df6cd6f9bf13aac27a3a (diff) |
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>
-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) | |||
44 | return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE); | 44 | return (reg < 0) ? reg : (reg & BMSR_ANEGCOMPLETE); |
45 | } | 45 | } |
46 | 46 | ||
47 | static int aquantia_config_intr(struct phy_device *phydev) | ||
48 | { | ||
49 | int err; | ||
50 | |||
51 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { | ||
52 | err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 1); | ||
53 | if (err < 0) | ||
54 | return err; | ||
55 | |||
56 | err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 1); | ||
57 | if (err < 0) | ||
58 | return err; | ||
59 | |||
60 | err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0x1001); | ||
61 | } else { | ||
62 | err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 0); | ||
63 | if (err < 0) | ||
64 | return err; | ||
65 | |||
66 | err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 0); | ||
67 | if (err < 0) | ||
68 | return err; | ||
69 | |||
70 | err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0); | ||
71 | } | ||
72 | |||
73 | return err; | ||
74 | } | ||
75 | |||
76 | static int aquantia_ack_interrupt(struct phy_device *phydev) | ||
77 | { | ||
78 | int reg; | ||
79 | |||
80 | reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xcc01); | ||
81 | return (reg < 0) ? reg : 0; | ||
82 | } | ||
83 | |||
47 | static int aquantia_read_status(struct phy_device *phydev) | 84 | static int aquantia_read_status(struct phy_device *phydev) |
48 | { | 85 | { |
49 | int reg; | 86 | int reg; |
@@ -85,8 +122,11 @@ static struct phy_driver aquantia_driver[] = { | |||
85 | .phy_id_mask = 0xfffffff0, | 122 | .phy_id_mask = 0xfffffff0, |
86 | .name = "Aquantia AQ1202", | 123 | .name = "Aquantia AQ1202", |
87 | .features = PHY_AQUANTIA_FEATURES, | 124 | .features = PHY_AQUANTIA_FEATURES, |
125 | .flags = PHY_HAS_INTERRUPT, | ||
88 | .aneg_done = aquantia_aneg_done, | 126 | .aneg_done = aquantia_aneg_done, |
89 | .config_aneg = aquantia_config_aneg, | 127 | .config_aneg = aquantia_config_aneg, |
128 | .config_intr = aquantia_config_intr, | ||
129 | .ack_interrupt = aquantia_ack_interrupt, | ||
90 | .read_status = aquantia_read_status, | 130 | .read_status = aquantia_read_status, |
91 | .driver = { .owner = THIS_MODULE,}, | 131 | .driver = { .owner = THIS_MODULE,}, |
92 | }, | 132 | }, |
@@ -95,8 +135,11 @@ static struct phy_driver aquantia_driver[] = { | |||
95 | .phy_id_mask = 0xfffffff0, | 135 | .phy_id_mask = 0xfffffff0, |
96 | .name = "Aquantia AQ2104", | 136 | .name = "Aquantia AQ2104", |
97 | .features = PHY_AQUANTIA_FEATURES, | 137 | .features = PHY_AQUANTIA_FEATURES, |
138 | .flags = PHY_HAS_INTERRUPT, | ||
98 | .aneg_done = aquantia_aneg_done, | 139 | .aneg_done = aquantia_aneg_done, |
99 | .config_aneg = aquantia_config_aneg, | 140 | .config_aneg = aquantia_config_aneg, |
141 | .config_intr = aquantia_config_intr, | ||
142 | .ack_interrupt = aquantia_ack_interrupt, | ||
100 | .read_status = aquantia_read_status, | 143 | .read_status = aquantia_read_status, |
101 | .driver = { .owner = THIS_MODULE,}, | 144 | .driver = { .owner = THIS_MODULE,}, |
102 | }, | 145 | }, |
@@ -105,8 +148,11 @@ static struct phy_driver aquantia_driver[] = { | |||
105 | .phy_id_mask = 0xfffffff0, | 148 | .phy_id_mask = 0xfffffff0, |
106 | .name = "Aquantia AQR105", | 149 | .name = "Aquantia AQR105", |
107 | .features = PHY_AQUANTIA_FEATURES, | 150 | .features = PHY_AQUANTIA_FEATURES, |
151 | .flags = PHY_HAS_INTERRUPT, | ||
108 | .aneg_done = aquantia_aneg_done, | 152 | .aneg_done = aquantia_aneg_done, |
109 | .config_aneg = aquantia_config_aneg, | 153 | .config_aneg = aquantia_config_aneg, |
154 | .config_intr = aquantia_config_intr, | ||
155 | .ack_interrupt = aquantia_ack_interrupt, | ||
110 | .read_status = aquantia_read_status, | 156 | .read_status = aquantia_read_status, |
111 | .driver = { .owner = THIS_MODULE,}, | 157 | .driver = { .owner = THIS_MODULE,}, |
112 | }, | 158 | }, |
@@ -115,8 +161,11 @@ static struct phy_driver aquantia_driver[] = { | |||
115 | .phy_id_mask = 0xfffffff0, | 161 | .phy_id_mask = 0xfffffff0, |
116 | .name = "Aquantia AQR405", | 162 | .name = "Aquantia AQR405", |
117 | .features = PHY_AQUANTIA_FEATURES, | 163 | .features = PHY_AQUANTIA_FEATURES, |
164 | .flags = PHY_HAS_INTERRUPT, | ||
118 | .aneg_done = aquantia_aneg_done, | 165 | .aneg_done = aquantia_aneg_done, |
119 | .config_aneg = aquantia_config_aneg, | 166 | .config_aneg = aquantia_config_aneg, |
167 | .config_intr = aquantia_config_intr, | ||
168 | .ack_interrupt = aquantia_ack_interrupt, | ||
120 | .read_status = aquantia_read_status, | 169 | .read_status = aquantia_read_status, |
121 | .driver = { .owner = THIS_MODULE,}, | 170 | .driver = { .owner = THIS_MODULE,}, |
122 | }, | 171 | }, |