]> git.ipfire.org Git - thirdparty/openwrt.git/blob
aa6dfcf7e6f036f98f7f4b59a61e138ad088d5aa
[thirdparty/openwrt.git] /
1 From bce254b839abe67577bebdef0838796af409c229 Mon Sep 17 00:00:00 2001
2 From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
3 Date: Fri, 9 Feb 2024 02:03:39 -0300
4 Subject: net: dsa: realtek: convert variants into real drivers
5
6 Previously, the interface modules realtek-smi and realtek-mdio served as
7 a platform and an MDIO driver, respectively. Each interface module
8 redundantly specified the same compatible strings for both variants and
9 referenced symbols from the variants.
10
11 Now, each variant module has been transformed into a unified driver
12 serving both as a platform and an MDIO driver. This modification
13 reverses the relationship between the interface and variant modules,
14 with the variant module now utilizing symbols from the interface
15 modules.
16
17 Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
18 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
19 Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
20 Signed-off-by: David S. Miller <davem@davemloft.net>
21 ---
22 drivers/net/dsa/realtek/Kconfig | 20 +++----
23 drivers/net/dsa/realtek/realtek-mdio.c | 68 +++++++++++++++---------
24 drivers/net/dsa/realtek/realtek-mdio.h | 48 +++++++++++++++++
25 drivers/net/dsa/realtek/realtek-smi.c | 73 +++++++++++++++-----------
26 drivers/net/dsa/realtek/realtek-smi.h | 48 +++++++++++++++++
27 drivers/net/dsa/realtek/rtl8365mb.c | 54 ++++++++++++++++++-
28 drivers/net/dsa/realtek/rtl8366rb.c | 54 ++++++++++++++++++-
29 7 files changed, 292 insertions(+), 73 deletions(-)
30 create mode 100644 drivers/net/dsa/realtek/realtek-mdio.h
31 create mode 100644 drivers/net/dsa/realtek/realtek-smi.h
32
33 --- a/drivers/net/dsa/realtek/Kconfig
34 +++ b/drivers/net/dsa/realtek/Kconfig
35 @@ -16,37 +16,29 @@ menuconfig NET_DSA_REALTEK
36 if NET_DSA_REALTEK
37
38 config NET_DSA_REALTEK_MDIO
39 - tristate "Realtek MDIO interface driver"
40 + tristate "Realtek MDIO interface support"
41 depends on OF
42 - depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB
43 - depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB
44 - depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB
45 help
46 Select to enable support for registering switches configured
47 through MDIO.
48
49 config NET_DSA_REALTEK_SMI
50 - tristate "Realtek SMI interface driver"
51 + tristate "Realtek SMI interface support"
52 depends on OF
53 - depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB
54 - depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB
55 - depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB
56 help
57 Select to enable support for registering switches connected
58 through SMI.
59
60 config NET_DSA_REALTEK_RTL8365MB
61 - tristate "Realtek RTL8365MB switch subdriver"
62 - imply NET_DSA_REALTEK_SMI
63 - imply NET_DSA_REALTEK_MDIO
64 + tristate "Realtek RTL8365MB switch driver"
65 + depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO
66 select NET_DSA_TAG_RTL8_4
67 help
68 Select to enable support for Realtek RTL8365MB-VC and RTL8367S.
69
70 config NET_DSA_REALTEK_RTL8366RB
71 - tristate "Realtek RTL8366RB switch subdriver"
72 - imply NET_DSA_REALTEK_SMI
73 - imply NET_DSA_REALTEK_MDIO
74 + tristate "Realtek RTL8366RB switch driver"
75 + depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO
76 select NET_DSA_TAG_RTL4_A
77 help
78 Select to enable support for Realtek RTL8366RB.
79 --- a/drivers/net/dsa/realtek/realtek-mdio.c
80 +++ b/drivers/net/dsa/realtek/realtek-mdio.c
81 @@ -25,6 +25,7 @@
82 #include <linux/regmap.h>
83
84 #include "realtek.h"
85 +#include "realtek-mdio.h"
86
87 /* Read/write via mdiobus */
88 #define REALTEK_MDIO_CTRL0_REG 31
89 @@ -140,7 +141,19 @@ static const struct regmap_config realte
90 .disable_locking = true,
91 };
92
93 -static int realtek_mdio_probe(struct mdio_device *mdiodev)
94 +/**
95 + * realtek_mdio_probe() - Probe a platform device for an MDIO-connected switch
96 + * @mdiodev: mdio_device to probe on.
97 + *
98 + * This function should be used as the .probe in an mdio_driver. It
99 + * initializes realtek_priv and read data from the device-tree node. The switch
100 + * is hard reset if a method is provided. It checks the switch chip ID and,
101 + * finally, a DSA switch is registered.
102 + *
103 + * Context: Can sleep. Takes and releases priv->map_lock.
104 + * Return: Returns 0 on success, a negative error on failure.
105 + */
106 +int realtek_mdio_probe(struct mdio_device *mdiodev)
107 {
108 struct realtek_priv *priv;
109 struct device *dev = &mdiodev->dev;
110 @@ -235,8 +248,20 @@ static int realtek_mdio_probe(struct mdi
111
112 return 0;
113 }
114 +EXPORT_SYMBOL_NS_GPL(realtek_mdio_probe, REALTEK_DSA);
115
116 -static void realtek_mdio_remove(struct mdio_device *mdiodev)
117 +/**
118 + * realtek_mdio_remove() - Remove the driver of an MDIO-connected switch
119 + * @mdiodev: mdio_device to be removed.
120 + *
121 + * This function should be used as the .remove_new in an mdio_driver. First
122 + * it unregisters the DSA switch and cleans internal data. If a method is
123 + * provided, the hard reset is asserted to avoid traffic leakage.
124 + *
125 + * Context: Can sleep.
126 + * Return: Nothing.
127 + */
128 +void realtek_mdio_remove(struct mdio_device *mdiodev)
129 {
130 struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
131
132 @@ -249,8 +274,21 @@ static void realtek_mdio_remove(struct m
133 if (priv->reset)
134 gpiod_set_value(priv->reset, 1);
135 }
136 +EXPORT_SYMBOL_NS_GPL(realtek_mdio_remove, REALTEK_DSA);
137
138 -static void realtek_mdio_shutdown(struct mdio_device *mdiodev)
139 +/**
140 + * realtek_mdio_shutdown() - Shutdown the driver of a MDIO-connected switch
141 + * @mdiodev: mdio_device shutting down.
142 + *
143 + * This function should be used as the .shutdown in an mdio_driver. It shuts
144 + * down the DSA switch and cleans the platform driver data, to prevent
145 + * realtek_mdio_remove() from running afterwards, which is possible if the
146 + * parent bus implements its own .shutdown() as .remove().
147 + *
148 + * Context: Can sleep.
149 + * Return: Nothing.
150 + */
151 +void realtek_mdio_shutdown(struct mdio_device *mdiodev)
152 {
153 struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
154
155 @@ -261,29 +299,7 @@ static void realtek_mdio_shutdown(struct
156
157 dev_set_drvdata(&mdiodev->dev, NULL);
158 }
159 -
160 -static const struct of_device_id realtek_mdio_of_match[] = {
161 -#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB)
162 - { .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, },
163 -#endif
164 -#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
165 - { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
166 -#endif
167 - { /* sentinel */ },
168 -};
169 -MODULE_DEVICE_TABLE(of, realtek_mdio_of_match);
170 -
171 -static struct mdio_driver realtek_mdio_driver = {
172 - .mdiodrv.driver = {
173 - .name = "realtek-mdio",
174 - .of_match_table = realtek_mdio_of_match,
175 - },
176 - .probe = realtek_mdio_probe,
177 - .remove = realtek_mdio_remove,
178 - .shutdown = realtek_mdio_shutdown,
179 -};
180 -
181 -mdio_module_driver(realtek_mdio_driver);
182 +EXPORT_SYMBOL_NS_GPL(realtek_mdio_shutdown, REALTEK_DSA);
183
184 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
185 MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface");
186 --- /dev/null
187 +++ b/drivers/net/dsa/realtek/realtek-mdio.h
188 @@ -0,0 +1,48 @@
189 +/* SPDX-License-Identifier: GPL-2.0+ */
190 +
191 +#ifndef _REALTEK_MDIO_H
192 +#define _REALTEK_MDIO_H
193 +
194 +#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO)
195 +
196 +static inline int realtek_mdio_driver_register(struct mdio_driver *drv)
197 +{
198 + return mdio_driver_register(drv);
199 +}
200 +
201 +static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv)
202 +{
203 + mdio_driver_unregister(drv);
204 +}
205 +
206 +int realtek_mdio_probe(struct mdio_device *mdiodev);
207 +void realtek_mdio_remove(struct mdio_device *mdiodev);
208 +void realtek_mdio_shutdown(struct mdio_device *mdiodev);
209 +
210 +#else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */
211 +
212 +static inline int realtek_mdio_driver_register(struct mdio_driver *drv)
213 +{
214 + return 0;
215 +}
216 +
217 +static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv)
218 +{
219 +}
220 +
221 +static inline int realtek_mdio_probe(struct mdio_device *mdiodev)
222 +{
223 + return -ENOENT;
224 +}
225 +
226 +static inline void realtek_mdio_remove(struct mdio_device *mdiodev)
227 +{
228 +}
229 +
230 +static inline void realtek_mdio_shutdown(struct mdio_device *mdiodev)
231 +{
232 +}
233 +
234 +#endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */
235 +
236 +#endif /* _REALTEK_MDIO_H */
237 --- a/drivers/net/dsa/realtek/realtek-smi.c
238 +++ b/drivers/net/dsa/realtek/realtek-smi.c
239 @@ -40,6 +40,7 @@
240 #include <linux/if_bridge.h>
241
242 #include "realtek.h"
243 +#include "realtek-smi.h"
244
245 #define REALTEK_SMI_ACK_RETRY_COUNT 5
246
247 @@ -408,7 +409,19 @@ err_put_node:
248 return ret;
249 }
250
251 -static int realtek_smi_probe(struct platform_device *pdev)
252 +/**
253 + * realtek_smi_probe() - Probe a platform device for an SMI-connected switch
254 + * @pdev: platform_device to probe on.
255 + *
256 + * This function should be used as the .probe in a platform_driver. It
257 + * initializes realtek_priv and read data from the device-tree node. The switch
258 + * is hard reset if a method is provided. It checks the switch chip ID and,
259 + * finally, a DSA switch is registered.
260 + *
261 + * Context: Can sleep. Takes and releases priv->map_lock.
262 + * Return: Returns 0 on success, a negative error on failure.
263 + */
264 +int realtek_smi_probe(struct platform_device *pdev)
265 {
266 const struct realtek_variant *var;
267 struct device *dev = &pdev->dev;
268 @@ -505,8 +518,20 @@ static int realtek_smi_probe(struct plat
269 }
270 return 0;
271 }
272 +EXPORT_SYMBOL_NS_GPL(realtek_smi_probe, REALTEK_DSA);
273
274 -static void realtek_smi_remove(struct platform_device *pdev)
275 +/**
276 + * realtek_smi_remove() - Remove the driver of a SMI-connected switch
277 + * @pdev: platform_device to be removed.
278 + *
279 + * This function should be used as the .remove_new in a platform_driver. First
280 + * it unregisters the DSA switch and cleans internal data. If a method is
281 + * provided, the hard reset is asserted to avoid traffic leakage.
282 + *
283 + * Context: Can sleep.
284 + * Return: Nothing.
285 + */
286 +void realtek_smi_remove(struct platform_device *pdev)
287 {
288 struct realtek_priv *priv = platform_get_drvdata(pdev);
289
290 @@ -521,8 +546,21 @@ static void realtek_smi_remove(struct pl
291 if (priv->reset)
292 gpiod_set_value(priv->reset, 1);
293 }
294 +EXPORT_SYMBOL_NS_GPL(realtek_smi_remove, REALTEK_DSA);
295
296 -static void realtek_smi_shutdown(struct platform_device *pdev)
297 +/**
298 + * realtek_smi_shutdown() - Shutdown the driver of a SMI-connected switch
299 + * @pdev: platform_device shutting down.
300 + *
301 + * This function should be used as the .shutdown in a platform_driver. It shuts
302 + * down the DSA switch and cleans the platform driver data, to prevent
303 + * realtek_smi_remove() from running afterwards, which is possible if the
304 + * parent bus implements its own .shutdown() as .remove().
305 + *
306 + * Context: Can sleep.
307 + * Return: Nothing.
308 + */
309 +void realtek_smi_shutdown(struct platform_device *pdev)
310 {
311 struct realtek_priv *priv = platform_get_drvdata(pdev);
312
313 @@ -533,34 +571,7 @@ static void realtek_smi_shutdown(struct
314
315 platform_set_drvdata(pdev, NULL);
316 }
317 -
318 -static const struct of_device_id realtek_smi_of_match[] = {
319 -#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB)
320 - {
321 - .compatible = "realtek,rtl8366rb",
322 - .data = &rtl8366rb_variant,
323 - },
324 -#endif
325 -#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
326 - {
327 - .compatible = "realtek,rtl8365mb",
328 - .data = &rtl8365mb_variant,
329 - },
330 -#endif
331 - { /* sentinel */ },
332 -};
333 -MODULE_DEVICE_TABLE(of, realtek_smi_of_match);
334 -
335 -static struct platform_driver realtek_smi_driver = {
336 - .driver = {
337 - .name = "realtek-smi",
338 - .of_match_table = realtek_smi_of_match,
339 - },
340 - .probe = realtek_smi_probe,
341 - .remove_new = realtek_smi_remove,
342 - .shutdown = realtek_smi_shutdown,
343 -};
344 -module_platform_driver(realtek_smi_driver);
345 +EXPORT_SYMBOL_NS_GPL(realtek_smi_shutdown, REALTEK_DSA);
346
347 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
348 MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via SMI interface");
349 --- /dev/null
350 +++ b/drivers/net/dsa/realtek/realtek-smi.h
351 @@ -0,0 +1,48 @@
352 +/* SPDX-License-Identifier: GPL-2.0+ */
353 +
354 +#ifndef _REALTEK_SMI_H
355 +#define _REALTEK_SMI_H
356 +
357 +#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI)
358 +
359 +static inline int realtek_smi_driver_register(struct platform_driver *drv)
360 +{
361 + return platform_driver_register(drv);
362 +}
363 +
364 +static inline void realtek_smi_driver_unregister(struct platform_driver *drv)
365 +{
366 + platform_driver_unregister(drv);
367 +}
368 +
369 +int realtek_smi_probe(struct platform_device *pdev);
370 +void realtek_smi_remove(struct platform_device *pdev);
371 +void realtek_smi_shutdown(struct platform_device *pdev);
372 +
373 +#else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */
374 +
375 +static inline int realtek_smi_driver_register(struct platform_driver *drv)
376 +{
377 + return 0;
378 +}
379 +
380 +static inline void realtek_smi_driver_unregister(struct platform_driver *drv)
381 +{
382 +}
383 +
384 +static inline int realtek_smi_probe(struct platform_device *pdev)
385 +{
386 + return -ENOENT;
387 +}
388 +
389 +static inline void realtek_smi_remove(struct platform_device *pdev)
390 +{
391 +}
392 +
393 +static inline void realtek_smi_shutdown(struct platform_device *pdev)
394 +{
395 +}
396 +
397 +#endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */
398 +
399 +#endif /* _REALTEK_SMI_H */
400 --- a/drivers/net/dsa/realtek/rtl8365mb.c
401 +++ b/drivers/net/dsa/realtek/rtl8365mb.c
402 @@ -101,6 +101,8 @@
403 #include <linux/if_vlan.h>
404
405 #include "realtek.h"
406 +#include "realtek-smi.h"
407 +#include "realtek-mdio.h"
408
409 /* Family-specific data and limits */
410 #define RTL8365MB_PHYADDRMAX 7
411 @@ -2173,7 +2175,57 @@ const struct realtek_variant rtl8365mb_v
412 .cmd_write = 0xb8,
413 .chip_data_sz = sizeof(struct rtl8365mb),
414 };
415 -EXPORT_SYMBOL_GPL(rtl8365mb_variant);
416 +
417 +static const struct of_device_id rtl8365mb_of_match[] = {
418 + { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
419 + { /* sentinel */ },
420 +};
421 +MODULE_DEVICE_TABLE(of, rtl8365mb_of_match);
422 +
423 +static struct platform_driver rtl8365mb_smi_driver = {
424 + .driver = {
425 + .name = "rtl8365mb-smi",
426 + .of_match_table = rtl8365mb_of_match,
427 + },
428 + .probe = realtek_smi_probe,
429 + .remove_new = realtek_smi_remove,
430 + .shutdown = realtek_smi_shutdown,
431 +};
432 +
433 +static struct mdio_driver rtl8365mb_mdio_driver = {
434 + .mdiodrv.driver = {
435 + .name = "rtl8365mb-mdio",
436 + .of_match_table = rtl8365mb_of_match,
437 + },
438 + .probe = realtek_mdio_probe,
439 + .remove = realtek_mdio_remove,
440 + .shutdown = realtek_mdio_shutdown,
441 +};
442 +
443 +static int rtl8365mb_init(void)
444 +{
445 + int ret;
446 +
447 + ret = realtek_mdio_driver_register(&rtl8365mb_mdio_driver);
448 + if (ret)
449 + return ret;
450 +
451 + ret = realtek_smi_driver_register(&rtl8365mb_smi_driver);
452 + if (ret) {
453 + realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
454 + return ret;
455 + }
456 +
457 + return 0;
458 +}
459 +module_init(rtl8365mb_init);
460 +
461 +static void __exit rtl8365mb_exit(void)
462 +{
463 + realtek_smi_driver_unregister(&rtl8365mb_smi_driver);
464 + realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
465 +}
466 +module_exit(rtl8365mb_exit);
467
468 MODULE_AUTHOR("Alvin Šipraga <alsi@bang-olufsen.dk>");
469 MODULE_DESCRIPTION("Driver for RTL8365MB-VC ethernet switch");
470 --- a/drivers/net/dsa/realtek/rtl8366rb.c
471 +++ b/drivers/net/dsa/realtek/rtl8366rb.c
472 @@ -22,6 +22,8 @@
473 #include <linux/regmap.h>
474
475 #include "realtek.h"
476 +#include "realtek-smi.h"
477 +#include "realtek-mdio.h"
478
479 #define RTL8366RB_PORT_NUM_CPU 5
480 #define RTL8366RB_NUM_PORTS 6
481 @@ -1847,7 +1849,57 @@ const struct realtek_variant rtl8366rb_v
482 .cmd_write = 0xa8,
483 .chip_data_sz = sizeof(struct rtl8366rb),
484 };
485 -EXPORT_SYMBOL_GPL(rtl8366rb_variant);
486 +
487 +static const struct of_device_id rtl8366rb_of_match[] = {
488 + { .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, },
489 + { /* sentinel */ },
490 +};
491 +MODULE_DEVICE_TABLE(of, rtl8366rb_of_match);
492 +
493 +static struct platform_driver rtl8366rb_smi_driver = {
494 + .driver = {
495 + .name = "rtl8366rb-smi",
496 + .of_match_table = rtl8366rb_of_match,
497 + },
498 + .probe = realtek_smi_probe,
499 + .remove_new = realtek_smi_remove,
500 + .shutdown = realtek_smi_shutdown,
501 +};
502 +
503 +static struct mdio_driver rtl8366rb_mdio_driver = {
504 + .mdiodrv.driver = {
505 + .name = "rtl8366rb-mdio",
506 + .of_match_table = rtl8366rb_of_match,
507 + },
508 + .probe = realtek_mdio_probe,
509 + .remove = realtek_mdio_remove,
510 + .shutdown = realtek_mdio_shutdown,
511 +};
512 +
513 +static int rtl8366rb_init(void)
514 +{
515 + int ret;
516 +
517 + ret = realtek_mdio_driver_register(&rtl8366rb_mdio_driver);
518 + if (ret)
519 + return ret;
520 +
521 + ret = realtek_smi_driver_register(&rtl8366rb_smi_driver);
522 + if (ret) {
523 + realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver);
524 + return ret;
525 + }
526 +
527 + return 0;
528 +}
529 +module_init(rtl8366rb_init);
530 +
531 +static void __exit rtl8366rb_exit(void)
532 +{
533 + realtek_smi_driver_unregister(&rtl8366rb_smi_driver);
534 + realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver);
535 +}
536 +module_exit(rtl8366rb_exit);
537
538 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
539 MODULE_DESCRIPTION("Driver for RTL8366RB ethernet switch");