[PATCH 06/41] net: phy: Iterate over both registered PHYs and struct phy_driver linker list

Marek Vasut marek.vasut+renesas at mailbox.org
Sun Mar 19 18:02:42 CET 2023

Introduce U_BOOT_PHY_DRIVER() macro which is used to add struct phy_driver
into a new linker list section containing all compiled in struct phy_driver
drivers. This is so far empty until PHY drivers are converted over to this

Iterate over both drivers registered using soon to be legacy phy_register()
as well as drivers in the new linker list when looking up a suitable PHY
driver. This way, PHY drivers can be converted over to the new macro one
driver at a time.

The relocation of callbacks for linker list based drivers now happens in
phy_init() call as the drivers are available at that point in time, and
phy_register() is not called for those drivers.

Signed-off-by: Marek Vasut <marek.vasut+renesas at mailbox.org>
Cc: "Ariel D'Alessandro" <ariel.dalessandro at collabora.com>
Cc: "Cédric Le Goater" <clg at kaod.org>
Cc: "Marek Behún" <kabel at kernel.org>
Cc: Alex Nemirovsky <alex.nemirovsky at cortina-access.com>
Cc: Haolin Li <li.haolin at qq.com>
Cc: Heinrich Schuchardt <xypron.glpk at gmx.de>
Cc: Joe Hershberger <joe.hershberger at ni.com>
Cc: Joel Stanley <joel at jms.id.au>
Cc: Josua Mayer <josua at solid-run.com>
Cc: Marek Vasut <marek.vasut+renesas at mailbox.org>
Cc: Michael Trimarchi <michael at amarulasolutions.com>
Cc: Michal Simek <michal.simek at amd.com>
Cc: Nate Drude <nate.d at variscite.com>
Cc: Neil Armstrong <neil.armstrong at linaro.org>
Cc: Radu Pirea <radu-nicolae.pirea at oss.nxp.com>
Cc: Ramon Fried <rfried.dev at gmail.com>
Cc: Samuel Mendoza-Jonas <sam at mendozajonas.com>
Cc: Stefan Roese <sr at denx.de>
Cc: T Karthik Reddy <t.karthik.reddy at xilinx.com>
Cc: Tim Harvey <tharvey at gateworks.com>
Cc: Vladimir Oltean <vladimir.oltean at nxp.com>
Cc: u-boot-amlogic at groups.io
 drivers/net/phy/phy.c | 15 +++++++++++++++
 include/phy.h         |  7 +++++++
 2 files changed, 22 insertions(+)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 5097c32b829..50bfabbb765 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -495,6 +495,9 @@ static void phy_drv_reloc(struct phy_driver *drv)
 int phy_init(void)
+	const int ll_n_ents = ll_entry_count(struct phy_driver, phy_driver);
+	struct phy_driver *drv, *ll_entry;
 	 * The pointers inside phy_drivers also needs to be updated incase of
 	 * manual reloc, without which these points to some invalid
@@ -504,6 +507,11 @@ int phy_init(void)
 	head->next = (void *)head->next + gd->reloc_off;
 	head->prev = (void *)head->prev + gd->reloc_off;
+	/* Perform manual relocation on linker list based PHY drivers */
+	ll_entry = ll_entry_start(struct phy_driver, phy_driver);
+	for (drv = ll_entry; drv != ll_entry + ll_n_ents; drv++)
+		phy_drv_reloc(drv);
@@ -660,6 +668,8 @@ static struct phy_driver *generic_for_phy(struct phy_device *phydev)
 static struct phy_driver *get_phy_driver(struct phy_device *phydev)
+	const int ll_n_ents = ll_entry_count(struct phy_driver, phy_driver);
+	struct phy_driver *ll_entry;
 	struct list_head *entry;
 	int phy_id = phydev->phy_id;
 	struct phy_driver *drv = NULL;
@@ -670,6 +680,11 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev)
 			return drv;
+	ll_entry = ll_entry_start(struct phy_driver, phy_driver);
+	for (drv = ll_entry; drv != ll_entry + ll_n_ents; drv++)
+		if ((drv->uid & drv->mask) == (phy_id & drv->mask))
+			return drv;
 	/* If we made it here, there's no driver for this PHY */
 	return generic_for_phy(phydev);
diff --git a/include/phy.h b/include/phy.h
index 87aa86c2e78..1eccfacec68 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -345,6 +345,13 @@ int phy_fixed_init(void);
 int phy_ncsi_init(void);
 int phy_xilinx_gmii2rgmii_init(void);
+ * U_BOOT_PHY_DRIVER() - Declare a new U-Boot driver
+ * @__name: name of the driver
+ */
+#define U_BOOT_PHY_DRIVER(__name)					\
+	ll_entry_declare(struct phy_driver, __name, phy_driver)
 int board_phy_config(struct phy_device *phydev);
 int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);

More information about the U-Boot mailing list