b0b3abf7a6446064bdff75f5acf7200ca92b82c4
[openwrt/staging/wigyori.git] / target / linux / generic / backport-5.10 / 772-v5.14-net-dsa-mt7530-add-interrupt-support.patch
1 From ba751e28d44255744a30190faad0ca09b455c44d Mon Sep 17 00:00:00 2001
2 From: DENG Qingfang <dqfext@gmail.com>
3 Date: Wed, 19 May 2021 11:32:00 +0800
4 Subject: [PATCH] net: dsa: mt7530: add interrupt support
5
6 Add support for MT7530 interrupt controller to handle internal PHYs.
7 In order to assign an IRQ number to each PHY, the registration of MDIO bus
8 is also done in this driver.
9
10 Signed-off-by: DENG Qingfang <dqfext@gmail.com>
11 Reviewed-by: Andrew Lunn <andrew@lunn.ch>
12 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
13 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
14 Signed-off-by: David S. Miller <davem@davemloft.net>
15 ---
16 drivers/net/dsa/Kconfig | 1 +
17 drivers/net/dsa/mt7530.c | 263 +++++++++++++++++++++++++++++++++++----
18 drivers/net/dsa/mt7530.h | 21 +++-
19 3 files changed, 256 insertions(+), 29 deletions(-)
20
21 --- a/drivers/net/dsa/Kconfig
22 +++ b/drivers/net/dsa/Kconfig
23 @@ -36,6 +36,7 @@ config NET_DSA_MT7530
24 tristate "MediaTek MT753x and MT7621 Ethernet switch support"
25 depends on NET_DSA
26 select NET_DSA_TAG_MTK
27 + select MEDIATEK_GE_PHY
28 help
29 This enables support for the MediaTek MT7530, MT7531, and MT7621
30 Ethernet switch chips.
31 --- a/drivers/net/dsa/mt7530.c
32 +++ b/drivers/net/dsa/mt7530.c
33 @@ -10,6 +10,7 @@
34 #include <linux/mfd/syscon.h>
35 #include <linux/module.h>
36 #include <linux/netdevice.h>
37 +#include <linux/of_irq.h>
38 #include <linux/of_mdio.h>
39 #include <linux/of_net.h>
40 #include <linux/of_platform.h>
41 @@ -602,18 +603,14 @@ mt7530_mib_reset(struct dsa_switch *ds)
42 mt7530_write(priv, MT7530_MIB_CCR, CCR_MIB_ACTIVATE);
43 }
44
45 -static int mt7530_phy_read(struct dsa_switch *ds, int port, int regnum)
46 +static int mt7530_phy_read(struct mt7530_priv *priv, int port, int regnum)
47 {
48 - struct mt7530_priv *priv = ds->priv;
49 -
50 return mdiobus_read_nested(priv->bus, port, regnum);
51 }
52
53 -static int mt7530_phy_write(struct dsa_switch *ds, int port, int regnum,
54 +static int mt7530_phy_write(struct mt7530_priv *priv, int port, int regnum,
55 u16 val)
56 {
57 - struct mt7530_priv *priv = ds->priv;
58 -
59 return mdiobus_write_nested(priv->bus, port, regnum, val);
60 }
61
62 @@ -791,9 +788,8 @@ out:
63 }
64
65 static int
66 -mt7531_ind_phy_read(struct dsa_switch *ds, int port, int regnum)
67 +mt7531_ind_phy_read(struct mt7530_priv *priv, int port, int regnum)
68 {
69 - struct mt7530_priv *priv = ds->priv;
70 int devad;
71 int ret;
72
73 @@ -809,10 +805,9 @@ mt7531_ind_phy_read(struct dsa_switch *d
74 }
75
76 static int
77 -mt7531_ind_phy_write(struct dsa_switch *ds, int port, int regnum,
78 +mt7531_ind_phy_write(struct mt7530_priv *priv, int port, int regnum,
79 u16 data)
80 {
81 - struct mt7530_priv *priv = ds->priv;
82 int devad;
83 int ret;
84
85 @@ -828,6 +823,22 @@ mt7531_ind_phy_write(struct dsa_switch *
86 return ret;
87 }
88
89 +static int
90 +mt753x_phy_read(struct mii_bus *bus, int port, int regnum)
91 +{
92 + struct mt7530_priv *priv = bus->priv;
93 +
94 + return priv->info->phy_read(priv, port, regnum);
95 +}
96 +
97 +static int
98 +mt753x_phy_write(struct mii_bus *bus, int port, int regnum, u16 val)
99 +{
100 + struct mt7530_priv *priv = bus->priv;
101 +
102 + return priv->info->phy_write(priv, port, regnum, val);
103 +}
104 +
105 static void
106 mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
107 uint8_t *data)
108 @@ -1991,6 +2002,211 @@ mt7530_setup(struct dsa_switch *ds)
109 return 0;
110 }
111
112 +static irqreturn_t
113 +mt7530_irq_thread_fn(int irq, void *dev_id)
114 +{
115 + struct mt7530_priv *priv = dev_id;
116 + bool handled = false;
117 + u32 val;
118 + int p;
119 +
120 + mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
121 + val = mt7530_mii_read(priv, MT7530_SYS_INT_STS);
122 + mt7530_mii_write(priv, MT7530_SYS_INT_STS, val);
123 + mutex_unlock(&priv->bus->mdio_lock);
124 +
125 + for (p = 0; p < MT7530_NUM_PHYS; p++) {
126 + if (BIT(p) & val) {
127 + unsigned int irq;
128 +
129 + irq = irq_find_mapping(priv->irq_domain, p);
130 + handle_nested_irq(irq);
131 + handled = true;
132 + }
133 + }
134 +
135 + return IRQ_RETVAL(handled);
136 +}
137 +
138 +static void
139 +mt7530_irq_mask(struct irq_data *d)
140 +{
141 + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
142 +
143 + priv->irq_enable &= ~BIT(d->hwirq);
144 +}
145 +
146 +static void
147 +mt7530_irq_unmask(struct irq_data *d)
148 +{
149 + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
150 +
151 + priv->irq_enable |= BIT(d->hwirq);
152 +}
153 +
154 +static void
155 +mt7530_irq_bus_lock(struct irq_data *d)
156 +{
157 + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
158 +
159 + mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
160 +}
161 +
162 +static void
163 +mt7530_irq_bus_sync_unlock(struct irq_data *d)
164 +{
165 + struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
166 +
167 + mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
168 + mutex_unlock(&priv->bus->mdio_lock);
169 +}
170 +
171 +static struct irq_chip mt7530_irq_chip = {
172 + .name = KBUILD_MODNAME,
173 + .irq_mask = mt7530_irq_mask,
174 + .irq_unmask = mt7530_irq_unmask,
175 + .irq_bus_lock = mt7530_irq_bus_lock,
176 + .irq_bus_sync_unlock = mt7530_irq_bus_sync_unlock,
177 +};
178 +
179 +static int
180 +mt7530_irq_map(struct irq_domain *domain, unsigned int irq,
181 + irq_hw_number_t hwirq)
182 +{
183 + irq_set_chip_data(irq, domain->host_data);
184 + irq_set_chip_and_handler(irq, &mt7530_irq_chip, handle_simple_irq);
185 + irq_set_nested_thread(irq, true);
186 + irq_set_noprobe(irq);
187 +
188 + return 0;
189 +}
190 +
191 +static const struct irq_domain_ops mt7530_irq_domain_ops = {
192 + .map = mt7530_irq_map,
193 + .xlate = irq_domain_xlate_onecell,
194 +};
195 +
196 +static void
197 +mt7530_setup_mdio_irq(struct mt7530_priv *priv)
198 +{
199 + struct dsa_switch *ds = priv->ds;
200 + int p;
201 +
202 + for (p = 0; p < MT7530_NUM_PHYS; p++) {
203 + if (BIT(p) & ds->phys_mii_mask) {
204 + unsigned int irq;
205 +
206 + irq = irq_create_mapping(priv->irq_domain, p);
207 + ds->slave_mii_bus->irq[p] = irq;
208 + }
209 + }
210 +}
211 +
212 +static int
213 +mt7530_setup_irq(struct mt7530_priv *priv)
214 +{
215 + struct device *dev = priv->dev;
216 + struct device_node *np = dev->of_node;
217 + int ret;
218 +
219 + if (!of_property_read_bool(np, "interrupt-controller")) {
220 + dev_info(dev, "no interrupt support\n");
221 + return 0;
222 + }
223 +
224 + priv->irq = of_irq_get(np, 0);
225 + if (priv->irq <= 0) {
226 + dev_err(dev, "failed to get parent IRQ: %d\n", priv->irq);
227 + return priv->irq ? : -EINVAL;
228 + }
229 +
230 + priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
231 + &mt7530_irq_domain_ops, priv);
232 + if (!priv->irq_domain) {
233 + dev_err(dev, "failed to create IRQ domain\n");
234 + return -ENOMEM;
235 + }
236 +
237 + /* This register must be set for MT7530 to properly fire interrupts */
238 + if (priv->id != ID_MT7531)
239 + mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL);
240 +
241 + ret = request_threaded_irq(priv->irq, NULL, mt7530_irq_thread_fn,
242 + IRQF_ONESHOT, KBUILD_MODNAME, priv);
243 + if (ret) {
244 + irq_domain_remove(priv->irq_domain);
245 + dev_err(dev, "failed to request IRQ: %d\n", ret);
246 + return ret;
247 + }
248 +
249 + return 0;
250 +}
251 +
252 +static void
253 +mt7530_free_mdio_irq(struct mt7530_priv *priv)
254 +{
255 + int p;
256 +
257 + for (p = 0; p < MT7530_NUM_PHYS; p++) {
258 + if (BIT(p) & priv->ds->phys_mii_mask) {
259 + unsigned int irq;
260 +
261 + irq = irq_find_mapping(priv->irq_domain, p);
262 + irq_dispose_mapping(irq);
263 + }
264 + }
265 +}
266 +
267 +
268 +static void
269 +mt7530_free_irq_common(struct mt7530_priv *priv)
270 +{
271 + free_irq(priv->irq, priv);
272 + irq_domain_remove(priv->irq_domain);
273 +}
274 +
275 +static void
276 +mt7530_free_irq(struct mt7530_priv *priv)
277 +{
278 + mt7530_free_mdio_irq(priv);
279 + mt7530_free_irq_common(priv);
280 +}
281 +
282 +static int
283 +mt7530_setup_mdio(struct mt7530_priv *priv)
284 +{
285 + struct dsa_switch *ds = priv->ds;
286 + struct device *dev = priv->dev;
287 + struct mii_bus *bus;
288 + static int idx;
289 + int ret;
290 +
291 + bus = devm_mdiobus_alloc(dev);
292 + if (!bus)
293 + return -ENOMEM;
294 +
295 + ds->slave_mii_bus = bus;
296 + bus->priv = priv;
297 + bus->name = KBUILD_MODNAME "-mii";
298 + snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d", idx++);
299 + bus->read = mt753x_phy_read;
300 + bus->write = mt753x_phy_write;
301 + bus->parent = dev;
302 + bus->phy_mask = ~ds->phys_mii_mask;
303 +
304 + if (priv->irq)
305 + mt7530_setup_mdio_irq(priv);
306 +
307 + ret = mdiobus_register(bus);
308 + if (ret) {
309 + dev_err(dev, "failed to register MDIO bus: %d\n", ret);
310 + if (priv->irq)
311 + mt7530_free_mdio_irq(priv);
312 + }
313 +
314 + return ret;
315 +}
316 +
317 static int
318 mt7531_setup(struct dsa_switch *ds)
319 {
320 @@ -2798,24 +3014,19 @@ static int
321 mt753x_setup(struct dsa_switch *ds)
322 {
323 struct mt7530_priv *priv = ds->priv;
324 + int ret = priv->info->sw_setup(ds);
325 + if (ret)
326 + return ret;
327
328 - return priv->info->sw_setup(ds);
329 -}
330 -
331 -static int
332 -mt753x_phy_read(struct dsa_switch *ds, int port, int regnum)
333 -{
334 - struct mt7530_priv *priv = ds->priv;
335 -
336 - return priv->info->phy_read(ds, port, regnum);
337 -}
338 + ret = mt7530_setup_irq(priv);
339 + if (ret)
340 + return ret;
341
342 -static int
343 -mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
344 -{
345 - struct mt7530_priv *priv = ds->priv;
346 + ret = mt7530_setup_mdio(priv);
347 + if (ret && priv->irq)
348 + mt7530_free_irq_common(priv);
349
350 - return priv->info->phy_write(ds, port, regnum, val);
351 + return ret;
352 }
353
354 static int mt753x_get_mac_eee(struct dsa_switch *ds, int port,
355 @@ -2852,8 +3063,6 @@ static const struct dsa_switch_ops mt753
356 .get_tag_protocol = mtk_get_tag_protocol,
357 .setup = mt753x_setup,
358 .get_strings = mt7530_get_strings,
359 - .phy_read = mt753x_phy_read,
360 - .phy_write = mt753x_phy_write,
361 .get_ethtool_stats = mt7530_get_ethtool_stats,
362 .get_sset_count = mt7530_get_sset_count,
363 .set_ageing_time = mt7530_set_ageing_time,
364 --- a/drivers/net/dsa/mt7530.h
365 +++ b/drivers/net/dsa/mt7530.h
366 @@ -7,6 +7,7 @@
367 #define __MT7530_H
368
369 #define MT7530_NUM_PORTS 7
370 +#define MT7530_NUM_PHYS 5
371 #define MT7530_CPU_PORT 6
372 #define MT7530_NUM_FDB_RECORDS 2048
373 #define MT7530_ALL_MEMBERS 0xff
374 @@ -401,6 +402,12 @@ enum mt7531_sgmii_force_duplex {
375 #define SYS_CTRL_SW_RST BIT(1)
376 #define SYS_CTRL_REG_RST BIT(0)
377
378 +/* Register for system interrupt */
379 +#define MT7530_SYS_INT_EN 0x7008
380 +
381 +/* Register for system interrupt status */
382 +#define MT7530_SYS_INT_STS 0x700c
383 +
384 /* Register for PHY Indirect Access Control */
385 #define MT7531_PHY_IAC 0x701C
386 #define MT7531_PHY_ACS_ST BIT(31)
387 @@ -722,6 +729,9 @@ static const char *p5_intf_modes(unsigne
388 }
389 }
390
391 +/* Forward declaration */
392 +struct mt7530_priv;
393 +
394 /* struct mt753x_info - This is the main data structure for holding the specific
395 * part for each supported device
396 * @sw_setup: Holding the handler to a device initialization
397 @@ -746,8 +756,8 @@ struct mt753x_info {
398 enum mt753x_id id;
399
400 int (*sw_setup)(struct dsa_switch *ds);
401 - int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
402 - int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
403 + int (*phy_read)(struct mt7530_priv *priv, int port, int regnum);
404 + int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
405 int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
406 int (*cpu_port_config)(struct dsa_switch *ds, int port);
407 bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
408 @@ -781,6 +791,10 @@ struct mt753x_info {
409 * registers
410 * @p6_interface Holding the current port 6 interface
411 * @p5_intf_sel: Holding the current port 5 interface select
412 + *
413 + * @irq: IRQ number of the switch
414 + * @irq_domain: IRQ domain of the switch irq_chip
415 + * @irq_enable: IRQ enable bits, synced to SYS_INT_EN
416 */
417 struct mt7530_priv {
418 struct device *dev;
419 @@ -802,6 +816,9 @@ struct mt7530_priv {
420 struct mt7530_port ports[MT7530_NUM_PORTS];
421 /* protect among processes for registers access*/
422 struct mutex reg_mutex;
423 + int irq;
424 + struct irq_domain *irq_domain;
425 + u32 irq_enable;
426 };
427
428 struct mt7530_hw_vlan_entry {