xref: /linux/drivers/net/phy/mdio_device.c (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
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