xref: /linux/drivers/net/dsa/realtek/rtl83xx.c (revision c5288cda69ee2d8607f5026bd599a5cebf0ee783)
1 // SPDX-License-Identifier: GPL-2.0+
2 
3 #include <linux/module.h>
4 #include <linux/regmap.h>
5 #include <linux/of_mdio.h>
6 
7 #include "realtek.h"
8 #include "rtl83xx.h"
9 
10 /**
11  * rtl83xx_lock() - Locks the mutex used by regmaps
12  * @ctx: realtek_priv pointer
13  *
14  * This function is passed to regmap to be used as the lock function.
15  * It is also used externally to block regmap before executing multiple
16  * operations that must happen in sequence (which will use
17  * realtek_priv.map_nolock instead).
18  *
19  * Context: Can sleep. Holds priv->map_lock lock.
20  * Return: nothing
21  */
22 void rtl83xx_lock(void *ctx)
23 {
24 	struct realtek_priv *priv = ctx;
25 
26 	mutex_lock(&priv->map_lock);
27 }
28 EXPORT_SYMBOL_NS_GPL(rtl83xx_lock, REALTEK_DSA);
29 
30 /**
31  * rtl83xx_unlock() - Unlocks the mutex used by regmaps
32  * @ctx: realtek_priv pointer
33  *
34  * This function unlocks the lock acquired by rtl83xx_lock.
35  *
36  * Context: Releases priv->map_lock lock.
37  * Return: nothing
38  */
39 void rtl83xx_unlock(void *ctx)
40 {
41 	struct realtek_priv *priv = ctx;
42 
43 	mutex_unlock(&priv->map_lock);
44 }
45 EXPORT_SYMBOL_NS_GPL(rtl83xx_unlock, REALTEK_DSA);
46 
47 static int rtl83xx_user_mdio_read(struct mii_bus *bus, int addr, int regnum)
48 {
49 	struct realtek_priv *priv = bus->priv;
50 
51 	return priv->ops->phy_read(priv, addr, regnum);
52 }
53 
54 static int rtl83xx_user_mdio_write(struct mii_bus *bus, int addr, int regnum,
55 				   u16 val)
56 {
57 	struct realtek_priv *priv = bus->priv;
58 
59 	return priv->ops->phy_write(priv, addr, regnum, val);
60 }
61 
62 /**
63  * rtl83xx_setup_user_mdio() - register the user mii bus driver
64  * @ds: DSA switch associated with this user_mii_bus
65  *
66  * Registers the MDIO bus for built-in Ethernet PHYs, and associates it with
67  * the mandatory 'mdio' child OF node of the switch.
68  *
69  * Context: Can sleep.
70  * Return: 0 on success, negative value for failure.
71  */
72 int rtl83xx_setup_user_mdio(struct dsa_switch *ds)
73 {
74 	struct realtek_priv *priv = ds->priv;
75 	struct device_node *mdio_np;
76 	struct mii_bus *bus;
77 	int ret = 0;
78 
79 	mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
80 	if (!mdio_np) {
81 		dev_err(priv->dev, "no MDIO bus node\n");
82 		return -ENODEV;
83 	}
84 
85 	bus = devm_mdiobus_alloc(priv->dev);
86 	if (!bus) {
87 		ret = -ENOMEM;
88 		goto err_put_node;
89 	}
90 
91 	bus->priv = priv;
92 	bus->name = "Realtek user MII";
93 	bus->read = rtl83xx_user_mdio_read;
94 	bus->write = rtl83xx_user_mdio_write;
95 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s:user_mii", dev_name(priv->dev));
96 	bus->parent = priv->dev;
97 
98 	ret = devm_of_mdiobus_register(priv->dev, bus, mdio_np);
99 	if (ret) {
100 		dev_err(priv->dev, "unable to register MDIO bus %s\n",
101 			bus->id);
102 		goto err_put_node;
103 	}
104 
105 	priv->user_mii_bus = bus;
106 
107 err_put_node:
108 	of_node_put(mdio_np);
109 
110 	return ret;
111 }
112 EXPORT_SYMBOL_NS_GPL(rtl83xx_setup_user_mdio, REALTEK_DSA);
113 
114 /**
115  * rtl83xx_probe() - probe a Realtek switch
116  * @dev: the device being probed
117  * @interface_info: specific management interface info.
118  *
119  * This function initializes realtek_priv and reads data from the device tree
120  * node. The switch is hard resetted if a method is provided.
121  *
122  * Context: Can sleep.
123  * Return: Pointer to the realtek_priv or ERR_PTR() in case of failure.
124  *
125  * The realtek_priv pointer does not need to be freed as it is controlled by
126  * devres.
127  */
128 struct realtek_priv *
129 rtl83xx_probe(struct device *dev,
130 	      const struct realtek_interface_info *interface_info)
131 {
132 	const struct realtek_variant *var;
133 	struct realtek_priv *priv;
134 	struct regmap_config rc = {
135 		.reg_bits = 10, /* A4..A0 R4..R0 */
136 		.val_bits = 16,
137 		.reg_stride = 1,
138 		.max_register = 0xffff,
139 		.reg_format_endian = REGMAP_ENDIAN_BIG,
140 		.reg_read = interface_info->reg_read,
141 		.reg_write = interface_info->reg_write,
142 		.cache_type = REGCACHE_NONE,
143 		.lock = rtl83xx_lock,
144 		.unlock = rtl83xx_unlock,
145 	};
146 	int ret;
147 
148 	var = of_device_get_match_data(dev);
149 	if (!var)
150 		return ERR_PTR(-EINVAL);
151 
152 	priv = devm_kzalloc(dev, size_add(sizeof(*priv), var->chip_data_sz),
153 			    GFP_KERNEL);
154 	if (!priv)
155 		return ERR_PTR(-ENOMEM);
156 
157 	mutex_init(&priv->map_lock);
158 
159 	rc.lock_arg = priv;
160 	priv->map = devm_regmap_init(dev, NULL, priv, &rc);
161 	if (IS_ERR(priv->map)) {
162 		ret = PTR_ERR(priv->map);
163 		dev_err(dev, "regmap init failed: %d\n", ret);
164 		return ERR_PTR(ret);
165 	}
166 
167 	rc.disable_locking = true;
168 	priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
169 	if (IS_ERR(priv->map_nolock)) {
170 		ret = PTR_ERR(priv->map_nolock);
171 		dev_err(dev, "regmap init failed: %d\n", ret);
172 		return ERR_PTR(ret);
173 	}
174 
175 	/* Link forward and backward */
176 	priv->dev = dev;
177 	priv->variant = var;
178 	priv->ops = var->ops;
179 	priv->chip_data = (void *)priv + sizeof(*priv);
180 
181 	spin_lock_init(&priv->lock);
182 
183 	priv->leds_disabled = of_property_read_bool(dev->of_node,
184 						    "realtek,disable-leds");
185 
186 	/* TODO: if power is software controlled, set up any regulators here */
187 	priv->reset_ctl = devm_reset_control_get_optional(dev, NULL);
188 	if (IS_ERR(priv->reset_ctl)) {
189 		ret = PTR_ERR(priv->reset_ctl);
190 		dev_err_probe(dev, ret, "failed to get reset control\n");
191 		return ERR_CAST(priv->reset_ctl);
192 	}
193 
194 	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
195 	if (IS_ERR(priv->reset)) {
196 		dev_err(dev, "failed to get RESET GPIO\n");
197 		return ERR_CAST(priv->reset);
198 	}
199 
200 	dev_set_drvdata(dev, priv);
201 
202 	if (priv->reset_ctl || priv->reset) {
203 		rtl83xx_reset_assert(priv);
204 		dev_dbg(dev, "asserted RESET\n");
205 		msleep(REALTEK_HW_STOP_DELAY);
206 		rtl83xx_reset_deassert(priv);
207 		msleep(REALTEK_HW_START_DELAY);
208 		dev_dbg(dev, "deasserted RESET\n");
209 	}
210 
211 	return priv;
212 }
213 EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, REALTEK_DSA);
214 
215 /**
216  * rtl83xx_register_switch() - detects and register a switch
217  * @priv: realtek_priv pointer
218  *
219  * This function first checks the switch chip ID and register a DSA
220  * switch.
221  *
222  * Context: Can sleep. Takes and releases priv->map_lock.
223  * Return: 0 on success, negative value for failure.
224  */
225 int rtl83xx_register_switch(struct realtek_priv *priv)
226 {
227 	struct dsa_switch *ds = &priv->ds;
228 	int ret;
229 
230 	ret = priv->ops->detect(priv);
231 	if (ret) {
232 		dev_err_probe(priv->dev, ret, "unable to detect switch\n");
233 		return ret;
234 	}
235 
236 	ds->priv = priv;
237 	ds->dev = priv->dev;
238 	ds->ops = priv->variant->ds_ops;
239 	ds->phylink_mac_ops = priv->variant->phylink_mac_ops;
240 	ds->num_ports = priv->num_ports;
241 
242 	ret = dsa_register_switch(ds);
243 	if (ret) {
244 		dev_err_probe(priv->dev, ret, "unable to register switch\n");
245 		return ret;
246 	}
247 
248 	return 0;
249 }
250 EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, REALTEK_DSA);
251 
252 /**
253  * rtl83xx_unregister_switch() - unregister a switch
254  * @priv: realtek_priv pointer
255  *
256  * This function unregister a DSA switch.
257  *
258  * Context: Can sleep.
259  * Return: Nothing.
260  */
261 void rtl83xx_unregister_switch(struct realtek_priv *priv)
262 {
263 	struct dsa_switch *ds = &priv->ds;
264 
265 	dsa_unregister_switch(ds);
266 }
267 EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, REALTEK_DSA);
268 
269 /**
270  * rtl83xx_shutdown() - shutdown a switch
271  * @priv: realtek_priv pointer
272  *
273  * This function shuts down the DSA switch and cleans the platform driver data,
274  * to prevent realtek_{smi,mdio}_remove() from running afterwards, which is
275  * possible if the parent bus implements its own .shutdown() as .remove().
276  *
277  * Context: Can sleep.
278  * Return: Nothing.
279  */
280 void rtl83xx_shutdown(struct realtek_priv *priv)
281 {
282 	struct dsa_switch *ds = &priv->ds;
283 
284 	dsa_switch_shutdown(ds);
285 
286 	dev_set_drvdata(priv->dev, NULL);
287 }
288 EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA);
289 
290 /**
291  * rtl83xx_remove() - Cleanup a realtek switch driver
292  * @priv: realtek_priv pointer
293  *
294  * Placehold for common cleanup procedures.
295  *
296  * Context: Any
297  * Return: nothing
298  */
299 void rtl83xx_remove(struct realtek_priv *priv)
300 {
301 }
302 EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
303 
304 void rtl83xx_reset_assert(struct realtek_priv *priv)
305 {
306 	int ret;
307 
308 	ret = reset_control_assert(priv->reset_ctl);
309 	if (ret)
310 		dev_warn(priv->dev,
311 			 "Failed to assert the switch reset control: %pe\n",
312 			 ERR_PTR(ret));
313 
314 	gpiod_set_value(priv->reset, true);
315 }
316 
317 void rtl83xx_reset_deassert(struct realtek_priv *priv)
318 {
319 	int ret;
320 
321 	ret = reset_control_deassert(priv->reset_ctl);
322 	if (ret)
323 		dev_warn(priv->dev,
324 			 "Failed to deassert the switch reset control: %pe\n",
325 			 ERR_PTR(ret));
326 
327 	gpiod_set_value(priv->reset, false);
328 }
329 
330 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
331 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
332 MODULE_DESCRIPTION("Realtek DSA switches common module");
333 MODULE_LICENSE("GPL");
334