xref: /linux/drivers/net/phy/mdio_device.c (revision 5c458073553f0ef74f5c8db1bd459c87c722a299)
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  */
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  */
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 
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 
107 void mdio_device_free(struct mdio_device *mdiodev)
108 {
109 	put_device(&mdiodev->dev);
110 }
111 EXPORT_SYMBOL(mdio_device_free);
112 
113 static void mdio_device_release(struct device *dev)
114 {
115 	fwnode_handle_put(dev->fwnode);
116 	kfree(to_mdio_device(dev));
117 }
118 
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  */
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  */
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 
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 
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  */
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 
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 
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  */
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 
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