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