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_ctl = devm_reset_control_get_optional(dev, NULL); 188 if (IS_ERR(priv->reset_ctl)) 189 return dev_err_cast_probe(dev, priv->reset_ctl, 190 "failed to get reset control\n"); 191 192 priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 193 if (IS_ERR(priv->reset)) { 194 dev_err(dev, "failed to get RESET GPIO\n"); 195 return ERR_CAST(priv->reset); 196 } 197 198 dev_set_drvdata(dev, priv); 199 200 if (priv->reset_ctl || priv->reset) { 201 rtl83xx_reset_assert(priv); 202 dev_dbg(dev, "asserted RESET\n"); 203 msleep(REALTEK_HW_STOP_DELAY); 204 rtl83xx_reset_deassert(priv); 205 msleep(REALTEK_HW_START_DELAY); 206 dev_dbg(dev, "deasserted RESET\n"); 207 } 208 209 return priv; 210 } 211 EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, REALTEK_DSA); 212 213 /** 214 * rtl83xx_register_switch() - detects and register a switch 215 * @priv: realtek_priv pointer 216 * 217 * This function first checks the switch chip ID and register a DSA 218 * switch. 219 * 220 * Context: Can sleep. Takes and releases priv->map_lock. 221 * Return: 0 on success, negative value for failure. 222 */ 223 int rtl83xx_register_switch(struct realtek_priv *priv) 224 { 225 struct dsa_switch *ds = &priv->ds; 226 int ret; 227 228 ret = priv->ops->detect(priv); 229 if (ret) { 230 dev_err_probe(priv->dev, ret, "unable to detect switch\n"); 231 return ret; 232 } 233 234 ds->priv = priv; 235 ds->dev = priv->dev; 236 ds->ops = priv->variant->ds_ops; 237 ds->phylink_mac_ops = priv->variant->phylink_mac_ops; 238 ds->num_ports = priv->num_ports; 239 240 ret = dsa_register_switch(ds); 241 if (ret) { 242 dev_err_probe(priv->dev, ret, "unable to register switch\n"); 243 return ret; 244 } 245 246 return 0; 247 } 248 EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, REALTEK_DSA); 249 250 /** 251 * rtl83xx_unregister_switch() - unregister a switch 252 * @priv: realtek_priv pointer 253 * 254 * This function unregister a DSA switch. 255 * 256 * Context: Can sleep. 257 * Return: Nothing. 258 */ 259 void rtl83xx_unregister_switch(struct realtek_priv *priv) 260 { 261 struct dsa_switch *ds = &priv->ds; 262 263 dsa_unregister_switch(ds); 264 } 265 EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, REALTEK_DSA); 266 267 /** 268 * rtl83xx_shutdown() - shutdown a switch 269 * @priv: realtek_priv pointer 270 * 271 * This function shuts down the DSA switch and cleans the platform driver data, 272 * to prevent realtek_{smi,mdio}_remove() from running afterwards, which is 273 * possible if the parent bus implements its own .shutdown() as .remove(). 274 * 275 * Context: Can sleep. 276 * Return: Nothing. 277 */ 278 void rtl83xx_shutdown(struct realtek_priv *priv) 279 { 280 struct dsa_switch *ds = &priv->ds; 281 282 dsa_switch_shutdown(ds); 283 284 dev_set_drvdata(priv->dev, NULL); 285 } 286 EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA); 287 288 /** 289 * rtl83xx_remove() - Cleanup a realtek switch driver 290 * @priv: realtek_priv pointer 291 * 292 * Placehold for common cleanup procedures. 293 * 294 * Context: Any 295 * Return: nothing 296 */ 297 void rtl83xx_remove(struct realtek_priv *priv) 298 { 299 } 300 EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA); 301 302 void rtl83xx_reset_assert(struct realtek_priv *priv) 303 { 304 int ret; 305 306 ret = reset_control_assert(priv->reset_ctl); 307 if (ret) 308 dev_warn(priv->dev, 309 "Failed to assert the switch reset control: %pe\n", 310 ERR_PTR(ret)); 311 312 gpiod_set_value(priv->reset, true); 313 } 314 315 void rtl83xx_reset_deassert(struct realtek_priv *priv) 316 { 317 int ret; 318 319 ret = reset_control_deassert(priv->reset_ctl); 320 if (ret) 321 dev_warn(priv->dev, 322 "Failed to deassert the switch reset control: %pe\n", 323 ERR_PTR(ret)); 324 325 gpiod_set_value(priv->reset, false); 326 } 327 328 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>"); 329 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 330 MODULE_DESCRIPTION("Realtek DSA switches common module"); 331 MODULE_LICENSE("GPL"); 332