xref: /linux/drivers/net/ethernet/mscc/ocelot_vsc7514.c (revision 4461568aa4e565de2c336f4875ddf912f26da8a5)
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3  * Microsemi Ocelot Switch driver
4  *
5  * Copyright (c) 2017 Microsemi Corporation
6  */
7 #include <linux/dsa/ocelot.h>
8 #include <linux/interrupt.h>
9 #include <linux/module.h>
10 #include <linux/of_net.h>
11 #include <linux/netdevice.h>
12 #include <linux/phylink.h>
13 #include <linux/of_mdio.h>
14 #include <linux/of_platform.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/skbuff.h>
17 #include <net/switchdev.h>
18 
19 #include <soc/mscc/ocelot_vcap.h>
20 #include <soc/mscc/ocelot_hsio.h>
21 #include <soc/mscc/vsc7514_regs.h>
22 #include "ocelot_fdma.h"
23 #include "ocelot.h"
24 
25 #define VSC7514_VCAP_POLICER_BASE			128
26 #define VSC7514_VCAP_POLICER_MAX			191
27 
28 static const u32 *ocelot_regmap[TARGET_MAX] = {
29 	[ANA] = vsc7514_ana_regmap,
30 	[QS] = vsc7514_qs_regmap,
31 	[QSYS] = vsc7514_qsys_regmap,
32 	[REW] = vsc7514_rew_regmap,
33 	[SYS] = vsc7514_sys_regmap,
34 	[S0] = vsc7514_vcap_regmap,
35 	[S1] = vsc7514_vcap_regmap,
36 	[S2] = vsc7514_vcap_regmap,
37 	[PTP] = vsc7514_ptp_regmap,
38 	[DEV_GMII] = vsc7514_dev_gmii_regmap,
39 };
40 
41 static const struct reg_field ocelot_regfields[REGFIELD_MAX] = {
42 	[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 11, 11),
43 	[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 10),
44 	[ANA_ANEVENTS_MSTI_DROP] = REG_FIELD(ANA_ANEVENTS, 27, 27),
45 	[ANA_ANEVENTS_ACLKILL] = REG_FIELD(ANA_ANEVENTS, 26, 26),
46 	[ANA_ANEVENTS_ACLUSED] = REG_FIELD(ANA_ANEVENTS, 25, 25),
47 	[ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
48 	[ANA_ANEVENTS_VS2TTL1] = REG_FIELD(ANA_ANEVENTS, 23, 23),
49 	[ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
50 	[ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
51 	[ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
52 	[ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
53 	[ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
54 	[ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
55 	[ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
56 	[ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
57 	[ANA_ANEVENTS_DROPPED] = REG_FIELD(ANA_ANEVENTS, 14, 14),
58 	[ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
59 	[ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
60 	[ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
61 	[ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
62 	[ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
63 	[ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
64 	[ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
65 	[ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
66 	[ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
67 	[ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
68 	[ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
69 	[ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
70 	[ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
71 	[ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
72 	[ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 18, 18),
73 	[ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 10, 11),
74 	[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 9),
75 	[QSYS_TIMED_FRAME_ENTRY_TFRM_VLD] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 20, 20),
76 	[QSYS_TIMED_FRAME_ENTRY_TFRM_FP] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 8, 19),
77 	[QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 4, 7),
78 	[QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 1, 3),
79 	[QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 0, 0),
80 	[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 2, 2),
81 	[SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 1, 1),
82 	[SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 0, 0),
83 	/* Replicated per number of ports (12), register size 4 per port */
84 	[QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 12, 4),
85 	[QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 12, 4),
86 	[QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 12, 4),
87 	[QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 12, 4),
88 	[QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 12, 4),
89 	[QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 12, 4),
90 	[SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 12, 4),
91 	[SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 12, 4),
92 	[SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 12, 4),
93 	[SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 12, 4),
94 	[SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 12, 4),
95 	[SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 12, 4),
96 	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4),
97 };
98 
99 static const struct ocelot_stat_layout ocelot_stats_layout[OCELOT_NUM_STATS] = {
100 	OCELOT_COMMON_STATS,
101 };
102 
103 static void ocelot_pll5_init(struct ocelot *ocelot)
104 {
105 	/* Configure PLL5. This will need a proper CCF driver
106 	 * The values are coming from the VTSS API for Ocelot
107 	 */
108 	regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG4,
109 		     HSIO_PLL5G_CFG4_IB_CTRL(0x7600) |
110 		     HSIO_PLL5G_CFG4_IB_BIAS_CTRL(0x8));
111 	regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG0,
112 		     HSIO_PLL5G_CFG0_CORE_CLK_DIV(0x11) |
113 		     HSIO_PLL5G_CFG0_CPU_CLK_DIV(2) |
114 		     HSIO_PLL5G_CFG0_ENA_BIAS |
115 		     HSIO_PLL5G_CFG0_ENA_VCO_BUF |
116 		     HSIO_PLL5G_CFG0_ENA_CP1 |
117 		     HSIO_PLL5G_CFG0_SELCPI(2) |
118 		     HSIO_PLL5G_CFG0_LOOP_BW_RES(0xe) |
119 		     HSIO_PLL5G_CFG0_SELBGV820(4) |
120 		     HSIO_PLL5G_CFG0_DIV4 |
121 		     HSIO_PLL5G_CFG0_ENA_CLKTREE |
122 		     HSIO_PLL5G_CFG0_ENA_LANE);
123 	regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG2,
124 		     HSIO_PLL5G_CFG2_EN_RESET_FRQ_DET |
125 		     HSIO_PLL5G_CFG2_EN_RESET_OVERRUN |
126 		     HSIO_PLL5G_CFG2_GAIN_TEST(0x8) |
127 		     HSIO_PLL5G_CFG2_ENA_AMPCTRL |
128 		     HSIO_PLL5G_CFG2_PWD_AMPCTRL_N |
129 		     HSIO_PLL5G_CFG2_AMPC_SEL(0x10));
130 }
131 
132 static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops)
133 {
134 	int ret;
135 
136 	ocelot->map = ocelot_regmap;
137 	ocelot->stats_layout = ocelot_stats_layout;
138 	ocelot->num_mact_rows = 1024;
139 	ocelot->ops = ops;
140 
141 	ret = ocelot_regfields_init(ocelot, ocelot_regfields);
142 	if (ret)
143 		return ret;
144 
145 	ocelot_pll5_init(ocelot);
146 
147 	eth_random_addr(ocelot->base_mac);
148 	ocelot->base_mac[5] &= 0xf0;
149 
150 	return 0;
151 }
152 
153 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
154 {
155 	struct ocelot *ocelot = arg;
156 	int grp = 0, err;
157 
158 	while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) {
159 		struct sk_buff *skb;
160 
161 		err = ocelot_xtr_poll_frame(ocelot, grp, &skb);
162 		if (err)
163 			goto out;
164 
165 		skb->dev->stats.rx_bytes += skb->len;
166 		skb->dev->stats.rx_packets++;
167 
168 		if (!skb_defer_rx_timestamp(skb))
169 			netif_rx(skb);
170 	}
171 
172 out:
173 	if (err < 0)
174 		ocelot_drain_cpu_queue(ocelot, 0);
175 
176 	return IRQ_HANDLED;
177 }
178 
179 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
180 {
181 	struct ocelot *ocelot = arg;
182 
183 	ocelot_get_txtstamp(ocelot);
184 
185 	return IRQ_HANDLED;
186 }
187 
188 static const struct of_device_id mscc_ocelot_match[] = {
189 	{ .compatible = "mscc,vsc7514-switch" },
190 	{ }
191 };
192 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
193 
194 static int ocelot_reset(struct ocelot *ocelot)
195 {
196 	int retries = 100;
197 	u32 val;
198 
199 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
200 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
201 
202 	do {
203 		msleep(1);
204 		regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
205 				  &val);
206 	} while (val && --retries);
207 
208 	if (!retries)
209 		return -ETIMEDOUT;
210 
211 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
212 	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
213 
214 	return 0;
215 }
216 
217 /* Watermark encode
218  * Bit 8:   Unit; 0:1, 1:16
219  * Bit 7-0: Value to be multiplied with unit
220  */
221 static u16 ocelot_wm_enc(u16 value)
222 {
223 	WARN_ON(value >= 16 * BIT(8));
224 
225 	if (value >= BIT(8))
226 		return BIT(8) | (value / 16);
227 
228 	return value;
229 }
230 
231 static u16 ocelot_wm_dec(u16 wm)
232 {
233 	if (wm & BIT(8))
234 		return (wm & GENMASK(7, 0)) * 16;
235 
236 	return wm;
237 }
238 
239 static void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
240 {
241 	*inuse = (val & GENMASK(23, 12)) >> 12;
242 	*maxuse = val & GENMASK(11, 0);
243 }
244 
245 static const struct ocelot_ops ocelot_ops = {
246 	.reset			= ocelot_reset,
247 	.wm_enc			= ocelot_wm_enc,
248 	.wm_dec			= ocelot_wm_dec,
249 	.wm_stat		= ocelot_wm_stat,
250 	.port_to_netdev		= ocelot_port_to_netdev,
251 	.netdev_to_port		= ocelot_netdev_to_port,
252 };
253 
254 static struct vcap_props vsc7514_vcap_props[] = {
255 	[VCAP_ES0] = {
256 		.action_type_width = 0,
257 		.action_table = {
258 			[ES0_ACTION_TYPE_NORMAL] = {
259 				.width = 73, /* HIT_STICKY not included */
260 				.count = 1,
261 			},
262 		},
263 		.target = S0,
264 		.keys = vsc7514_vcap_es0_keys,
265 		.actions = vsc7514_vcap_es0_actions,
266 	},
267 	[VCAP_IS1] = {
268 		.action_type_width = 0,
269 		.action_table = {
270 			[IS1_ACTION_TYPE_NORMAL] = {
271 				.width = 78, /* HIT_STICKY not included */
272 				.count = 4,
273 			},
274 		},
275 		.target = S1,
276 		.keys = vsc7514_vcap_is1_keys,
277 		.actions = vsc7514_vcap_is1_actions,
278 	},
279 	[VCAP_IS2] = {
280 		.action_type_width = 1,
281 		.action_table = {
282 			[IS2_ACTION_TYPE_NORMAL] = {
283 				.width = 49,
284 				.count = 2
285 			},
286 			[IS2_ACTION_TYPE_SMAC_SIP] = {
287 				.width = 6,
288 				.count = 4
289 			},
290 		},
291 		.target = S2,
292 		.keys = vsc7514_vcap_is2_keys,
293 		.actions = vsc7514_vcap_is2_actions,
294 	},
295 };
296 
297 static struct ptp_clock_info ocelot_ptp_clock_info = {
298 	.owner		= THIS_MODULE,
299 	.name		= "ocelot ptp",
300 	.max_adj	= 0x7fffffff,
301 	.n_alarm	= 0,
302 	.n_ext_ts	= 0,
303 	.n_per_out	= OCELOT_PTP_PINS_NUM,
304 	.n_pins		= OCELOT_PTP_PINS_NUM,
305 	.pps		= 0,
306 	.gettime64	= ocelot_ptp_gettime64,
307 	.settime64	= ocelot_ptp_settime64,
308 	.adjtime	= ocelot_ptp_adjtime,
309 	.adjfine	= ocelot_ptp_adjfine,
310 	.verify		= ocelot_ptp_verify,
311 	.enable		= ocelot_ptp_enable,
312 };
313 
314 static void mscc_ocelot_teardown_devlink_ports(struct ocelot *ocelot)
315 {
316 	int port;
317 
318 	for (port = 0; port < ocelot->num_phys_ports; port++)
319 		ocelot_port_devlink_teardown(ocelot, port);
320 }
321 
322 static void mscc_ocelot_release_ports(struct ocelot *ocelot)
323 {
324 	int port;
325 
326 	for (port = 0; port < ocelot->num_phys_ports; port++) {
327 		struct ocelot_port *ocelot_port;
328 
329 		ocelot_port = ocelot->ports[port];
330 		if (!ocelot_port)
331 			continue;
332 
333 		ocelot_deinit_port(ocelot, port);
334 		ocelot_release_port(ocelot_port);
335 	}
336 }
337 
338 static int mscc_ocelot_init_ports(struct platform_device *pdev,
339 				  struct device_node *ports)
340 {
341 	struct ocelot *ocelot = platform_get_drvdata(pdev);
342 	u32 devlink_ports_registered = 0;
343 	struct device_node *portnp;
344 	int port, err;
345 	u32 reg;
346 
347 	ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
348 				     sizeof(struct ocelot_port *), GFP_KERNEL);
349 	if (!ocelot->ports)
350 		return -ENOMEM;
351 
352 	ocelot->devlink_ports = devm_kcalloc(ocelot->dev,
353 					     ocelot->num_phys_ports,
354 					     sizeof(*ocelot->devlink_ports),
355 					     GFP_KERNEL);
356 	if (!ocelot->devlink_ports)
357 		return -ENOMEM;
358 
359 	for_each_available_child_of_node(ports, portnp) {
360 		struct ocelot_port_private *priv;
361 		struct ocelot_port *ocelot_port;
362 		struct devlink_port *dlp;
363 		struct regmap *target;
364 		struct resource *res;
365 		char res_name[8];
366 
367 		if (of_property_read_u32(portnp, "reg", &reg))
368 			continue;
369 
370 		port = reg;
371 		if (port < 0 || port >= ocelot->num_phys_ports) {
372 			dev_err(ocelot->dev,
373 				"invalid port number: %d >= %d\n", port,
374 				ocelot->num_phys_ports);
375 			continue;
376 		}
377 
378 		snprintf(res_name, sizeof(res_name), "port%d", port);
379 
380 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
381 						   res_name);
382 		target = ocelot_regmap_init(ocelot, res);
383 		if (IS_ERR(target)) {
384 			err = PTR_ERR(target);
385 			of_node_put(portnp);
386 			goto out_teardown;
387 		}
388 
389 		err = ocelot_port_devlink_init(ocelot, port,
390 					       DEVLINK_PORT_FLAVOUR_PHYSICAL);
391 		if (err) {
392 			of_node_put(portnp);
393 			goto out_teardown;
394 		}
395 
396 		err = ocelot_probe_port(ocelot, port, target, portnp);
397 		if (err) {
398 			ocelot_port_devlink_teardown(ocelot, port);
399 			continue;
400 		}
401 
402 		devlink_ports_registered |= BIT(port);
403 
404 		ocelot_port = ocelot->ports[port];
405 		priv = container_of(ocelot_port, struct ocelot_port_private,
406 				    port);
407 		dlp = &ocelot->devlink_ports[port];
408 		devlink_port_type_eth_set(dlp, priv->dev);
409 	}
410 
411 	/* Initialize unused devlink ports at the end */
412 	for (port = 0; port < ocelot->num_phys_ports; port++) {
413 		if (devlink_ports_registered & BIT(port))
414 			continue;
415 
416 		err = ocelot_port_devlink_init(ocelot, port,
417 					       DEVLINK_PORT_FLAVOUR_UNUSED);
418 		if (err)
419 			goto out_teardown;
420 
421 		devlink_ports_registered |= BIT(port);
422 	}
423 
424 	return 0;
425 
426 out_teardown:
427 	/* Unregister the network interfaces */
428 	mscc_ocelot_release_ports(ocelot);
429 	/* Tear down devlink ports for the registered network interfaces */
430 	for (port = 0; port < ocelot->num_phys_ports; port++) {
431 		if (devlink_ports_registered & BIT(port))
432 			ocelot_port_devlink_teardown(ocelot, port);
433 	}
434 	return err;
435 }
436 
437 static int mscc_ocelot_probe(struct platform_device *pdev)
438 {
439 	struct device_node *np = pdev->dev.of_node;
440 	int err, irq_xtr, irq_ptp_rdy;
441 	struct device_node *ports;
442 	struct devlink *devlink;
443 	struct ocelot *ocelot;
444 	struct regmap *hsio;
445 	unsigned int i;
446 
447 	struct {
448 		enum ocelot_target id;
449 		char *name;
450 		u8 optional:1;
451 	} io_target[] = {
452 		{ SYS, "sys" },
453 		{ REW, "rew" },
454 		{ QSYS, "qsys" },
455 		{ ANA, "ana" },
456 		{ QS, "qs" },
457 		{ S0, "s0" },
458 		{ S1, "s1" },
459 		{ S2, "s2" },
460 		{ PTP, "ptp", 1 },
461 		{ FDMA, "fdma", 1 },
462 	};
463 
464 	if (!np && !pdev->dev.platform_data)
465 		return -ENODEV;
466 
467 	devlink =
468 		devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev);
469 	if (!devlink)
470 		return -ENOMEM;
471 
472 	ocelot = devlink_priv(devlink);
473 	ocelot->devlink = priv_to_devlink(ocelot);
474 	platform_set_drvdata(pdev, ocelot);
475 	ocelot->dev = &pdev->dev;
476 
477 	for (i = 0; i < ARRAY_SIZE(io_target); i++) {
478 		struct regmap *target;
479 		struct resource *res;
480 
481 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
482 						   io_target[i].name);
483 
484 		target = ocelot_regmap_init(ocelot, res);
485 		if (IS_ERR(target)) {
486 			if (io_target[i].optional) {
487 				ocelot->targets[io_target[i].id] = NULL;
488 				continue;
489 			}
490 			err = PTR_ERR(target);
491 			goto out_free_devlink;
492 		}
493 
494 		ocelot->targets[io_target[i].id] = target;
495 	}
496 
497 	if (ocelot->targets[FDMA])
498 		ocelot_fdma_init(pdev, ocelot);
499 
500 	hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio");
501 	if (IS_ERR(hsio)) {
502 		dev_err(&pdev->dev, "missing hsio syscon\n");
503 		err = PTR_ERR(hsio);
504 		goto out_free_devlink;
505 	}
506 
507 	ocelot->targets[HSIO] = hsio;
508 
509 	err = ocelot_chip_init(ocelot, &ocelot_ops);
510 	if (err)
511 		goto out_free_devlink;
512 
513 	irq_xtr = platform_get_irq_byname(pdev, "xtr");
514 	if (irq_xtr < 0) {
515 		err = irq_xtr;
516 		goto out_free_devlink;
517 	}
518 
519 	err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
520 					ocelot_xtr_irq_handler, IRQF_ONESHOT,
521 					"frame extraction", ocelot);
522 	if (err)
523 		goto out_free_devlink;
524 
525 	irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
526 	if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) {
527 		err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
528 						ocelot_ptp_rdy_irq_handler,
529 						IRQF_ONESHOT, "ptp ready",
530 						ocelot);
531 		if (err)
532 			goto out_free_devlink;
533 
534 		/* Both the PTP interrupt and the PTP bank are available */
535 		ocelot->ptp = 1;
536 	}
537 
538 	ports = of_get_child_by_name(np, "ethernet-ports");
539 	if (!ports) {
540 		dev_err(ocelot->dev, "no ethernet-ports child node found\n");
541 		err = -ENODEV;
542 		goto out_free_devlink;
543 	}
544 
545 	ocelot->num_phys_ports = of_get_child_count(ports);
546 	ocelot->num_flooding_pgids = 1;
547 
548 	ocelot->vcap = vsc7514_vcap_props;
549 
550 	ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE;
551 	ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX;
552 
553 	ocelot->npi = -1;
554 
555 	err = ocelot_init(ocelot);
556 	if (err)
557 		goto out_put_ports;
558 
559 	err = mscc_ocelot_init_ports(pdev, ports);
560 	if (err)
561 		goto out_ocelot_devlink_unregister;
562 
563 	if (ocelot->fdma)
564 		ocelot_fdma_start(ocelot);
565 
566 	err = ocelot_devlink_sb_register(ocelot);
567 	if (err)
568 		goto out_ocelot_release_ports;
569 
570 	if (ocelot->ptp) {
571 		err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
572 		if (err) {
573 			dev_err(ocelot->dev,
574 				"Timestamp initialization failed\n");
575 			ocelot->ptp = 0;
576 		}
577 	}
578 
579 	register_netdevice_notifier(&ocelot_netdevice_nb);
580 	register_switchdev_notifier(&ocelot_switchdev_nb);
581 	register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
582 
583 	of_node_put(ports);
584 	devlink_register(devlink);
585 
586 	dev_info(&pdev->dev, "Ocelot switch probed\n");
587 
588 	return 0;
589 
590 out_ocelot_release_ports:
591 	mscc_ocelot_release_ports(ocelot);
592 	mscc_ocelot_teardown_devlink_ports(ocelot);
593 out_ocelot_devlink_unregister:
594 	ocelot_deinit(ocelot);
595 out_put_ports:
596 	of_node_put(ports);
597 out_free_devlink:
598 	devlink_free(devlink);
599 	return err;
600 }
601 
602 static int mscc_ocelot_remove(struct platform_device *pdev)
603 {
604 	struct ocelot *ocelot = platform_get_drvdata(pdev);
605 
606 	if (ocelot->fdma)
607 		ocelot_fdma_deinit(ocelot);
608 	devlink_unregister(ocelot->devlink);
609 	ocelot_deinit_timestamp(ocelot);
610 	ocelot_devlink_sb_unregister(ocelot);
611 	mscc_ocelot_release_ports(ocelot);
612 	mscc_ocelot_teardown_devlink_ports(ocelot);
613 	ocelot_deinit(ocelot);
614 	unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
615 	unregister_switchdev_notifier(&ocelot_switchdev_nb);
616 	unregister_netdevice_notifier(&ocelot_netdevice_nb);
617 	devlink_free(ocelot->devlink);
618 
619 	return 0;
620 }
621 
622 static struct platform_driver mscc_ocelot_driver = {
623 	.probe = mscc_ocelot_probe,
624 	.remove = mscc_ocelot_remove,
625 	.driver = {
626 		.name = "ocelot-switch",
627 		.of_match_table = mscc_ocelot_match,
628 	},
629 };
630 
631 module_platform_driver(mscc_ocelot_driver);
632 
633 MODULE_DESCRIPTION("Microsemi Ocelot switch driver");
634 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
635 MODULE_LICENSE("Dual MIT/GPL");
636