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