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