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