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