1 // SPDX-License-Identifier: GPL-2.0+ 2 /* Framework for MDIO devices, other than PHYs. 3 * 4 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch> 5 */ 6 7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 9 #include <linux/delay.h> 10 #include <linux/errno.h> 11 #include <linux/gpio.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/kernel.h> 16 #include <linux/mdio.h> 17 #include <linux/mii.h> 18 #include <linux/module.h> 19 #include <linux/phy.h> 20 #include <linux/reset.h> 21 #include <linux/slab.h> 22 #include <linux/string.h> 23 #include <linux/unistd.h> 24 #include <linux/property.h> 25 #include "phylib-internal.h" 26 27 /** 28 * mdio_device_register_reset - Read and initialize the reset properties of 29 * an mdio device 30 * @mdiodev: mdio_device structure 31 * 32 * Return: Zero if successful, negative error code on failure 33 */ 34 static int mdio_device_register_reset(struct mdio_device *mdiodev) 35 { 36 struct reset_control *reset; 37 38 /* Deassert the optional reset signal */ 39 mdiodev->reset_gpio = gpiod_get_optional(&mdiodev->dev, 40 "reset", GPIOD_OUT_LOW); 41 if (IS_ERR(mdiodev->reset_gpio)) 42 return PTR_ERR(mdiodev->reset_gpio); 43 44 if (mdiodev->reset_gpio) 45 gpiod_set_consumer_name(mdiodev->reset_gpio, "PHY reset"); 46 47 reset = reset_control_get_optional_exclusive(&mdiodev->dev, "phy"); 48 if (IS_ERR(reset)) { 49 gpiod_put(mdiodev->reset_gpio); 50 mdiodev->reset_gpio = NULL; 51 return PTR_ERR(reset); 52 } 53 54 mdiodev->reset_ctrl = reset; 55 56 /* Read optional firmware properties */ 57 device_property_read_u32(&mdiodev->dev, "reset-assert-us", 58 &mdiodev->reset_assert_delay); 59 device_property_read_u32(&mdiodev->dev, "reset-deassert-us", 60 &mdiodev->reset_deassert_delay); 61 62 return 0; 63 } 64 65 /** 66 * mdio_device_unregister_reset - uninitialize the reset properties of 67 * an mdio device 68 * @mdiodev: mdio_device structure 69 */ 70 static void mdio_device_unregister_reset(struct mdio_device *mdiodev) 71 { 72 gpiod_put(mdiodev->reset_gpio); 73 mdiodev->reset_gpio = NULL; 74 reset_control_put(mdiodev->reset_ctrl); 75 mdiodev->reset_ctrl = NULL; 76 mdiodev->reset_assert_delay = 0; 77 mdiodev->reset_deassert_delay = 0; 78 } 79 80 void mdio_device_reset(struct mdio_device *mdiodev, int value) 81 { 82 unsigned int d; 83 84 if (!mdiodev->reset_gpio && !mdiodev->reset_ctrl) 85 return; 86 87 if (mdiodev->reset_state == value) 88 return; 89 90 if (mdiodev->reset_gpio) 91 gpiod_set_value_cansleep(mdiodev->reset_gpio, value); 92 93 if (mdiodev->reset_ctrl) { 94 if (value) 95 reset_control_assert(mdiodev->reset_ctrl); 96 else 97 reset_control_deassert(mdiodev->reset_ctrl); 98 } 99 100 d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay; 101 if (d) 102 fsleep(d); 103 104 mdiodev->reset_state = value; 105 } 106 EXPORT_SYMBOL(mdio_device_reset); 107 108 void mdio_device_free(struct mdio_device *mdiodev) 109 { 110 put_device(&mdiodev->dev); 111 } 112 EXPORT_SYMBOL(mdio_device_free); 113 114 static void mdio_device_release(struct device *dev) 115 { 116 fwnode_handle_put(dev->fwnode); 117 kfree(to_mdio_device(dev)); 118 } 119 120 struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr) 121 { 122 struct mdio_device *mdiodev; 123 124 /* We allocate the device, and initialize the default values */ 125 mdiodev = kzalloc_obj(*mdiodev); 126 if (!mdiodev) 127 return ERR_PTR(-ENOMEM); 128 129 mdiodev->dev.release = mdio_device_release; 130 mdiodev->dev.parent = &bus->dev; 131 mdiodev->dev.bus = &mdio_bus_type; 132 mdiodev->device_free = mdio_device_free; 133 mdiodev->device_remove = mdio_device_remove; 134 mdiodev->bus = bus; 135 mdiodev->addr = addr; 136 mdiodev->reset_state = -1; 137 138 dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr); 139 140 device_initialize(&mdiodev->dev); 141 142 return mdiodev; 143 } 144 EXPORT_SYMBOL(mdio_device_create); 145 146 /** 147 * mdio_device_register - Register the mdio device on the MDIO bus 148 * @mdiodev: mdio_device structure to be added to the MDIO bus 149 * 150 * Return: Zero if successful, negative error code on failure 151 */ 152 int mdio_device_register(struct mdio_device *mdiodev) 153 { 154 int err; 155 156 dev_dbg(&mdiodev->dev, "%s\n", __func__); 157 158 err = mdiobus_register_device(mdiodev); 159 if (err) 160 return err; 161 162 err = device_add(&mdiodev->dev); 163 if (err) { 164 pr_err("MDIO %d failed to add\n", mdiodev->addr); 165 goto out; 166 } 167 168 return 0; 169 170 out: 171 mdiobus_unregister_device(mdiodev); 172 return err; 173 } 174 EXPORT_SYMBOL(mdio_device_register); 175 176 /** 177 * mdio_device_remove - Remove a previously registered mdio device from the 178 * MDIO bus 179 * @mdiodev: mdio_device structure to remove 180 * 181 * This doesn't free the mdio_device itself, it merely reverses the effects 182 * of mdio_device_register(). Use mdio_device_free() to free the device 183 * after calling this function. 184 */ 185 void mdio_device_remove(struct mdio_device *mdiodev) 186 { 187 device_del(&mdiodev->dev); 188 mdiobus_unregister_device(mdiodev); 189 } 190 EXPORT_SYMBOL(mdio_device_remove); 191 192 int mdiobus_register_device(struct mdio_device *mdiodev) 193 { 194 int err; 195 196 if (mdiodev->bus->mdio_map[mdiodev->addr]) 197 return -EBUSY; 198 199 if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY) { 200 err = mdio_device_register_reset(mdiodev); 201 if (err) 202 return err; 203 204 /* Assert the reset signal */ 205 mdio_device_reset(mdiodev, 1); 206 } 207 208 mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev; 209 210 return 0; 211 } 212 213 int mdiobus_unregister_device(struct mdio_device *mdiodev) 214 { 215 if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev) 216 return -EINVAL; 217 218 mdio_device_unregister_reset(mdiodev); 219 220 mdiodev->bus->mdio_map[mdiodev->addr] = NULL; 221 222 return 0; 223 } 224 225 /** 226 * mdio_probe - probe an MDIO device 227 * @dev: device to probe 228 * 229 * Description: Take care of setting up the mdio_device structure 230 * and calling the driver to probe the device. 231 * 232 * Return: Zero if successful, negative error code on failure 233 */ 234 static int mdio_probe(struct device *dev) 235 { 236 struct mdio_device *mdiodev = to_mdio_device(dev); 237 struct device_driver *drv = mdiodev->dev.driver; 238 struct mdio_driver *mdiodrv = to_mdio_driver(drv); 239 int err = 0; 240 241 /* Deassert the reset signal */ 242 mdio_device_reset(mdiodev, 0); 243 244 if (mdiodrv->probe) { 245 err = mdiodrv->probe(mdiodev); 246 if (err) { 247 /* Assert the reset signal */ 248 mdio_device_reset(mdiodev, 1); 249 } 250 } 251 252 return err; 253 } 254 255 static int mdio_remove(struct device *dev) 256 { 257 struct mdio_device *mdiodev = to_mdio_device(dev); 258 struct device_driver *drv = mdiodev->dev.driver; 259 struct mdio_driver *mdiodrv = to_mdio_driver(drv); 260 261 if (mdiodrv->remove) 262 mdiodrv->remove(mdiodev); 263 264 /* Assert the reset signal */ 265 mdio_device_reset(mdiodev, 1); 266 267 return 0; 268 } 269 270 static void mdio_shutdown(struct device *dev) 271 { 272 struct mdio_device *mdiodev = to_mdio_device(dev); 273 struct device_driver *drv = mdiodev->dev.driver; 274 struct mdio_driver *mdiodrv = to_mdio_driver(drv); 275 276 if (mdiodrv->shutdown) 277 mdiodrv->shutdown(mdiodev); 278 } 279 280 /** 281 * mdio_driver_register - register an mdio_driver with the MDIO layer 282 * @drv: new mdio_driver to register 283 * 284 * Return: Zero if successful, negative error code on failure 285 */ 286 int mdio_driver_register(struct mdio_driver *drv) 287 { 288 struct mdio_driver_common *mdiodrv = &drv->mdiodrv; 289 int retval; 290 291 pr_debug("%s: %s\n", __func__, mdiodrv->driver.name); 292 293 mdiodrv->driver.bus = &mdio_bus_type; 294 mdiodrv->driver.probe = mdio_probe; 295 mdiodrv->driver.remove = mdio_remove; 296 mdiodrv->driver.shutdown = mdio_shutdown; 297 298 retval = driver_register(&mdiodrv->driver); 299 if (retval) { 300 pr_err("%s: Error %d in registering driver\n", 301 mdiodrv->driver.name, retval); 302 303 return retval; 304 } 305 306 return 0; 307 } 308 EXPORT_SYMBOL(mdio_driver_register); 309 310 void mdio_driver_unregister(struct mdio_driver *drv) 311 { 312 struct mdio_driver_common *mdiodrv = &drv->mdiodrv; 313 314 driver_unregister(&mdiodrv->driver); 315 } 316 EXPORT_SYMBOL(mdio_driver_unregister); 317