root/drivers/net/phy/mdio_device.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mdio_device_free
  2. mdio_device_release
  3. mdio_device_bus_match
  4. mdio_device_create
  5. mdio_device_register
  6. mdio_device_remove
  7. mdio_device_reset
  8. mdio_probe
  9. mdio_remove
  10. mdio_driver_register
  11. mdio_driver_unregister

   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/errno.h>
  10 #include <linux/gpio.h>
  11 #include <linux/gpio/consumer.h>
  12 #include <linux/init.h>
  13 #include <linux/interrupt.h>
  14 #include <linux/kernel.h>
  15 #include <linux/mdio.h>
  16 #include <linux/mii.h>
  17 #include <linux/module.h>
  18 #include <linux/phy.h>
  19 #include <linux/reset.h>
  20 #include <linux/slab.h>
  21 #include <linux/string.h>
  22 #include <linux/unistd.h>
  23 #include <linux/delay.h>
  24 
  25 void mdio_device_free(struct mdio_device *mdiodev)
  26 {
  27         put_device(&mdiodev->dev);
  28 }
  29 EXPORT_SYMBOL(mdio_device_free);
  30 
  31 static void mdio_device_release(struct device *dev)
  32 {
  33         kfree(to_mdio_device(dev));
  34 }
  35 
  36 int mdio_device_bus_match(struct device *dev, struct device_driver *drv)
  37 {
  38         struct mdio_device *mdiodev = to_mdio_device(dev);
  39         struct mdio_driver *mdiodrv = to_mdio_driver(drv);
  40 
  41         if (mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY)
  42                 return 0;
  43 
  44         return strcmp(mdiodev->modalias, drv->name) == 0;
  45 }
  46 
  47 struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr)
  48 {
  49         struct mdio_device *mdiodev;
  50 
  51         /* We allocate the device, and initialize the default values */
  52         mdiodev = kzalloc(sizeof(*mdiodev), GFP_KERNEL);
  53         if (!mdiodev)
  54                 return ERR_PTR(-ENOMEM);
  55 
  56         mdiodev->dev.release = mdio_device_release;
  57         mdiodev->dev.parent = &bus->dev;
  58         mdiodev->dev.bus = &mdio_bus_type;
  59         mdiodev->device_free = mdio_device_free;
  60         mdiodev->device_remove = mdio_device_remove;
  61         mdiodev->bus = bus;
  62         mdiodev->addr = addr;
  63 
  64         dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);
  65 
  66         device_initialize(&mdiodev->dev);
  67 
  68         return mdiodev;
  69 }
  70 EXPORT_SYMBOL(mdio_device_create);
  71 
  72 /**
  73  * mdio_device_register - Register the mdio device on the MDIO bus
  74  * @mdiodev: mdio_device structure to be added to the MDIO bus
  75  */
  76 int mdio_device_register(struct mdio_device *mdiodev)
  77 {
  78         int err;
  79 
  80         dev_dbg(&mdiodev->dev, "mdio_device_register\n");
  81 
  82         err = mdiobus_register_device(mdiodev);
  83         if (err)
  84                 return err;
  85 
  86         err = device_add(&mdiodev->dev);
  87         if (err) {
  88                 pr_err("MDIO %d failed to add\n", mdiodev->addr);
  89                 goto out;
  90         }
  91 
  92         return 0;
  93 
  94  out:
  95         mdiobus_unregister_device(mdiodev);
  96         return err;
  97 }
  98 EXPORT_SYMBOL(mdio_device_register);
  99 
 100 /**
 101  * mdio_device_remove - Remove a previously registered mdio device from the
 102  *                      MDIO bus
 103  * @mdiodev: mdio_device structure to remove
 104  *
 105  * This doesn't free the mdio_device itself, it merely reverses the effects
 106  * of mdio_device_register(). Use mdio_device_free() to free the device
 107  * after calling this function.
 108  */
 109 void mdio_device_remove(struct mdio_device *mdiodev)
 110 {
 111         device_del(&mdiodev->dev);
 112         mdiobus_unregister_device(mdiodev);
 113 }
 114 EXPORT_SYMBOL(mdio_device_remove);
 115 
 116 void mdio_device_reset(struct mdio_device *mdiodev, int value)
 117 {
 118         unsigned int d;
 119 
 120         if (!mdiodev->reset_gpio && !mdiodev->reset_ctrl)
 121                 return;
 122 
 123         if (mdiodev->reset_gpio)
 124                 gpiod_set_value_cansleep(mdiodev->reset_gpio, value);
 125 
 126         if (mdiodev->reset_ctrl) {
 127                 if (value)
 128                         reset_control_assert(mdiodev->reset_ctrl);
 129                 else
 130                         reset_control_deassert(mdiodev->reset_ctrl);
 131         }
 132 
 133         d = value ? mdiodev->reset_assert_delay : mdiodev->reset_deassert_delay;
 134         if (d)
 135                 usleep_range(d, d + max_t(unsigned int, d / 10, 100));
 136 }
 137 EXPORT_SYMBOL(mdio_device_reset);
 138 
 139 /**
 140  * mdio_probe - probe an MDIO device
 141  * @dev: device to probe
 142  *
 143  * Description: Take care of setting up the mdio_device structure
 144  * and calling the driver to probe the device.
 145  */
 146 static int mdio_probe(struct device *dev)
 147 {
 148         struct mdio_device *mdiodev = to_mdio_device(dev);
 149         struct device_driver *drv = mdiodev->dev.driver;
 150         struct mdio_driver *mdiodrv = to_mdio_driver(drv);
 151         int err = 0;
 152 
 153         if (mdiodrv->probe) {
 154                 /* Deassert the reset signal */
 155                 mdio_device_reset(mdiodev, 0);
 156 
 157                 err = mdiodrv->probe(mdiodev);
 158                 if (err) {
 159                         /* Assert the reset signal */
 160                         mdio_device_reset(mdiodev, 1);
 161                 }
 162         }
 163 
 164         return err;
 165 }
 166 
 167 static int mdio_remove(struct device *dev)
 168 {
 169         struct mdio_device *mdiodev = to_mdio_device(dev);
 170         struct device_driver *drv = mdiodev->dev.driver;
 171         struct mdio_driver *mdiodrv = to_mdio_driver(drv);
 172 
 173         if (mdiodrv->remove) {
 174                 mdiodrv->remove(mdiodev);
 175 
 176                 /* Assert the reset signal */
 177                 mdio_device_reset(mdiodev, 1);
 178         }
 179 
 180         return 0;
 181 }
 182 
 183 /**
 184  * mdio_driver_register - register an mdio_driver with the MDIO layer
 185  * @new_driver: new mdio_driver to register
 186  */
 187 int mdio_driver_register(struct mdio_driver *drv)
 188 {
 189         struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
 190         int retval;
 191 
 192         pr_debug("mdio_driver_register: %s\n", mdiodrv->driver.name);
 193 
 194         mdiodrv->driver.bus = &mdio_bus_type;
 195         mdiodrv->driver.probe = mdio_probe;
 196         mdiodrv->driver.remove = mdio_remove;
 197 
 198         retval = driver_register(&mdiodrv->driver);
 199         if (retval) {
 200                 pr_err("%s: Error %d in registering driver\n",
 201                        mdiodrv->driver.name, retval);
 202 
 203                 return retval;
 204         }
 205 
 206         return 0;
 207 }
 208 EXPORT_SYMBOL(mdio_driver_register);
 209 
 210 void mdio_driver_unregister(struct mdio_driver *drv)
 211 {
 212         struct mdio_driver_common *mdiodrv = &drv->mdiodrv;
 213 
 214         driver_unregister(&mdiodrv->driver);
 215 }
 216 EXPORT_SYMBOL(mdio_driver_unregister);

/* [<][>][^][v][top][bottom][index][help] */