Skip to content

Commit 7c41179

Browse files
vladimirolteandavem330
authored andcommitted
net: mscc: ocelot: refactor ports parsing code into a dedicated function
mscc_ocelot_probe() is already pretty large and hard to follow. So move the code for parsing ports in a separate function. This makes it easier for the next patch to just call mscc_ocelot_release_ports from the error path of mscc_ocelot_init_ports. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Tested-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d1cc0e9 commit 7c41179

File tree

1 file changed

+110
-99
lines changed

1 file changed

+110
-99
lines changed

drivers/net/ethernet/mscc/ocelot_vsc7514.c

Lines changed: 110 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -896,11 +896,115 @@ static struct ptp_clock_info ocelot_ptp_clock_info = {
896896
.enable = ocelot_ptp_enable,
897897
};
898898

899+
static int mscc_ocelot_init_ports(struct platform_device *pdev,
900+
struct device_node *ports)
901+
{
902+
struct ocelot *ocelot = platform_get_drvdata(pdev);
903+
struct device_node *portnp;
904+
int err;
905+
906+
ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
907+
sizeof(struct ocelot_port *), GFP_KERNEL);
908+
if (!ocelot->ports)
909+
return -ENOMEM;
910+
911+
/* No NPI port */
912+
ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
913+
OCELOT_TAG_PREFIX_NONE);
914+
915+
for_each_available_child_of_node(ports, portnp) {
916+
struct ocelot_port_private *priv;
917+
struct ocelot_port *ocelot_port;
918+
struct device_node *phy_node;
919+
phy_interface_t phy_mode;
920+
struct phy_device *phy;
921+
struct regmap *target;
922+
struct resource *res;
923+
struct phy *serdes;
924+
char res_name[8];
925+
u32 port;
926+
927+
if (of_property_read_u32(portnp, "reg", &port))
928+
continue;
929+
930+
snprintf(res_name, sizeof(res_name), "port%d", port);
931+
932+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
933+
res_name);
934+
target = ocelot_regmap_init(ocelot, res);
935+
if (IS_ERR(target))
936+
continue;
937+
938+
phy_node = of_parse_phandle(portnp, "phy-handle", 0);
939+
if (!phy_node)
940+
continue;
941+
942+
phy = of_phy_find_device(phy_node);
943+
of_node_put(phy_node);
944+
if (!phy)
945+
continue;
946+
947+
err = ocelot_probe_port(ocelot, port, target, phy);
948+
if (err) {
949+
of_node_put(portnp);
950+
return err;
951+
}
952+
953+
ocelot_port = ocelot->ports[port];
954+
priv = container_of(ocelot_port, struct ocelot_port_private,
955+
port);
956+
957+
of_get_phy_mode(portnp, &phy_mode);
958+
959+
ocelot_port->phy_mode = phy_mode;
960+
961+
switch (ocelot_port->phy_mode) {
962+
case PHY_INTERFACE_MODE_NA:
963+
continue;
964+
case PHY_INTERFACE_MODE_SGMII:
965+
break;
966+
case PHY_INTERFACE_MODE_QSGMII:
967+
/* Ensure clock signals and speed is set on all
968+
* QSGMII links
969+
*/
970+
ocelot_port_writel(ocelot_port,
971+
DEV_CLOCK_CFG_LINK_SPEED
972+
(OCELOT_SPEED_1000),
973+
DEV_CLOCK_CFG);
974+
break;
975+
default:
976+
dev_err(ocelot->dev,
977+
"invalid phy mode for port%d, (Q)SGMII only\n",
978+
port);
979+
of_node_put(portnp);
980+
return -EINVAL;
981+
}
982+
983+
serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
984+
if (IS_ERR(serdes)) {
985+
err = PTR_ERR(serdes);
986+
if (err == -EPROBE_DEFER)
987+
dev_dbg(ocelot->dev, "deferring probe\n");
988+
else
989+
dev_err(ocelot->dev,
990+
"missing SerDes phys for port%d\n",
991+
port);
992+
993+
of_node_put(portnp);
994+
return err;
995+
}
996+
997+
priv->serdes = serdes;
998+
}
999+
1000+
return 0;
1001+
}
1002+
8991003
static int mscc_ocelot_probe(struct platform_device *pdev)
9001004
{
9011005
struct device_node *np = pdev->dev.of_node;
902-
struct device_node *ports, *portnp;
9031006
int err, irq_xtr, irq_ptp_rdy;
1007+
struct device_node *ports;
9041008
struct ocelot *ocelot;
9051009
struct regmap *hsio;
9061010
unsigned int i;
@@ -985,19 +1089,12 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
9851089

9861090
ports = of_get_child_by_name(np, "ethernet-ports");
9871091
if (!ports) {
988-
dev_err(&pdev->dev, "no ethernet-ports child node found\n");
1092+
dev_err(ocelot->dev, "no ethernet-ports child node found\n");
9891093
return -ENODEV;
9901094
}
9911095

9921096
ocelot->num_phys_ports = of_get_child_count(ports);
9931097

994-
ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
995-
sizeof(struct ocelot_port *), GFP_KERNEL);
996-
if (!ocelot->ports) {
997-
err = -ENOMEM;
998-
goto out_put_ports;
999-
}
1000-
10011098
ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
10021099
ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
10031100
ocelot->vcap = vsc7514_vcap_props;
@@ -1006,6 +1103,10 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
10061103
if (err)
10071104
goto out_put_ports;
10081105

1106+
err = mscc_ocelot_init_ports(pdev, ports);
1107+
if (err)
1108+
goto out_put_ports;
1109+
10091110
if (ocelot->ptp) {
10101111
err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info);
10111112
if (err) {
@@ -1015,96 +1116,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
10151116
}
10161117
}
10171118

1018-
/* No NPI port */
1019-
ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
1020-
OCELOT_TAG_PREFIX_NONE);
1021-
1022-
for_each_available_child_of_node(ports, portnp) {
1023-
struct ocelot_port_private *priv;
1024-
struct ocelot_port *ocelot_port;
1025-
struct device_node *phy_node;
1026-
phy_interface_t phy_mode;
1027-
struct phy_device *phy;
1028-
struct regmap *target;
1029-
struct resource *res;
1030-
struct phy *serdes;
1031-
char res_name[8];
1032-
u32 port;
1033-
1034-
if (of_property_read_u32(portnp, "reg", &port))
1035-
continue;
1036-
1037-
snprintf(res_name, sizeof(res_name), "port%d", port);
1038-
1039-
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1040-
res_name);
1041-
target = ocelot_regmap_init(ocelot, res);
1042-
if (IS_ERR(target))
1043-
continue;
1044-
1045-
phy_node = of_parse_phandle(portnp, "phy-handle", 0);
1046-
if (!phy_node)
1047-
continue;
1048-
1049-
phy = of_phy_find_device(phy_node);
1050-
of_node_put(phy_node);
1051-
if (!phy)
1052-
continue;
1053-
1054-
err = ocelot_probe_port(ocelot, port, target, phy);
1055-
if (err) {
1056-
of_node_put(portnp);
1057-
goto out_put_ports;
1058-
}
1059-
1060-
ocelot_port = ocelot->ports[port];
1061-
priv = container_of(ocelot_port, struct ocelot_port_private,
1062-
port);
1063-
1064-
of_get_phy_mode(portnp, &phy_mode);
1065-
1066-
ocelot_port->phy_mode = phy_mode;
1067-
1068-
switch (ocelot_port->phy_mode) {
1069-
case PHY_INTERFACE_MODE_NA:
1070-
continue;
1071-
case PHY_INTERFACE_MODE_SGMII:
1072-
break;
1073-
case PHY_INTERFACE_MODE_QSGMII:
1074-
/* Ensure clock signals and speed is set on all
1075-
* QSGMII links
1076-
*/
1077-
ocelot_port_writel(ocelot_port,
1078-
DEV_CLOCK_CFG_LINK_SPEED
1079-
(OCELOT_SPEED_1000),
1080-
DEV_CLOCK_CFG);
1081-
break;
1082-
default:
1083-
dev_err(ocelot->dev,
1084-
"invalid phy mode for port%d, (Q)SGMII only\n",
1085-
port);
1086-
of_node_put(portnp);
1087-
err = -EINVAL;
1088-
goto out_put_ports;
1089-
}
1090-
1091-
serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
1092-
if (IS_ERR(serdes)) {
1093-
err = PTR_ERR(serdes);
1094-
if (err == -EPROBE_DEFER)
1095-
dev_dbg(ocelot->dev, "deferring probe\n");
1096-
else
1097-
dev_err(ocelot->dev,
1098-
"missing SerDes phys for port%d\n",
1099-
port);
1100-
1101-
of_node_put(portnp);
1102-
goto out_put_ports;
1103-
}
1104-
1105-
priv->serdes = serdes;
1106-
}
1107-
11081119
register_netdevice_notifier(&ocelot_netdevice_nb);
11091120
register_switchdev_notifier(&ocelot_switchdev_nb);
11101121
register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);

0 commit comments

Comments
 (0)