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
next prev 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®