mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Colin Foster <colin.foster@in-advantage.com>
To: linux-phy@lists.infradead.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Cc: Russell King <linux@armlinux.org.uk>,
	Kishon Vijay Abraham I <kishon@kernel.org>,
	Vinod Koul <vkoul@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Eric Dumazet <edumazet@google.com>,
	"David S. Miller" <davem@davemloft.net>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Andrew Lunn <andrew@lunn.ch>,
	UNGLinuxDriver@microchip.com,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Claudiu Manoil <claudiu.manoil@nxp.com>,
	Vladimir Oltean <vladimir.oltean@nxp.com>,
	Lee Jones <lee@kernel.org>
Subject: [RFC v1 net-next 6/7] net: dsa: felix: allow external parsing of port nodes
Date: Wed, 15 Feb 2023 23:53:20 -0800	[thread overview]
Message-ID: <20230216075321.2898003-7-colin.foster@in-advantage.com> (raw)
In-Reply-To: <20230216075321.2898003-1-colin.foster@in-advantage.com>

When the felix driver parses the device tree, it does so in such a way that
every node is parsed in a loop. This is done in the felix_init_structs()
function. After this is done, a separate loop will invoke
ocelot_init_port() on each port.

This causes problems if a user of the felix driver needs to retain some
information from the device tree during port initialization. A driver
might, for example, need to create call phylink_create() during
ocelot_init_port(), which requires a reference to the fwnode_handle.

Add a hook from felix into the sub-drivers, where they can optionally grab
references to the device_node when needed.

Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
---
 drivers/net/dsa/ocelot/felix.c | 54 +++++++++++++++++++++++++---------
 drivers/net/dsa/ocelot/felix.h |  5 ++++
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 21dcb9cadc12..b6e3a88addb8 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1245,7 +1245,8 @@ static int felix_parse_ports_node(struct felix *felix,
 				  struct device_node *ports_node,
 				  phy_interface_t *port_phy_modes)
 {
-	struct device *dev = felix->ocelot.dev;
+	struct ocelot *ocelot = &felix->ocelot;
+	struct device *dev = ocelot->dev;
 	struct device_node *child;
 
 	for_each_available_child_of_node(ports_node, child) {
@@ -1285,6 +1286,19 @@ static int felix_parse_ports_node(struct felix *felix,
 		}
 
 		port_phy_modes[port] = phy_mode;
+
+		if (dsa_is_cpu_port(felix->ds, port) ||
+		    !felix->info->parse_port_node)
+			continue;
+
+		err = felix->info->parse_port_node(ocelot, child, phy_mode,
+						   port);
+		if (err < 0) {
+			dev_err(dev, "Unable to create etherdev for port %d\n",
+				port);
+			of_node_put(child);
+			return err;
+		}
 	}
 
 	return 0;
@@ -1396,8 +1410,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 
 	err = felix_parse_dt(felix, port_phy_modes);
 	if (err) {
-		kfree(port_phy_modes);
-		return err;
+		goto free_port_modes;
 	}
 
 	for (i = 0; i < TARGET_MAX; i++) {
@@ -1406,8 +1419,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 			dev_err(ocelot->dev,
 				"Failed to map device memory space: %pe\n",
 				target);
-			kfree(port_phy_modes);
-			return PTR_ERR(target);
+			err = PTR_ERR(target);
+			goto free_port_modes;
 		}
 
 		ocelot->targets[i] = target;
@@ -1416,8 +1429,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 	err = ocelot_regfields_init(ocelot, felix->info->regfields);
 	if (err) {
 		dev_err(ocelot->dev, "failed to init reg fields map\n");
-		kfree(port_phy_modes);
-		return err;
+		goto free_port_modes;
 	}
 
 	for (port = 0; port < num_phys_ports; port++) {
@@ -1429,8 +1441,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 		if (!ocelot_port) {
 			dev_err(ocelot->dev,
 				"failed to allocate port memory\n");
-			kfree(port_phy_modes);
-			return -ENOMEM;
+			err = -ENOMEM;
+			goto free_port_modes;
 		}
 
 		target = felix_request_port_regmap(felix, port);
@@ -1438,8 +1450,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 			dev_err(ocelot->dev,
 				"Failed to map memory space for port %d: %pe\n",
 				port, target);
-			kfree(port_phy_modes);
-			return PTR_ERR(target);
+			err = PTR_ERR(target);
+			goto free_port_modes;
 		}
 
 		ocelot_port->phy_mode = port_phy_modes[port];
@@ -1449,15 +1461,21 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 		ocelot->ports[port] = ocelot_port;
 	}
 
-	kfree(port_phy_modes);
-
 	if (felix->info->mdio_bus_alloc) {
 		err = felix->info->mdio_bus_alloc(ocelot);
 		if (err < 0)
-			return err;
+			goto free_port_modes;
 	}
 
+	kfree(port_phy_modes);
+
 	return 0;
+
+free_port_modes:
+	if (felix->info->phylink_of_cleanup)
+		felix->info->phylink_of_cleanup(ocelot);
+	kfree(port_phy_modes);
+	return err;
 }
 
 static void ocelot_port_purge_txtstamp_skb(struct ocelot *ocelot, int port,
@@ -1574,12 +1592,18 @@ static int felix_setup(struct dsa_switch *ds)
 	dsa_switch_for_each_available_port(dp, ds) {
 		ocelot_init_port(ocelot, dp->index);
 
+		if (felix->info->phylink_create)
+			felix->info->phylink_create(ocelot, dp->index);
+
 		/* Set the default QoS Classification based on PCP and DEI
 		 * bits of vlan tag.
 		 */
 		felix_port_qos_map_init(ocelot, dp->index);
 	}
 
+	if (felix->info->phylink_of_cleanup)
+		felix->info->phylink_of_cleanup(ocelot);
+
 	err = ocelot_devlink_sb_register(ocelot);
 	if (err)
 		goto out_deinit_ports;
@@ -1604,6 +1628,8 @@ static int felix_setup(struct dsa_switch *ds)
 	ocelot_deinit(ocelot);
 
 out_mdiobus_free:
+	if (felix->info->phylink_of_cleanup)
+		felix->info->phylink_of_cleanup(ocelot);
 	if (felix->info->mdio_bus_free)
 		felix->info->mdio_bus_free(ocelot);
 
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index d5d0b30c0b75..ffb60bcf1817 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -58,6 +58,11 @@ struct felix_info {
 	void	(*tas_guard_bands_update)(struct ocelot *ocelot, int port);
 	void	(*port_sched_speed_set)(struct ocelot *ocelot, int port,
 					u32 speed);
+	int	(*parse_port_node)(struct ocelot *ocelot,
+				   struct device_node *ports_node,
+				   phy_interface_t phy_mode, int port);
+	int	(*phylink_create)(struct ocelot *ocelot, int port);
+	void	(*phylink_of_cleanup)(struct ocelot *ocelot);
 };
 
 /* Methods for initializing the hardware resources specific to a tagging
-- 
2.25.1


  parent reply	other threads:[~2023-02-16  7:54 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-16  7:53 [RFC v1 net-next 0/7] add support for ocelot external ports Colin Foster
2023-02-16  7:53 ` [RFC v1 net-next 1/7] phy: phy-ocelot-serdes: add ability to be used in a non-syscon configuration Colin Foster
2023-02-16  7:53 ` [RFC v1 net-next 2/7] mfd: ocelot: add ocelot-serdes capability Colin Foster
2023-03-03 10:48   ` Lee Jones
2023-03-03 15:12     ` Colin Foster
2023-03-03 21:57       ` Lee Jones
2023-02-16  7:53 ` [RFC v1 net-next 3/7] net: mscc: ocelot: expose ocelot_pll5_init routine Colin Foster
2023-02-16  7:53 ` [RFC v1 net-next 4/7] net: mscc: ocelot: expose generic phylink_mac_config routine Colin Foster
2023-02-16  7:53 ` [RFC v1 net-next 5/7] net: dsa: felix: attempt to initialize internal hsio plls Colin Foster
2023-02-16  7:53 ` Colin Foster [this message]
2023-02-16  7:53 ` [RFC v1 net-next 7/7] net: dsa: ocelot_ext: add support for external phys Colin Foster
2023-02-16 11:17   ` Russell King (Oracle)
2023-02-17  1:31     ` Colin Foster
2023-02-16 12:14 ` [RFC v1 net-next 0/7] add support for ocelot external ports Russell King (Oracle)
2023-02-17  0:42   ` Colin Foster
2023-02-17  1:11     ` Vladimir Oltean
2023-02-17  7:02       ` Colin Foster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230216075321.2898003-7-colin.foster@in-advantage.com \
    --to=colin.foster@in-advantage.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=andrew@lunn.ch \
    --cc=claudiu.manoil@nxp.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=f.fainelli@gmail.com \
    --cc=kishon@kernel.org \
    --cc=kuba@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=vkoul@kernel.org \
    --cc=vladimir.oltean@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®