xref: /linux/drivers/net/dsa/realtek/rtl83xx.c (revision 06a130e42a5bfc84795464bff023bff4c16f58c5)
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 		return dev_err_cast_probe(dev, priv->reset_ctl,
190 					  "failed to get reset control\n");
191 
192 	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
193 	if (IS_ERR(priv->reset)) {
194 		dev_err(dev, "failed to get RESET GPIO\n");
195 		return ERR_CAST(priv->reset);
196 	}
197 
198 	dev_set_drvdata(dev, priv);
199 
200 	if (priv->reset_ctl || priv->reset) {
201 		rtl83xx_reset_assert(priv);
202 		dev_dbg(dev, "asserted RESET\n");
203 		msleep(REALTEK_HW_STOP_DELAY);
204 		rtl83xx_reset_deassert(priv);
205 		msleep(REALTEK_HW_START_DELAY);
206 		dev_dbg(dev, "deasserted RESET\n");
207 	}
208 
209 	return priv;
210 }
211 EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, REALTEK_DSA);
212 
213 /**
214  * rtl83xx_register_switch() - detects and register a switch
215  * @priv: realtek_priv pointer
216  *
217  * This function first checks the switch chip ID and register a DSA
218  * switch.
219  *
220  * Context: Can sleep. Takes and releases priv->map_lock.
221  * Return: 0 on success, negative value for failure.
222  */
223 int rtl83xx_register_switch(struct realtek_priv *priv)
224 {
225 	struct dsa_switch *ds = &priv->ds;
226 	int ret;
227 
228 	ret = priv->ops->detect(priv);
229 	if (ret) {
230 		dev_err_probe(priv->dev, ret, "unable to detect switch\n");
231 		return ret;
232 	}
233 
234 	ds->priv = priv;
235 	ds->dev = priv->dev;
236 	ds->ops = priv->variant->ds_ops;
237 	ds->phylink_mac_ops = priv->variant->phylink_mac_ops;
238 	ds->num_ports = priv->num_ports;
239 
240 	ret = dsa_register_switch(ds);
241 	if (ret) {
242 		dev_err_probe(priv->dev, ret, "unable to register switch\n");
243 		return ret;
244 	}
245 
246 	return 0;
247 }
248 EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, REALTEK_DSA);
249 
250 /**
251  * rtl83xx_unregister_switch() - unregister a switch
252  * @priv: realtek_priv pointer
253  *
254  * This function unregister a DSA switch.
255  *
256  * Context: Can sleep.
257  * Return: Nothing.
258  */
259 void rtl83xx_unregister_switch(struct realtek_priv *priv)
260 {
261 	struct dsa_switch *ds = &priv->ds;
262 
263 	dsa_unregister_switch(ds);
264 }
265 EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, REALTEK_DSA);
266 
267 /**
268  * rtl83xx_shutdown() - shutdown a switch
269  * @priv: realtek_priv pointer
270  *
271  * This function shuts down the DSA switch and cleans the platform driver data,
272  * to prevent realtek_{smi,mdio}_remove() from running afterwards, which is
273  * possible if the parent bus implements its own .shutdown() as .remove().
274  *
275  * Context: Can sleep.
276  * Return: Nothing.
277  */
278 void rtl83xx_shutdown(struct realtek_priv *priv)
279 {
280 	struct dsa_switch *ds = &priv->ds;
281 
282 	dsa_switch_shutdown(ds);
283 
284 	dev_set_drvdata(priv->dev, NULL);
285 }
286 EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA);
287 
288 /**
289  * rtl83xx_remove() - Cleanup a realtek switch driver
290  * @priv: realtek_priv pointer
291  *
292  * Placehold for common cleanup procedures.
293  *
294  * Context: Any
295  * Return: nothing
296  */
297 void rtl83xx_remove(struct realtek_priv *priv)
298 {
299 }
300 EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
301 
302 void rtl83xx_reset_assert(struct realtek_priv *priv)
303 {
304 	int ret;
305 
306 	ret = reset_control_assert(priv->reset_ctl);
307 	if (ret)
308 		dev_warn(priv->dev,
309 			 "Failed to assert the switch reset control: %pe\n",
310 			 ERR_PTR(ret));
311 
312 	gpiod_set_value(priv->reset, true);
313 }
314 
315 void rtl83xx_reset_deassert(struct realtek_priv *priv)
316 {
317 	int ret;
318 
319 	ret = reset_control_deassert(priv->reset_ctl);
320 	if (ret)
321 		dev_warn(priv->dev,
322 			 "Failed to deassert the switch reset control: %pe\n",
323 			 ERR_PTR(ret));
324 
325 	gpiod_set_value(priv->reset, false);
326 }
327 
328 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
329 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
330 MODULE_DESCRIPTION("Realtek DSA switches common module");
331 MODULE_LICENSE("GPL");
332