Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'dsa-realtek-common'

Luiz Angelo Daros de Luca says:

====================
net: dsa: realtek: variants to drivers, interfaces to a common module

The current driver consists of two interface modules (SMI and MDIO) and
two family/variant modules (RTL8365MB and RTL8366RB). The SMI and MDIO
modules serve as the platform and MDIO drivers, respectively, calling
functions from the variant modules. In this setup, one interface module
can be loaded independently of the other, but both variants must be
loaded (if not disabled at build time) for any type of interface. This
approach doesn't scale well, especially with the addition of more switch
variants (e.g., RTL8366B), leading to loaded but unused modules.
Additionally, this also seems upside down, as the specific driver code
normally depends on the more generic functions and not the other way
around.

Each variant module was converted into real drivers, serving as both a
platform driver (for switches connected using the SMI interface) and an
MDIO driver (for MDIO-connected switches). The relationship between the
variant and interface modules is reversed, with the variant module now
calling both interface functions (if not disabled at build time). While
in most devices only one interface is likely used, the interface code is
significantly smaller than a variant module, consuming fewer resources
than the previous code. With variant modules now functioning as real
drivers, compatible strings are published only in a single variant
module, preventing conflicts.

The patch series introduces a new common module for functions shared by
both variants. This module also absorbs the two previous interface
modules, as they would always be loaded anyway.

The series relocates the user MII driver from realtek-smi to rtl83xx. It
is now used by MDIO-connected switches instead of the generic DSA
driver. There's a change in how this driver locates the MDIO node. It
now only searches for a child node named "mdio".

The dsa_switch in realtek_priv->ds is now embedded in the struct. It is
always in use and avoids dynamic memory allocation.

Testing has been performed with an RTL8367S (rtl8365mb) using MDIO
interface and an RTL8366RB (rtl8366) with SMI interface.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+705 -514
+6 -14
drivers/net/dsa/realtek/Kconfig
··· 16 16 if NET_DSA_REALTEK 17 17 18 18 config NET_DSA_REALTEK_MDIO 19 - tristate "Realtek MDIO interface driver" 19 + bool "Realtek MDIO interface support" 20 20 depends on OF 21 - depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB 22 - depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB 23 - depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB 24 21 help 25 22 Select to enable support for registering switches configured 26 23 through MDIO. 27 24 28 25 config NET_DSA_REALTEK_SMI 29 - tristate "Realtek SMI interface driver" 26 + bool "Realtek SMI interface support" 30 27 depends on OF 31 - depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB 32 - depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB 33 - depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB 34 28 help 35 29 Select to enable support for registering switches connected 36 30 through SMI. 37 31 38 32 config NET_DSA_REALTEK_RTL8365MB 39 - tristate "Realtek RTL8365MB switch subdriver" 40 - imply NET_DSA_REALTEK_SMI 41 - imply NET_DSA_REALTEK_MDIO 33 + tristate "Realtek RTL8365MB switch driver" 34 + depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO 42 35 select NET_DSA_TAG_RTL8_4 43 36 help 44 37 Select to enable support for Realtek RTL8365MB-VC and RTL8367S. 45 38 46 39 config NET_DSA_REALTEK_RTL8366RB 47 - tristate "Realtek RTL8366RB switch subdriver" 48 - imply NET_DSA_REALTEK_SMI 49 - imply NET_DSA_REALTEK_MDIO 40 + tristate "Realtek RTL8366RB switch driver" 41 + depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO 50 42 select NET_DSA_TAG_RTL4_A 51 43 help 52 44 Select to enable support for Realtek RTL8366RB.
+11 -2
drivers/net/dsa/realtek/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_NET_DSA_REALTEK_MDIO) += realtek-mdio.o 3 - obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o 2 + obj-$(CONFIG_NET_DSA_REALTEK) += realtek_dsa.o 3 + realtek_dsa-objs := rtl83xx.o 4 + 5 + ifdef CONFIG_NET_DSA_REALTEK_MDIO 6 + realtek_dsa-objs += realtek-mdio.o 7 + endif 8 + 9 + ifdef CONFIG_NET_DSA_REALTEK_SMI 10 + realtek_dsa-objs += realtek-smi.o 11 + endif 12 + 4 13 obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o 5 14 rtl8366-objs := rtl8366-core.o rtl8366rb.o 6 15 obj-$(CONFIG_NET_DSA_REALTEK_RTL8365MB) += rtl8365mb.o
+51 -154
drivers/net/dsa/realtek/realtek-mdio.c
··· 25 25 #include <linux/regmap.h> 26 26 27 27 #include "realtek.h" 28 + #include "realtek-mdio.h" 29 + #include "rtl83xx.h" 28 30 29 31 /* Read/write via mdiobus */ 30 32 #define REALTEK_MDIO_CTRL0_REG 31 ··· 101 99 return ret; 102 100 } 103 101 104 - static void realtek_mdio_lock(void *ctx) 105 - { 106 - struct realtek_priv *priv = ctx; 107 - 108 - mutex_lock(&priv->map_lock); 109 - } 110 - 111 - static void realtek_mdio_unlock(void *ctx) 112 - { 113 - struct realtek_priv *priv = ctx; 114 - 115 - mutex_unlock(&priv->map_lock); 116 - } 117 - 118 - static const struct regmap_config realtek_mdio_regmap_config = { 119 - .reg_bits = 10, /* A4..A0 R4..R0 */ 120 - .val_bits = 16, 121 - .reg_stride = 1, 122 - /* PHY regs are at 0x8000 */ 123 - .max_register = 0xffff, 124 - .reg_format_endian = REGMAP_ENDIAN_BIG, 102 + static const struct realtek_interface_info realtek_mdio_info = { 125 103 .reg_read = realtek_mdio_read, 126 104 .reg_write = realtek_mdio_write, 127 - .cache_type = REGCACHE_NONE, 128 - .lock = realtek_mdio_lock, 129 - .unlock = realtek_mdio_unlock, 130 105 }; 131 106 132 - static const struct regmap_config realtek_mdio_nolock_regmap_config = { 133 - .reg_bits = 10, /* A4..A0 R4..R0 */ 134 - .val_bits = 16, 135 - .reg_stride = 1, 136 - /* PHY regs are at 0x8000 */ 137 - .max_register = 0xffff, 138 - .reg_format_endian = REGMAP_ENDIAN_BIG, 139 - .reg_read = realtek_mdio_read, 140 - .reg_write = realtek_mdio_write, 141 - .cache_type = REGCACHE_NONE, 142 - .disable_locking = true, 143 - }; 144 - 145 - static int realtek_mdio_probe(struct mdio_device *mdiodev) 107 + /** 108 + * realtek_mdio_probe() - Probe a platform device for an MDIO-connected switch 109 + * @mdiodev: mdio_device to probe on. 110 + * 111 + * This function should be used as the .probe in an mdio_driver. After 112 + * calling the common probe function for both interfaces, it initializes the 113 + * values specific for MDIO-connected devices. Finally, it calls a common 114 + * function to register the DSA switch. 115 + * 116 + * Context: Can sleep. Takes and releases priv->map_lock. 117 + * Return: Returns 0 on success, a negative error on failure. 118 + */ 119 + int realtek_mdio_probe(struct mdio_device *mdiodev) 146 120 { 147 - struct realtek_priv *priv; 148 121 struct device *dev = &mdiodev->dev; 149 - const struct realtek_variant *var; 150 - struct regmap_config rc; 151 - struct device_node *np; 122 + struct realtek_priv *priv; 152 123 int ret; 153 124 154 - var = of_device_get_match_data(dev); 155 - if (!var) 156 - return -EINVAL; 125 + priv = rtl83xx_probe(dev, &realtek_mdio_info); 126 + if (IS_ERR(priv)) 127 + return PTR_ERR(priv); 157 128 158 - priv = devm_kzalloc(&mdiodev->dev, 159 - size_add(sizeof(*priv), var->chip_data_sz), 160 - GFP_KERNEL); 161 - if (!priv) 162 - return -ENOMEM; 163 - 164 - mutex_init(&priv->map_lock); 165 - 166 - rc = realtek_mdio_regmap_config; 167 - rc.lock_arg = priv; 168 - priv->map = devm_regmap_init(dev, NULL, priv, &rc); 169 - if (IS_ERR(priv->map)) { 170 - ret = PTR_ERR(priv->map); 171 - dev_err(dev, "regmap init failed: %d\n", ret); 172 - return ret; 173 - } 174 - 175 - rc = realtek_mdio_nolock_regmap_config; 176 - priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc); 177 - if (IS_ERR(priv->map_nolock)) { 178 - ret = PTR_ERR(priv->map_nolock); 179 - dev_err(dev, "regmap init failed: %d\n", ret); 180 - return ret; 181 - } 182 - 183 - priv->mdio_addr = mdiodev->addr; 184 129 priv->bus = mdiodev->bus; 185 - priv->dev = &mdiodev->dev; 186 - priv->chip_data = (void *)priv + sizeof(*priv); 187 - 188 - priv->clk_delay = var->clk_delay; 189 - priv->cmd_read = var->cmd_read; 190 - priv->cmd_write = var->cmd_write; 191 - priv->ops = var->ops; 192 - 130 + priv->mdio_addr = mdiodev->addr; 193 131 priv->write_reg_noack = realtek_mdio_write; 194 132 195 - np = dev->of_node; 196 - 197 - dev_set_drvdata(dev, priv); 198 - 199 - /* TODO: if power is software controlled, set up any regulators here */ 200 - priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds"); 201 - 202 - priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 203 - if (IS_ERR(priv->reset)) { 204 - dev_err(dev, "failed to get RESET GPIO\n"); 205 - return PTR_ERR(priv->reset); 206 - } 207 - 208 - if (priv->reset) { 209 - gpiod_set_value(priv->reset, 1); 210 - dev_dbg(dev, "asserted RESET\n"); 211 - msleep(REALTEK_HW_STOP_DELAY); 212 - gpiod_set_value(priv->reset, 0); 213 - msleep(REALTEK_HW_START_DELAY); 214 - dev_dbg(dev, "deasserted RESET\n"); 215 - } 216 - 217 - ret = priv->ops->detect(priv); 133 + ret = rtl83xx_register_switch(priv); 218 134 if (ret) { 219 - dev_err(dev, "unable to detect switch\n"); 220 - return ret; 221 - } 222 - 223 - priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL); 224 - if (!priv->ds) 225 - return -ENOMEM; 226 - 227 - priv->ds->dev = dev; 228 - priv->ds->num_ports = priv->num_ports; 229 - priv->ds->priv = priv; 230 - priv->ds->ops = var->ds_ops_mdio; 231 - 232 - ret = dsa_register_switch(priv->ds); 233 - if (ret) { 234 - dev_err(priv->dev, "unable to register switch ret = %d\n", ret); 135 + rtl83xx_remove(priv); 235 136 return ret; 236 137 } 237 138 238 139 return 0; 239 140 } 141 + EXPORT_SYMBOL_NS_GPL(realtek_mdio_probe, REALTEK_DSA); 240 142 241 - static void realtek_mdio_remove(struct mdio_device *mdiodev) 143 + /** 144 + * realtek_mdio_remove() - Remove the driver of an MDIO-connected switch 145 + * @mdiodev: mdio_device to be removed. 146 + * 147 + * This function should be used as the .remove_new in an mdio_driver. First 148 + * it unregisters the DSA switch and then it calls the common remove function. 149 + * 150 + * Context: Can sleep. 151 + * Return: Nothing. 152 + */ 153 + void realtek_mdio_remove(struct mdio_device *mdiodev) 242 154 { 243 155 struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev); 244 156 245 157 if (!priv) 246 158 return; 247 159 248 - dsa_unregister_switch(priv->ds); 160 + rtl83xx_unregister_switch(priv); 249 161 250 - /* leave the device reset asserted */ 251 - if (priv->reset) 252 - gpiod_set_value(priv->reset, 1); 162 + rtl83xx_remove(priv); 253 163 } 164 + EXPORT_SYMBOL_NS_GPL(realtek_mdio_remove, REALTEK_DSA); 254 165 255 - static void realtek_mdio_shutdown(struct mdio_device *mdiodev) 166 + /** 167 + * realtek_mdio_shutdown() - Shutdown the driver of a MDIO-connected switch 168 + * @mdiodev: mdio_device shutting down. 169 + * 170 + * This function should be used as the .shutdown in a platform_driver. It calls 171 + * the common shutdown function. 172 + * 173 + * Context: Can sleep. 174 + * Return: Nothing. 175 + */ 176 + void realtek_mdio_shutdown(struct mdio_device *mdiodev) 256 177 { 257 178 struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev); 258 179 259 180 if (!priv) 260 181 return; 261 182 262 - dsa_switch_shutdown(priv->ds); 263 - 264 - dev_set_drvdata(&mdiodev->dev, NULL); 183 + rtl83xx_shutdown(priv); 265 184 } 266 - 267 - static const struct of_device_id realtek_mdio_of_match[] = { 268 - #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB) 269 - { .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, }, 270 - #endif 271 - #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB) 272 - { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, }, 273 - #endif 274 - { /* sentinel */ }, 275 - }; 276 - MODULE_DEVICE_TABLE(of, realtek_mdio_of_match); 277 - 278 - static struct mdio_driver realtek_mdio_driver = { 279 - .mdiodrv.driver = { 280 - .name = "realtek-mdio", 281 - .of_match_table = realtek_mdio_of_match, 282 - }, 283 - .probe = realtek_mdio_probe, 284 - .remove = realtek_mdio_remove, 285 - .shutdown = realtek_mdio_shutdown, 286 - }; 287 - 288 - mdio_module_driver(realtek_mdio_driver); 289 - 290 - MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>"); 291 - MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface"); 292 - MODULE_LICENSE("GPL"); 185 + EXPORT_SYMBOL_NS_GPL(realtek_mdio_shutdown, REALTEK_DSA);
+48
drivers/net/dsa/realtek/realtek-mdio.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + 3 + #ifndef _REALTEK_MDIO_H 4 + #define _REALTEK_MDIO_H 5 + 6 + #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) 7 + 8 + static inline int realtek_mdio_driver_register(struct mdio_driver *drv) 9 + { 10 + return mdio_driver_register(drv); 11 + } 12 + 13 + static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv) 14 + { 15 + mdio_driver_unregister(drv); 16 + } 17 + 18 + int realtek_mdio_probe(struct mdio_device *mdiodev); 19 + void realtek_mdio_remove(struct mdio_device *mdiodev); 20 + void realtek_mdio_shutdown(struct mdio_device *mdiodev); 21 + 22 + #else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */ 23 + 24 + static inline int realtek_mdio_driver_register(struct mdio_driver *drv) 25 + { 26 + return 0; 27 + } 28 + 29 + static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv) 30 + { 31 + } 32 + 33 + static inline int realtek_mdio_probe(struct mdio_device *mdiodev) 34 + { 35 + return -ENOENT; 36 + } 37 + 38 + static inline void realtek_mdio_remove(struct mdio_device *mdiodev) 39 + { 40 + } 41 + 42 + static inline void realtek_mdio_shutdown(struct mdio_device *mdiodev) 43 + { 44 + } 45 + 46 + #endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */ 47 + 48 + #endif /* _REALTEK_MDIO_H */
+60 -219
drivers/net/dsa/realtek/realtek-smi.c
··· 31 31 #include <linux/spinlock.h> 32 32 #include <linux/skbuff.h> 33 33 #include <linux/of.h> 34 - #include <linux/of_mdio.h> 35 34 #include <linux/delay.h> 36 35 #include <linux/gpio/consumer.h> 37 36 #include <linux/platform_device.h> ··· 39 40 #include <linux/if_bridge.h> 40 41 41 42 #include "realtek.h" 43 + #include "realtek-smi.h" 44 + #include "rtl83xx.h" 42 45 43 46 #define REALTEK_SMI_ACK_RETRY_COUNT 5 44 47 45 48 static inline void realtek_smi_clk_delay(struct realtek_priv *priv) 46 49 { 47 - ndelay(priv->clk_delay); 50 + ndelay(priv->variant->clk_delay); 48 51 } 49 52 50 53 static void realtek_smi_start(struct realtek_priv *priv) ··· 209 208 realtek_smi_start(priv); 210 209 211 210 /* Send READ command */ 212 - ret = realtek_smi_write_byte(priv, priv->cmd_read); 211 + ret = realtek_smi_write_byte(priv, priv->variant->cmd_read); 213 212 if (ret) 214 213 goto out; 215 214 ··· 250 249 realtek_smi_start(priv); 251 250 252 251 /* Send WRITE command */ 253 - ret = realtek_smi_write_byte(priv, priv->cmd_write); 252 + ret = realtek_smi_write_byte(priv, priv->variant->cmd_write); 254 253 if (ret) 255 254 goto out; 256 255 ··· 311 310 return realtek_smi_read_reg(priv, reg, val); 312 311 } 313 312 314 - static void realtek_smi_lock(void *ctx) 315 - { 316 - struct realtek_priv *priv = ctx; 317 - 318 - mutex_lock(&priv->map_lock); 319 - } 320 - 321 - static void realtek_smi_unlock(void *ctx) 322 - { 323 - struct realtek_priv *priv = ctx; 324 - 325 - mutex_unlock(&priv->map_lock); 326 - } 327 - 328 - static const struct regmap_config realtek_smi_regmap_config = { 329 - .reg_bits = 10, /* A4..A0 R4..R0 */ 330 - .val_bits = 16, 331 - .reg_stride = 1, 332 - /* PHY regs are at 0x8000 */ 333 - .max_register = 0xffff, 334 - .reg_format_endian = REGMAP_ENDIAN_BIG, 313 + static const struct realtek_interface_info realtek_smi_info = { 335 314 .reg_read = realtek_smi_read, 336 315 .reg_write = realtek_smi_write, 337 - .cache_type = REGCACHE_NONE, 338 - .lock = realtek_smi_lock, 339 - .unlock = realtek_smi_unlock, 340 316 }; 341 317 342 - static const struct regmap_config realtek_smi_nolock_regmap_config = { 343 - .reg_bits = 10, /* A4..A0 R4..R0 */ 344 - .val_bits = 16, 345 - .reg_stride = 1, 346 - /* PHY regs are at 0x8000 */ 347 - .max_register = 0xffff, 348 - .reg_format_endian = REGMAP_ENDIAN_BIG, 349 - .reg_read = realtek_smi_read, 350 - .reg_write = realtek_smi_write, 351 - .cache_type = REGCACHE_NONE, 352 - .disable_locking = true, 353 - }; 354 - 355 - static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum) 318 + /** 319 + * realtek_smi_probe() - Probe a platform device for an SMI-connected switch 320 + * @pdev: platform_device to probe on. 321 + * 322 + * This function should be used as the .probe in a platform_driver. After 323 + * calling the common probe function for both interfaces, it initializes the 324 + * values specific for SMI-connected devices. Finally, it calls a common 325 + * function to register the DSA switch. 326 + * 327 + * Context: Can sleep. Takes and releases priv->map_lock. 328 + * Return: Returns 0 on success, a negative error on failure. 329 + */ 330 + int realtek_smi_probe(struct platform_device *pdev) 356 331 { 357 - struct realtek_priv *priv = bus->priv; 358 - 359 - return priv->ops->phy_read(priv, addr, regnum); 360 - } 361 - 362 - static int realtek_smi_mdio_write(struct mii_bus *bus, int addr, int regnum, 363 - u16 val) 364 - { 365 - struct realtek_priv *priv = bus->priv; 366 - 367 - return priv->ops->phy_write(priv, addr, regnum, val); 368 - } 369 - 370 - static int realtek_smi_setup_mdio(struct dsa_switch *ds) 371 - { 372 - struct realtek_priv *priv = ds->priv; 373 - struct device_node *mdio_np; 374 - int ret; 375 - 376 - mdio_np = of_get_compatible_child(priv->dev->of_node, "realtek,smi-mdio"); 377 - if (!mdio_np) { 378 - dev_err(priv->dev, "no MDIO bus node\n"); 379 - return -ENODEV; 380 - } 381 - 382 - priv->user_mii_bus = devm_mdiobus_alloc(priv->dev); 383 - if (!priv->user_mii_bus) { 384 - ret = -ENOMEM; 385 - goto err_put_node; 386 - } 387 - priv->user_mii_bus->priv = priv; 388 - priv->user_mii_bus->name = "SMI user MII"; 389 - priv->user_mii_bus->read = realtek_smi_mdio_read; 390 - priv->user_mii_bus->write = realtek_smi_mdio_write; 391 - snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d", 392 - ds->index); 393 - priv->user_mii_bus->dev.of_node = mdio_np; 394 - priv->user_mii_bus->parent = priv->dev; 395 - ds->user_mii_bus = priv->user_mii_bus; 396 - 397 - ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np); 398 - if (ret) { 399 - dev_err(priv->dev, "unable to register MDIO bus %s\n", 400 - priv->user_mii_bus->id); 401 - goto err_put_node; 402 - } 403 - 404 - return 0; 405 - 406 - err_put_node: 407 - of_node_put(mdio_np); 408 - 409 - return ret; 410 - } 411 - 412 - static int realtek_smi_probe(struct platform_device *pdev) 413 - { 414 - const struct realtek_variant *var; 415 332 struct device *dev = &pdev->dev; 416 333 struct realtek_priv *priv; 417 - struct regmap_config rc; 418 - struct device_node *np; 419 334 int ret; 420 335 421 - var = of_device_get_match_data(dev); 422 - np = dev->of_node; 423 - 424 - priv = devm_kzalloc(dev, sizeof(*priv) + var->chip_data_sz, GFP_KERNEL); 425 - if (!priv) 426 - return -ENOMEM; 427 - priv->chip_data = (void *)priv + sizeof(*priv); 428 - 429 - mutex_init(&priv->map_lock); 430 - 431 - rc = realtek_smi_regmap_config; 432 - rc.lock_arg = priv; 433 - priv->map = devm_regmap_init(dev, NULL, priv, &rc); 434 - if (IS_ERR(priv->map)) { 435 - ret = PTR_ERR(priv->map); 436 - dev_err(dev, "regmap init failed: %d\n", ret); 437 - return ret; 438 - } 439 - 440 - rc = realtek_smi_nolock_regmap_config; 441 - priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc); 442 - if (IS_ERR(priv->map_nolock)) { 443 - ret = PTR_ERR(priv->map_nolock); 444 - dev_err(dev, "regmap init failed: %d\n", ret); 445 - return ret; 446 - } 447 - 448 - /* Link forward and backward */ 449 - priv->dev = dev; 450 - priv->clk_delay = var->clk_delay; 451 - priv->cmd_read = var->cmd_read; 452 - priv->cmd_write = var->cmd_write; 453 - priv->ops = var->ops; 454 - 455 - priv->setup_interface = realtek_smi_setup_mdio; 456 - priv->write_reg_noack = realtek_smi_write_reg_noack; 457 - 458 - dev_set_drvdata(dev, priv); 459 - spin_lock_init(&priv->lock); 460 - 461 - /* TODO: if power is software controlled, set up any regulators here */ 462 - 463 - priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 464 - if (IS_ERR(priv->reset)) { 465 - dev_err(dev, "failed to get RESET GPIO\n"); 466 - return PTR_ERR(priv->reset); 467 - } 468 - if (priv->reset) { 469 - gpiod_set_value(priv->reset, 1); 470 - dev_dbg(dev, "asserted RESET\n"); 471 - msleep(REALTEK_HW_STOP_DELAY); 472 - gpiod_set_value(priv->reset, 0); 473 - msleep(REALTEK_HW_START_DELAY); 474 - dev_dbg(dev, "deasserted RESET\n"); 475 - } 336 + priv = rtl83xx_probe(dev, &realtek_smi_info); 337 + if (IS_ERR(priv)) 338 + return PTR_ERR(priv); 476 339 477 340 /* Fetch MDIO pins */ 478 341 priv->mdc = devm_gpiod_get_optional(dev, "mdc", GPIOD_OUT_LOW); 479 - if (IS_ERR(priv->mdc)) 342 + if (IS_ERR(priv->mdc)) { 343 + rtl83xx_remove(priv); 480 344 return PTR_ERR(priv->mdc); 345 + } 346 + 481 347 priv->mdio = devm_gpiod_get_optional(dev, "mdio", GPIOD_OUT_LOW); 482 - if (IS_ERR(priv->mdio)) 348 + if (IS_ERR(priv->mdio)) { 349 + rtl83xx_remove(priv); 483 350 return PTR_ERR(priv->mdio); 351 + } 484 352 485 - priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds"); 353 + priv->write_reg_noack = realtek_smi_write_reg_noack; 486 354 487 - ret = priv->ops->detect(priv); 355 + ret = rtl83xx_register_switch(priv); 488 356 if (ret) { 489 - dev_err(dev, "unable to detect switch\n"); 357 + rtl83xx_remove(priv); 490 358 return ret; 491 359 } 492 360 493 - priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL); 494 - if (!priv->ds) 495 - return -ENOMEM; 496 - 497 - priv->ds->dev = dev; 498 - priv->ds->num_ports = priv->num_ports; 499 - priv->ds->priv = priv; 500 - 501 - priv->ds->ops = var->ds_ops_smi; 502 - ret = dsa_register_switch(priv->ds); 503 - if (ret) { 504 - dev_err_probe(dev, ret, "unable to register switch\n"); 505 - return ret; 506 - } 507 361 return 0; 508 362 } 363 + EXPORT_SYMBOL_NS_GPL(realtek_smi_probe, REALTEK_DSA); 509 364 510 - static void realtek_smi_remove(struct platform_device *pdev) 365 + /** 366 + * realtek_smi_remove() - Remove the driver of a SMI-connected switch 367 + * @pdev: platform_device to be removed. 368 + * 369 + * This function should be used as the .remove_new in a platform_driver. First 370 + * it unregisters the DSA switch and then it calls the common remove function. 371 + * 372 + * Context: Can sleep. 373 + * Return: Nothing. 374 + */ 375 + void realtek_smi_remove(struct platform_device *pdev) 511 376 { 512 377 struct realtek_priv *priv = platform_get_drvdata(pdev); 513 378 514 379 if (!priv) 515 380 return; 516 381 517 - dsa_unregister_switch(priv->ds); 518 - if (priv->user_mii_bus) 519 - of_node_put(priv->user_mii_bus->dev.of_node); 382 + rtl83xx_unregister_switch(priv); 520 383 521 - /* leave the device reset asserted */ 522 - if (priv->reset) 523 - gpiod_set_value(priv->reset, 1); 384 + rtl83xx_remove(priv); 524 385 } 386 + EXPORT_SYMBOL_NS_GPL(realtek_smi_remove, REALTEK_DSA); 525 387 526 - static void realtek_smi_shutdown(struct platform_device *pdev) 388 + /** 389 + * realtek_smi_shutdown() - Shutdown the driver of a SMI-connected switch 390 + * @pdev: platform_device shutting down. 391 + * 392 + * This function should be used as the .shutdown in a platform_driver. It calls 393 + * the common shutdown function. 394 + * 395 + * Context: Can sleep. 396 + * Return: Nothing. 397 + */ 398 + void realtek_smi_shutdown(struct platform_device *pdev) 527 399 { 528 400 struct realtek_priv *priv = platform_get_drvdata(pdev); 529 401 530 402 if (!priv) 531 403 return; 532 404 533 - dsa_switch_shutdown(priv->ds); 534 - 535 - platform_set_drvdata(pdev, NULL); 405 + rtl83xx_shutdown(priv); 536 406 } 537 - 538 - static const struct of_device_id realtek_smi_of_match[] = { 539 - #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB) 540 - { 541 - .compatible = "realtek,rtl8366rb", 542 - .data = &rtl8366rb_variant, 543 - }, 544 - #endif 545 - #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB) 546 - { 547 - .compatible = "realtek,rtl8365mb", 548 - .data = &rtl8365mb_variant, 549 - }, 550 - #endif 551 - { /* sentinel */ }, 552 - }; 553 - MODULE_DEVICE_TABLE(of, realtek_smi_of_match); 554 - 555 - static struct platform_driver realtek_smi_driver = { 556 - .driver = { 557 - .name = "realtek-smi", 558 - .of_match_table = realtek_smi_of_match, 559 - }, 560 - .probe = realtek_smi_probe, 561 - .remove_new = realtek_smi_remove, 562 - .shutdown = realtek_smi_shutdown, 563 - }; 564 - module_platform_driver(realtek_smi_driver); 565 - 566 - MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 567 - MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via SMI interface"); 568 - MODULE_LICENSE("GPL"); 407 + EXPORT_SYMBOL_NS_GPL(realtek_smi_shutdown, REALTEK_DSA);
+48
drivers/net/dsa/realtek/realtek-smi.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + 3 + #ifndef _REALTEK_SMI_H 4 + #define _REALTEK_SMI_H 5 + 6 + #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) 7 + 8 + static inline int realtek_smi_driver_register(struct platform_driver *drv) 9 + { 10 + return platform_driver_register(drv); 11 + } 12 + 13 + static inline void realtek_smi_driver_unregister(struct platform_driver *drv) 14 + { 15 + platform_driver_unregister(drv); 16 + } 17 + 18 + int realtek_smi_probe(struct platform_device *pdev); 19 + void realtek_smi_remove(struct platform_device *pdev); 20 + void realtek_smi_shutdown(struct platform_device *pdev); 21 + 22 + #else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */ 23 + 24 + static inline int realtek_smi_driver_register(struct platform_driver *drv) 25 + { 26 + return 0; 27 + } 28 + 29 + static inline void realtek_smi_driver_unregister(struct platform_driver *drv) 30 + { 31 + } 32 + 33 + static inline int realtek_smi_probe(struct platform_device *pdev) 34 + { 35 + return -ENOENT; 36 + } 37 + 38 + static inline void realtek_smi_remove(struct platform_device *pdev) 39 + { 40 + } 41 + 42 + static inline void realtek_smi_shutdown(struct platform_device *pdev) 43 + { 44 + } 45 + 46 + #endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */ 47 + 48 + #endif /* _REALTEK_SMI_H */
+4 -8
drivers/net/dsa/realtek/realtek.h
··· 58 58 struct mii_bus *bus; 59 59 int mdio_addr; 60 60 61 - unsigned int clk_delay; 62 - u8 cmd_read; 63 - u8 cmd_write; 61 + const struct realtek_variant *variant; 62 + 64 63 spinlock_t lock; /* Locks around command writes */ 65 - struct dsa_switch *ds; 64 + struct dsa_switch ds; 66 65 struct irq_domain *irqdomain; 67 66 bool leds_disabled; 68 67 ··· 72 73 struct rtl8366_mib_counter *mib_counters; 73 74 74 75 const struct realtek_ops *ops; 75 - int (*setup_interface)(struct dsa_switch *ds); 76 76 int (*write_reg_noack)(void *ctx, u32 addr, u32 data); 77 77 78 78 int vlan_enabled; ··· 89 91 int (*detect)(struct realtek_priv *priv); 90 92 int (*reset_chip)(struct realtek_priv *priv); 91 93 int (*setup)(struct realtek_priv *priv); 92 - void (*cleanup)(struct realtek_priv *priv); 93 94 int (*get_mib_counter)(struct realtek_priv *priv, 94 95 int port, 95 96 struct rtl8366_mib_counter *mib, ··· 113 116 }; 114 117 115 118 struct realtek_variant { 116 - const struct dsa_switch_ops *ds_ops_smi; 117 - const struct dsa_switch_ops *ds_ops_mdio; 119 + const struct dsa_switch_ops *ds_ops; 118 120 const struct realtek_ops *ops; 119 121 unsigned int clk_delay; 120 122 u8 cmd_read;
+74 -54
drivers/net/dsa/realtek/rtl8365mb.c
··· 101 101 #include <linux/if_vlan.h> 102 102 103 103 #include "realtek.h" 104 + #include "realtek-smi.h" 105 + #include "realtek-mdio.h" 106 + #include "rtl83xx.h" 104 107 105 108 /* Family-specific data and limits */ 106 109 #define RTL8365MB_PHYADDRMAX 7 ··· 692 689 u32 val; 693 690 int ret; 694 691 695 - mutex_lock(&priv->map_lock); 692 + rtl83xx_lock(priv); 696 693 697 694 ret = rtl8365mb_phy_poll_busy(priv); 698 695 if (ret) ··· 725 722 *data = val & 0xFFFF; 726 723 727 724 out: 728 - mutex_unlock(&priv->map_lock); 725 + rtl83xx_unlock(priv); 729 726 730 727 return ret; 731 728 } ··· 736 733 u32 val; 737 734 int ret; 738 735 739 - mutex_lock(&priv->map_lock); 736 + rtl83xx_lock(priv); 740 737 741 738 ret = rtl8365mb_phy_poll_busy(priv); 742 739 if (ret) ··· 767 764 goto out; 768 765 769 766 out: 770 - mutex_unlock(&priv->map_lock); 767 + rtl83xx_unlock(priv); 771 768 772 769 return 0; 773 770 } ··· 828 825 return 0; 829 826 } 830 827 831 - static int rtl8365mb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum) 832 - { 833 - return rtl8365mb_phy_read(ds->priv, phy, regnum); 834 - } 835 - 836 - static int rtl8365mb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum, 837 - u16 val) 838 - { 839 - return rtl8365mb_phy_write(ds->priv, phy, regnum, val); 840 - } 841 - 842 828 static const struct rtl8365mb_extint * 843 829 rtl8365mb_get_port_extint(struct realtek_priv *priv, int port) 844 830 { ··· 870 878 { 871 879 const struct rtl8365mb_extint *extint = 872 880 rtl8365mb_get_port_extint(priv, port); 881 + struct dsa_switch *ds = &priv->ds; 873 882 struct device_node *dn; 874 883 struct dsa_port *dp; 875 884 int tx_delay = 0; ··· 881 888 if (!extint) 882 889 return -ENODEV; 883 890 884 - dp = dsa_to_port(priv->ds, port); 891 + dp = dsa_to_port(ds, port); 885 892 dn = dp->dn; 886 893 887 894 /* Set the RGMII TX/RX delay ··· 1534 1541 static void rtl8365mb_stats_setup(struct realtek_priv *priv) 1535 1542 { 1536 1543 struct rtl8365mb *mb = priv->chip_data; 1544 + struct dsa_switch *ds = &priv->ds; 1537 1545 int i; 1538 1546 1539 1547 /* Per-chip global mutex to protect MIB counter access, since doing ··· 1545 1551 for (i = 0; i < priv->num_ports; i++) { 1546 1552 struct rtl8365mb_port *p = &mb->ports[i]; 1547 1553 1548 - if (dsa_is_unused_port(priv->ds, i)) 1554 + if (dsa_is_unused_port(ds, i)) 1549 1555 continue; 1550 1556 1551 1557 /* Per-port spinlock to protect the stats64 data */ ··· 1561 1567 static void rtl8365mb_stats_teardown(struct realtek_priv *priv) 1562 1568 { 1563 1569 struct rtl8365mb *mb = priv->chip_data; 1570 + struct dsa_switch *ds = &priv->ds; 1564 1571 int i; 1565 1572 1566 1573 for (i = 0; i < priv->num_ports; i++) { 1567 1574 struct rtl8365mb_port *p = &mb->ports[i]; 1568 1575 1569 - if (dsa_is_unused_port(priv->ds, i)) 1576 + if (dsa_is_unused_port(ds, i)) 1570 1577 continue; 1571 1578 1572 1579 cancel_delayed_work_sync(&p->mib_work); ··· 1966 1971 dev_info(priv->dev, "no interrupt support\n"); 1967 1972 1968 1973 /* Configure CPU tagging */ 1969 - dsa_switch_for_each_cpu_port(cpu_dp, priv->ds) { 1974 + dsa_switch_for_each_cpu_port(cpu_dp, ds) { 1970 1975 cpu->mask |= BIT(cpu_dp->index); 1971 1976 1972 1977 if (cpu->trap_port == RTL8365MB_MAX_NUM_PORTS) ··· 1981 1986 for (i = 0; i < priv->num_ports; i++) { 1982 1987 struct rtl8365mb_port *p = &mb->ports[i]; 1983 1988 1984 - if (dsa_is_unused_port(priv->ds, i)) 1989 + if (dsa_is_unused_port(ds, i)) 1985 1990 continue; 1986 1991 1987 1992 /* Forward only to the CPU */ ··· 1998 2003 * ports will still forward frames to the CPU despite being 1999 2004 * administratively down by default. 2000 2005 */ 2001 - rtl8365mb_port_stp_state_set(priv->ds, i, BR_STATE_DISABLED); 2006 + rtl8365mb_port_stp_state_set(ds, i, BR_STATE_DISABLED); 2002 2007 2003 2008 /* Set up per-port private data */ 2004 2009 p->priv = priv; ··· 2009 2014 if (ret) 2010 2015 goto out_teardown_irq; 2011 2016 2012 - if (priv->setup_interface) { 2013 - ret = priv->setup_interface(ds); 2014 - if (ret) { 2015 - dev_err(priv->dev, "could not set up MDIO bus\n"); 2016 - goto out_teardown_irq; 2017 - } 2017 + ret = rtl83xx_setup_user_mdio(ds); 2018 + if (ret) { 2019 + dev_err(priv->dev, "could not set up MDIO bus\n"); 2020 + goto out_teardown_irq; 2018 2021 } 2019 2022 2020 2023 /* Start statistics counter polling */ ··· 2106 2113 return 0; 2107 2114 } 2108 2115 2109 - static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = { 2116 + static const struct dsa_switch_ops rtl8365mb_switch_ops = { 2110 2117 .get_tag_protocol = rtl8365mb_get_tag_protocol, 2111 2118 .change_tag_protocol = rtl8365mb_change_tag_protocol, 2112 2119 .setup = rtl8365mb_setup, ··· 2115 2122 .phylink_mac_config = rtl8365mb_phylink_mac_config, 2116 2123 .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down, 2117 2124 .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up, 2118 - .port_stp_state_set = rtl8365mb_port_stp_state_set, 2119 - .get_strings = rtl8365mb_get_strings, 2120 - .get_ethtool_stats = rtl8365mb_get_ethtool_stats, 2121 - .get_sset_count = rtl8365mb_get_sset_count, 2122 - .get_eth_phy_stats = rtl8365mb_get_phy_stats, 2123 - .get_eth_mac_stats = rtl8365mb_get_mac_stats, 2124 - .get_eth_ctrl_stats = rtl8365mb_get_ctrl_stats, 2125 - .get_stats64 = rtl8365mb_get_stats64, 2126 - .port_change_mtu = rtl8365mb_port_change_mtu, 2127 - .port_max_mtu = rtl8365mb_port_max_mtu, 2128 - }; 2129 - 2130 - static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = { 2131 - .get_tag_protocol = rtl8365mb_get_tag_protocol, 2132 - .change_tag_protocol = rtl8365mb_change_tag_protocol, 2133 - .setup = rtl8365mb_setup, 2134 - .teardown = rtl8365mb_teardown, 2135 - .phylink_get_caps = rtl8365mb_phylink_get_caps, 2136 - .phylink_mac_config = rtl8365mb_phylink_mac_config, 2137 - .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down, 2138 - .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up, 2139 - .phy_read = rtl8365mb_dsa_phy_read, 2140 - .phy_write = rtl8365mb_dsa_phy_write, 2141 2125 .port_stp_state_set = rtl8365mb_port_stp_state_set, 2142 2126 .get_strings = rtl8365mb_get_strings, 2143 2127 .get_ethtool_stats = rtl8365mb_get_ethtool_stats, ··· 2134 2164 }; 2135 2165 2136 2166 const struct realtek_variant rtl8365mb_variant = { 2137 - .ds_ops_smi = &rtl8365mb_switch_ops_smi, 2138 - .ds_ops_mdio = &rtl8365mb_switch_ops_mdio, 2167 + .ds_ops = &rtl8365mb_switch_ops, 2139 2168 .ops = &rtl8365mb_ops, 2140 2169 .clk_delay = 10, 2141 2170 .cmd_read = 0xb9, 2142 2171 .cmd_write = 0xb8, 2143 2172 .chip_data_sz = sizeof(struct rtl8365mb), 2144 2173 }; 2145 - EXPORT_SYMBOL_GPL(rtl8365mb_variant); 2174 + 2175 + static const struct of_device_id rtl8365mb_of_match[] = { 2176 + { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, }, 2177 + { /* sentinel */ }, 2178 + }; 2179 + MODULE_DEVICE_TABLE(of, rtl8365mb_of_match); 2180 + 2181 + static struct platform_driver rtl8365mb_smi_driver = { 2182 + .driver = { 2183 + .name = "rtl8365mb-smi", 2184 + .of_match_table = rtl8365mb_of_match, 2185 + }, 2186 + .probe = realtek_smi_probe, 2187 + .remove_new = realtek_smi_remove, 2188 + .shutdown = realtek_smi_shutdown, 2189 + }; 2190 + 2191 + static struct mdio_driver rtl8365mb_mdio_driver = { 2192 + .mdiodrv.driver = { 2193 + .name = "rtl8365mb-mdio", 2194 + .of_match_table = rtl8365mb_of_match, 2195 + }, 2196 + .probe = realtek_mdio_probe, 2197 + .remove = realtek_mdio_remove, 2198 + .shutdown = realtek_mdio_shutdown, 2199 + }; 2200 + 2201 + static int rtl8365mb_init(void) 2202 + { 2203 + int ret; 2204 + 2205 + ret = realtek_mdio_driver_register(&rtl8365mb_mdio_driver); 2206 + if (ret) 2207 + return ret; 2208 + 2209 + ret = realtek_smi_driver_register(&rtl8365mb_smi_driver); 2210 + if (ret) { 2211 + realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver); 2212 + return ret; 2213 + } 2214 + 2215 + return 0; 2216 + } 2217 + module_init(rtl8365mb_init); 2218 + 2219 + static void __exit rtl8365mb_exit(void) 2220 + { 2221 + realtek_smi_driver_unregister(&rtl8365mb_smi_driver); 2222 + realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver); 2223 + } 2224 + module_exit(rtl8365mb_exit); 2146 2225 2147 2226 MODULE_AUTHOR("Alvin Šipraga <alsi@bang-olufsen.dk>"); 2148 2227 MODULE_DESCRIPTION("Driver for RTL8365MB-VC ethernet switch"); 2149 2228 MODULE_LICENSE("GPL"); 2229 + MODULE_IMPORT_NS(REALTEK_DSA);
+11 -11
drivers/net/dsa/realtek/rtl8366-core.c
··· 34 34 35 35 return 0; 36 36 } 37 - EXPORT_SYMBOL_GPL(rtl8366_mc_is_used); 37 + EXPORT_SYMBOL_NS_GPL(rtl8366_mc_is_used, REALTEK_DSA); 38 38 39 39 /** 40 40 * rtl8366_obtain_mc() - retrieve or allocate a VLAN member configuration ··· 187 187 188 188 return ret; 189 189 } 190 - EXPORT_SYMBOL_GPL(rtl8366_set_vlan); 190 + EXPORT_SYMBOL_NS_GPL(rtl8366_set_vlan, REALTEK_DSA); 191 191 192 192 int rtl8366_set_pvid(struct realtek_priv *priv, unsigned int port, 193 193 unsigned int vid) ··· 217 217 218 218 return 0; 219 219 } 220 - EXPORT_SYMBOL_GPL(rtl8366_set_pvid); 220 + EXPORT_SYMBOL_NS_GPL(rtl8366_set_pvid, REALTEK_DSA); 221 221 222 222 int rtl8366_enable_vlan4k(struct realtek_priv *priv, bool enable) 223 223 { ··· 243 243 priv->vlan4k_enabled = enable; 244 244 return 0; 245 245 } 246 - EXPORT_SYMBOL_GPL(rtl8366_enable_vlan4k); 246 + EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan4k, REALTEK_DSA); 247 247 248 248 int rtl8366_enable_vlan(struct realtek_priv *priv, bool enable) 249 249 { ··· 265 265 266 266 return ret; 267 267 } 268 - EXPORT_SYMBOL_GPL(rtl8366_enable_vlan); 268 + EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan, REALTEK_DSA); 269 269 270 270 int rtl8366_reset_vlan(struct realtek_priv *priv) 271 271 { ··· 290 290 291 291 return 0; 292 292 } 293 - EXPORT_SYMBOL_GPL(rtl8366_reset_vlan); 293 + EXPORT_SYMBOL_NS_GPL(rtl8366_reset_vlan, REALTEK_DSA); 294 294 295 295 int rtl8366_vlan_add(struct dsa_switch *ds, int port, 296 296 const struct switchdev_obj_port_vlan *vlan, ··· 345 345 346 346 return 0; 347 347 } 348 - EXPORT_SYMBOL_GPL(rtl8366_vlan_add); 348 + EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_add, REALTEK_DSA); 349 349 350 350 int rtl8366_vlan_del(struct dsa_switch *ds, int port, 351 351 const struct switchdev_obj_port_vlan *vlan) ··· 389 389 390 390 return 0; 391 391 } 392 - EXPORT_SYMBOL_GPL(rtl8366_vlan_del); 392 + EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_del, REALTEK_DSA); 393 393 394 394 void rtl8366_get_strings(struct dsa_switch *ds, int port, u32 stringset, 395 395 uint8_t *data) ··· 403 403 for (i = 0; i < priv->num_mib_counters; i++) 404 404 ethtool_puts(&data, priv->mib_counters[i].name); 405 405 } 406 - EXPORT_SYMBOL_GPL(rtl8366_get_strings); 406 + EXPORT_SYMBOL_NS_GPL(rtl8366_get_strings, REALTEK_DSA); 407 407 408 408 int rtl8366_get_sset_count(struct dsa_switch *ds, int port, int sset) 409 409 { ··· 417 417 418 418 return priv->num_mib_counters; 419 419 } 420 - EXPORT_SYMBOL_GPL(rtl8366_get_sset_count); 420 + EXPORT_SYMBOL_NS_GPL(rtl8366_get_sset_count, REALTEK_DSA); 421 421 422 422 void rtl8366_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) 423 423 { ··· 441 441 data[i] = mibvalue; 442 442 } 443 443 } 444 - EXPORT_SYMBOL_GPL(rtl8366_get_ethtool_stats); 444 + EXPORT_SYMBOL_NS_GPL(rtl8366_get_ethtool_stats, REALTEK_DSA);
+67 -52
drivers/net/dsa/realtek/rtl8366rb.c
··· 23 23 #include <linux/regmap.h> 24 24 25 25 #include "realtek.h" 26 + #include "realtek-smi.h" 27 + #include "realtek-mdio.h" 28 + #include "rtl83xx.h" 26 29 27 30 #define RTL8366RB_PORT_NUM_CPU 5 28 31 #define RTL8366RB_NUM_PORTS 6 ··· 1033 1030 if (ret) 1034 1031 dev_info(priv->dev, "no interrupt support\n"); 1035 1032 1036 - if (priv->setup_interface) { 1037 - ret = priv->setup_interface(ds); 1038 - if (ret) { 1039 - dev_err(priv->dev, "could not set up MDIO bus\n"); 1040 - return -ENODEV; 1041 - } 1033 + ret = rtl83xx_setup_user_mdio(ds); 1034 + if (ret) { 1035 + dev_err(priv->dev, "could not set up MDIO bus\n"); 1036 + return -ENODEV; 1042 1037 } 1043 1038 1044 1039 return 0; ··· 1651 1650 1652 1651 static int rtl8366rb_set_mc_index(struct realtek_priv *priv, int port, int index) 1653 1652 { 1653 + struct dsa_switch *ds = &priv->ds; 1654 1654 struct rtl8366rb *rb; 1655 1655 bool pvid_enabled; 1656 1656 int ret; ··· 1676 1674 * not drop any untagged or C-tagged frames. Make sure to update the 1677 1675 * filtering setting. 1678 1676 */ 1679 - if (dsa_port_is_vlan_filtering(dsa_to_port(priv->ds, port))) 1677 + if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) 1680 1678 ret = rtl8366rb_drop_untagged(priv, port, !pvid_enabled); 1681 1679 1682 1680 return ret; ··· 1720 1718 if (phy > RTL8366RB_PHY_NO_MAX) 1721 1719 return -EINVAL; 1722 1720 1723 - mutex_lock(&priv->map_lock); 1721 + rtl83xx_lock(priv); 1724 1722 1725 1723 ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG, 1726 1724 RTL8366RB_PHY_CTRL_READ); ··· 1748 1746 phy, regnum, reg, val); 1749 1747 1750 1748 out: 1751 - mutex_unlock(&priv->map_lock); 1749 + rtl83xx_unlock(priv); 1752 1750 1753 1751 return ret; 1754 1752 } ··· 1762 1760 if (phy > RTL8366RB_PHY_NO_MAX) 1763 1761 return -EINVAL; 1764 1762 1765 - mutex_lock(&priv->map_lock); 1763 + rtl83xx_lock(priv); 1766 1764 1767 1765 ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG, 1768 1766 RTL8366RB_PHY_CTRL_WRITE); ··· 1779 1777 goto out; 1780 1778 1781 1779 out: 1782 - mutex_unlock(&priv->map_lock); 1780 + rtl83xx_unlock(priv); 1783 1781 1784 1782 return ret; 1785 - } 1786 - 1787 - static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum) 1788 - { 1789 - return rtl8366rb_phy_read(ds->priv, phy, regnum); 1790 - } 1791 - 1792 - static int rtl8366rb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum, 1793 - u16 val) 1794 - { 1795 - return rtl8366rb_phy_write(ds->priv, phy, regnum, val); 1796 1783 } 1797 1784 1798 1785 static int rtl8366rb_reset_chip(struct realtek_priv *priv) ··· 1849 1858 return 0; 1850 1859 } 1851 1860 1852 - static const struct dsa_switch_ops rtl8366rb_switch_ops_smi = { 1861 + static const struct dsa_switch_ops rtl8366rb_switch_ops = { 1853 1862 .get_tag_protocol = rtl8366_get_tag_protocol, 1854 1863 .setup = rtl8366rb_setup, 1855 - .phylink_get_caps = rtl8366rb_phylink_get_caps, 1856 - .phylink_mac_link_up = rtl8366rb_mac_link_up, 1857 - .phylink_mac_link_down = rtl8366rb_mac_link_down, 1858 - .get_strings = rtl8366_get_strings, 1859 - .get_ethtool_stats = rtl8366_get_ethtool_stats, 1860 - .get_sset_count = rtl8366_get_sset_count, 1861 - .port_bridge_join = rtl8366rb_port_bridge_join, 1862 - .port_bridge_leave = rtl8366rb_port_bridge_leave, 1863 - .port_vlan_filtering = rtl8366rb_vlan_filtering, 1864 - .port_vlan_add = rtl8366_vlan_add, 1865 - .port_vlan_del = rtl8366_vlan_del, 1866 - .port_enable = rtl8366rb_port_enable, 1867 - .port_disable = rtl8366rb_port_disable, 1868 - .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags, 1869 - .port_bridge_flags = rtl8366rb_port_bridge_flags, 1870 - .port_stp_state_set = rtl8366rb_port_stp_state_set, 1871 - .port_fast_age = rtl8366rb_port_fast_age, 1872 - .port_change_mtu = rtl8366rb_change_mtu, 1873 - .port_max_mtu = rtl8366rb_max_mtu, 1874 - }; 1875 - 1876 - static const struct dsa_switch_ops rtl8366rb_switch_ops_mdio = { 1877 - .get_tag_protocol = rtl8366_get_tag_protocol, 1878 - .setup = rtl8366rb_setup, 1879 - .phy_read = rtl8366rb_dsa_phy_read, 1880 - .phy_write = rtl8366rb_dsa_phy_write, 1881 1864 .phylink_get_caps = rtl8366rb_phylink_get_caps, 1882 1865 .phylink_mac_link_up = rtl8366rb_mac_link_up, 1883 1866 .phylink_mac_link_down = rtl8366rb_mac_link_down, ··· 1890 1925 }; 1891 1926 1892 1927 const struct realtek_variant rtl8366rb_variant = { 1893 - .ds_ops_smi = &rtl8366rb_switch_ops_smi, 1894 - .ds_ops_mdio = &rtl8366rb_switch_ops_mdio, 1928 + .ds_ops = &rtl8366rb_switch_ops, 1895 1929 .ops = &rtl8366rb_ops, 1896 1930 .clk_delay = 10, 1897 1931 .cmd_read = 0xa9, 1898 1932 .cmd_write = 0xa8, 1899 1933 .chip_data_sz = sizeof(struct rtl8366rb), 1900 1934 }; 1901 - EXPORT_SYMBOL_GPL(rtl8366rb_variant); 1935 + 1936 + static const struct of_device_id rtl8366rb_of_match[] = { 1937 + { .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, }, 1938 + { /* sentinel */ }, 1939 + }; 1940 + MODULE_DEVICE_TABLE(of, rtl8366rb_of_match); 1941 + 1942 + static struct platform_driver rtl8366rb_smi_driver = { 1943 + .driver = { 1944 + .name = "rtl8366rb-smi", 1945 + .of_match_table = rtl8366rb_of_match, 1946 + }, 1947 + .probe = realtek_smi_probe, 1948 + .remove_new = realtek_smi_remove, 1949 + .shutdown = realtek_smi_shutdown, 1950 + }; 1951 + 1952 + static struct mdio_driver rtl8366rb_mdio_driver = { 1953 + .mdiodrv.driver = { 1954 + .name = "rtl8366rb-mdio", 1955 + .of_match_table = rtl8366rb_of_match, 1956 + }, 1957 + .probe = realtek_mdio_probe, 1958 + .remove = realtek_mdio_remove, 1959 + .shutdown = realtek_mdio_shutdown, 1960 + }; 1961 + 1962 + static int rtl8366rb_init(void) 1963 + { 1964 + int ret; 1965 + 1966 + ret = realtek_mdio_driver_register(&rtl8366rb_mdio_driver); 1967 + if (ret) 1968 + return ret; 1969 + 1970 + ret = realtek_smi_driver_register(&rtl8366rb_smi_driver); 1971 + if (ret) { 1972 + realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver); 1973 + return ret; 1974 + } 1975 + 1976 + return 0; 1977 + } 1978 + module_init(rtl8366rb_init); 1979 + 1980 + static void __exit rtl8366rb_exit(void) 1981 + { 1982 + realtek_smi_driver_unregister(&rtl8366rb_smi_driver); 1983 + realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver); 1984 + } 1985 + module_exit(rtl8366rb_exit); 1902 1986 1903 1987 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 1904 1988 MODULE_DESCRIPTION("Driver for RTL8366RB ethernet switch"); 1905 1989 MODULE_LICENSE("GPL"); 1990 + MODULE_IMPORT_NS(REALTEK_DSA);
+303
drivers/net/dsa/realtek/rtl83xx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + 3 + #include <linux/module.h> 4 + #include <linux/regmap.h> 5 + #include <linux/of_mdio.h> 6 + 7 + #include "realtek.h" 8 + #include "rtl83xx.h" 9 + 10 + /** 11 + * rtl83xx_lock() - Locks the mutex used by regmaps 12 + * @ctx: realtek_priv pointer 13 + * 14 + * This function is passed to regmap to be used as the lock function. 15 + * It is also used externally to block regmap before executing multiple 16 + * operations that must happen in sequence (which will use 17 + * realtek_priv.map_nolock instead). 18 + * 19 + * Context: Can sleep. Holds priv->map_lock lock. 20 + * Return: nothing 21 + */ 22 + void rtl83xx_lock(void *ctx) 23 + { 24 + struct realtek_priv *priv = ctx; 25 + 26 + mutex_lock(&priv->map_lock); 27 + } 28 + EXPORT_SYMBOL_NS_GPL(rtl83xx_lock, REALTEK_DSA); 29 + 30 + /** 31 + * rtl83xx_unlock() - Unlocks the mutex used by regmaps 32 + * @ctx: realtek_priv pointer 33 + * 34 + * This function unlocks the lock acquired by rtl83xx_lock. 35 + * 36 + * Context: Releases priv->map_lock lock. 37 + * Return: nothing 38 + */ 39 + void rtl83xx_unlock(void *ctx) 40 + { 41 + struct realtek_priv *priv = ctx; 42 + 43 + mutex_unlock(&priv->map_lock); 44 + } 45 + EXPORT_SYMBOL_NS_GPL(rtl83xx_unlock, REALTEK_DSA); 46 + 47 + static int rtl83xx_user_mdio_read(struct mii_bus *bus, int addr, int regnum) 48 + { 49 + struct realtek_priv *priv = bus->priv; 50 + 51 + return priv->ops->phy_read(priv, addr, regnum); 52 + } 53 + 54 + static int rtl83xx_user_mdio_write(struct mii_bus *bus, int addr, int regnum, 55 + u16 val) 56 + { 57 + struct realtek_priv *priv = bus->priv; 58 + 59 + return priv->ops->phy_write(priv, addr, regnum, val); 60 + } 61 + 62 + /** 63 + * rtl83xx_setup_user_mdio() - register the user mii bus driver 64 + * @ds: DSA switch associated with this user_mii_bus 65 + * 66 + * Registers the MDIO bus for built-in Ethernet PHYs, and associates it with 67 + * the mandatory 'mdio' child OF node of the switch. 68 + * 69 + * Context: Can sleep. 70 + * Return: 0 on success, negative value for failure. 71 + */ 72 + int rtl83xx_setup_user_mdio(struct dsa_switch *ds) 73 + { 74 + struct realtek_priv *priv = ds->priv; 75 + struct device_node *mdio_np; 76 + struct mii_bus *bus; 77 + int ret = 0; 78 + 79 + mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio"); 80 + if (!mdio_np) { 81 + dev_err(priv->dev, "no MDIO bus node\n"); 82 + return -ENODEV; 83 + } 84 + 85 + bus = devm_mdiobus_alloc(priv->dev); 86 + if (!bus) { 87 + ret = -ENOMEM; 88 + goto err_put_node; 89 + } 90 + 91 + bus->priv = priv; 92 + bus->name = "Realtek user MII"; 93 + bus->read = rtl83xx_user_mdio_read; 94 + bus->write = rtl83xx_user_mdio_write; 95 + snprintf(bus->id, MII_BUS_ID_SIZE, "%s:user_mii", dev_name(priv->dev)); 96 + bus->parent = priv->dev; 97 + 98 + ret = devm_of_mdiobus_register(priv->dev, bus, mdio_np); 99 + if (ret) { 100 + dev_err(priv->dev, "unable to register MDIO bus %s\n", 101 + bus->id); 102 + goto err_put_node; 103 + } 104 + 105 + priv->user_mii_bus = bus; 106 + 107 + err_put_node: 108 + of_node_put(mdio_np); 109 + 110 + return ret; 111 + } 112 + EXPORT_SYMBOL_NS_GPL(rtl83xx_setup_user_mdio, REALTEK_DSA); 113 + 114 + /** 115 + * rtl83xx_probe() - probe a Realtek switch 116 + * @dev: the device being probed 117 + * @interface_info: specific management interface info. 118 + * 119 + * This function initializes realtek_priv and reads data from the device tree 120 + * node. The switch is hard resetted if a method is provided. 121 + * 122 + * Context: Can sleep. 123 + * Return: Pointer to the realtek_priv or ERR_PTR() in case of failure. 124 + * 125 + * The realtek_priv pointer does not need to be freed as it is controlled by 126 + * devres. 127 + */ 128 + struct realtek_priv * 129 + rtl83xx_probe(struct device *dev, 130 + const struct realtek_interface_info *interface_info) 131 + { 132 + const struct realtek_variant *var; 133 + struct realtek_priv *priv; 134 + struct regmap_config rc = { 135 + .reg_bits = 10, /* A4..A0 R4..R0 */ 136 + .val_bits = 16, 137 + .reg_stride = 1, 138 + .max_register = 0xffff, 139 + .reg_format_endian = REGMAP_ENDIAN_BIG, 140 + .reg_read = interface_info->reg_read, 141 + .reg_write = interface_info->reg_write, 142 + .cache_type = REGCACHE_NONE, 143 + .lock = rtl83xx_lock, 144 + .unlock = rtl83xx_unlock, 145 + }; 146 + int ret; 147 + 148 + var = of_device_get_match_data(dev); 149 + if (!var) 150 + return ERR_PTR(-EINVAL); 151 + 152 + priv = devm_kzalloc(dev, size_add(sizeof(*priv), var->chip_data_sz), 153 + GFP_KERNEL); 154 + if (!priv) 155 + return ERR_PTR(-ENOMEM); 156 + 157 + mutex_init(&priv->map_lock); 158 + 159 + rc.lock_arg = priv; 160 + priv->map = devm_regmap_init(dev, NULL, priv, &rc); 161 + if (IS_ERR(priv->map)) { 162 + ret = PTR_ERR(priv->map); 163 + dev_err(dev, "regmap init failed: %d\n", ret); 164 + return ERR_PTR(ret); 165 + } 166 + 167 + rc.disable_locking = true; 168 + priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc); 169 + if (IS_ERR(priv->map_nolock)) { 170 + ret = PTR_ERR(priv->map_nolock); 171 + dev_err(dev, "regmap init failed: %d\n", ret); 172 + return ERR_PTR(ret); 173 + } 174 + 175 + /* Link forward and backward */ 176 + priv->dev = dev; 177 + priv->variant = var; 178 + priv->ops = var->ops; 179 + priv->chip_data = (void *)priv + sizeof(*priv); 180 + 181 + spin_lock_init(&priv->lock); 182 + 183 + priv->leds_disabled = of_property_read_bool(dev->of_node, 184 + "realtek,disable-leds"); 185 + 186 + /* TODO: if power is software controlled, set up any regulators here */ 187 + priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 188 + if (IS_ERR(priv->reset)) { 189 + dev_err(dev, "failed to get RESET GPIO\n"); 190 + return ERR_CAST(priv->reset); 191 + } 192 + 193 + dev_set_drvdata(dev, priv); 194 + 195 + if (priv->reset) { 196 + gpiod_set_value(priv->reset, 1); 197 + dev_dbg(dev, "asserted RESET\n"); 198 + msleep(REALTEK_HW_STOP_DELAY); 199 + gpiod_set_value(priv->reset, 0); 200 + msleep(REALTEK_HW_START_DELAY); 201 + dev_dbg(dev, "deasserted RESET\n"); 202 + } 203 + 204 + return priv; 205 + } 206 + EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, REALTEK_DSA); 207 + 208 + /** 209 + * rtl83xx_register_switch() - detects and register a switch 210 + * @priv: realtek_priv pointer 211 + * 212 + * This function first checks the switch chip ID and register a DSA 213 + * switch. 214 + * 215 + * Context: Can sleep. Takes and releases priv->map_lock. 216 + * Return: 0 on success, negative value for failure. 217 + */ 218 + int rtl83xx_register_switch(struct realtek_priv *priv) 219 + { 220 + struct dsa_switch *ds = &priv->ds; 221 + int ret; 222 + 223 + ret = priv->ops->detect(priv); 224 + if (ret) { 225 + dev_err_probe(priv->dev, ret, "unable to detect switch\n"); 226 + return ret; 227 + } 228 + 229 + ds->priv = priv; 230 + ds->dev = priv->dev; 231 + ds->ops = priv->variant->ds_ops; 232 + ds->num_ports = priv->num_ports; 233 + 234 + ret = dsa_register_switch(ds); 235 + if (ret) { 236 + dev_err_probe(priv->dev, ret, "unable to register switch\n"); 237 + return ret; 238 + } 239 + 240 + return 0; 241 + } 242 + EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, REALTEK_DSA); 243 + 244 + /** 245 + * rtl83xx_unregister_switch() - unregister a switch 246 + * @priv: realtek_priv pointer 247 + * 248 + * This function unregister a DSA switch. 249 + * 250 + * Context: Can sleep. 251 + * Return: Nothing. 252 + */ 253 + void rtl83xx_unregister_switch(struct realtek_priv *priv) 254 + { 255 + struct dsa_switch *ds = &priv->ds; 256 + 257 + dsa_unregister_switch(ds); 258 + } 259 + EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, REALTEK_DSA); 260 + 261 + /** 262 + * rtl83xx_shutdown() - shutdown a switch 263 + * @priv: realtek_priv pointer 264 + * 265 + * This function shuts down the DSA switch and cleans the platform driver data, 266 + * to prevent realtek_{smi,mdio}_remove() from running afterwards, which is 267 + * possible if the parent bus implements its own .shutdown() as .remove(). 268 + * 269 + * Context: Can sleep. 270 + * Return: Nothing. 271 + */ 272 + void rtl83xx_shutdown(struct realtek_priv *priv) 273 + { 274 + struct dsa_switch *ds = &priv->ds; 275 + 276 + dsa_switch_shutdown(ds); 277 + 278 + dev_set_drvdata(priv->dev, NULL); 279 + } 280 + EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA); 281 + 282 + /** 283 + * rtl83xx_remove() - Cleanup a realtek switch driver 284 + * @priv: realtek_priv pointer 285 + * 286 + * If a method is provided, this function asserts the hard reset of the switch 287 + * in order to avoid leaking traffic when the driver is gone. 288 + * 289 + * Context: Might sleep if priv->gdev->chip->can_sleep. 290 + * Return: nothing 291 + */ 292 + void rtl83xx_remove(struct realtek_priv *priv) 293 + { 294 + /* leave the device reset asserted */ 295 + if (priv->reset) 296 + gpiod_set_value(priv->reset, 1); 297 + } 298 + EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA); 299 + 300 + MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>"); 301 + MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 302 + MODULE_DESCRIPTION("Realtek DSA switches common module"); 303 + MODULE_LICENSE("GPL");
+22
drivers/net/dsa/realtek/rtl83xx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + 3 + #ifndef _RTL83XX_H 4 + #define _RTL83XX_H 5 + 6 + struct realtek_interface_info { 7 + int (*reg_read)(void *ctx, u32 reg, u32 *val); 8 + int (*reg_write)(void *ctx, u32 reg, u32 val); 9 + }; 10 + 11 + void rtl83xx_lock(void *ctx); 12 + void rtl83xx_unlock(void *ctx); 13 + int rtl83xx_setup_user_mdio(struct dsa_switch *ds); 14 + struct realtek_priv * 15 + rtl83xx_probe(struct device *dev, 16 + const struct realtek_interface_info *interface_info); 17 + int rtl83xx_register_switch(struct realtek_priv *priv); 18 + void rtl83xx_unregister_switch(struct realtek_priv *priv); 19 + void rtl83xx_shutdown(struct realtek_priv *priv); 20 + void rtl83xx_remove(struct realtek_priv *priv); 21 + 22 + #endif /* _RTL83XX_H */