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 */
rtl83xx_lock(void * ctx)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 */
rtl83xx_unlock(void * ctx)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
rtl83xx_user_mdio_read(struct mii_bus * bus,int addr,int regnum)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
rtl83xx_user_mdio_write(struct mii_bus * bus,int addr,int regnum,u16 val)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 */
rtl83xx_setup_user_mdio(struct dsa_switch * ds)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 *
rtl83xx_probe(struct device * dev,const struct realtek_interface_info * interface_info)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 */
rtl83xx_register_switch(struct realtek_priv * priv)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 */
rtl83xx_unregister_switch(struct realtek_priv * priv)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 */
rtl83xx_shutdown(struct realtek_priv * priv)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 */
rtl83xx_remove(struct realtek_priv * priv)297 void rtl83xx_remove(struct realtek_priv *priv)
298 {
299 }
300 EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
301
rtl83xx_reset_assert(struct realtek_priv * priv)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
rtl83xx_reset_deassert(struct realtek_priv * priv)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