[net-next PATCH v6 05/10] net: pcs: lynx: Convert to an MDIO driver

Sean Anderson posted 10 patches 4 months ago
[net-next PATCH v6 05/10] net: pcs: lynx: Convert to an MDIO driver
Posted by Sean Anderson 4 months ago
This converts the lynx PCS driver to a proper MDIO driver.
This allows using a more conventional driver lifecycle (e.g. with a
probe and remove). It will also make it easier to add interrupt support.

The existing helpers are converted to bind the MDIO driver instead of
creating the PCS directly. As lynx_pcs_create_mdiodev creates the PCS
device, we can just set the modalias. For lynx_pcs_create_fwnode, we try
to get the PCS the usual way, and if that fails we edit the devicetree
to add a compatible and reprobe the device.

To ensure my contributions remain free software, remove the BSD option
from the license. This is permitted because the SPDX uses "OR".

Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---

Changes in v6:
- Define lynx_pcs_of_match only when OF_MATCH is enabled
- Remove duplicate include of phylink.h
- Remove unneccessary Kconfig selects

Changes in v5:
- Use MDIO_BUS instead of MDIO_DEVICE

Changes in v4:
- Add a note about the license
- Convert to dev-less pcs_put

Changes in v3:
- Call devm_pcs_register instead of devm_pcs_register_provider

Changes in v2:
- Add support for #pcs-cells
- Remove unused variable lynx_properties

 drivers/net/dsa/ocelot/felix_vsc9959.c        |  11 +-
 drivers/net/dsa/ocelot/seville_vsc9953.c      |  11 +-
 drivers/net/ethernet/altera/altera_tse_main.c |   7 +-
 drivers/net/ethernet/freescale/dpaa2/Kconfig  |   1 +
 .../net/ethernet/freescale/dpaa2/dpaa2-mac.c  |  11 +-
 .../net/ethernet/freescale/enetc/enetc_pf.c   |   8 +-
 .../net/ethernet/freescale/enetc/enetc_pf.h   |   1 -
 .../freescale/enetc/enetc_pf_common.c         |   4 +-
 drivers/net/ethernet/freescale/fman/Kconfig   |   2 +-
 .../net/ethernet/freescale/fman/fman_memac.c  |  25 ++--
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |   1 +
 .../ethernet/stmicro/stmmac/dwmac-socfpga.c   |   6 +-
 drivers/net/pcs/Kconfig                       |  12 +-
 drivers/net/pcs/pcs-lynx.c                    | 113 ++++++++++--------
 include/linux/pcs-lynx.h                      |  13 +-
 15 files changed, 116 insertions(+), 110 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 087d368a59e0..6feae845af10 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -12,6 +12,7 @@
 #include <net/tc_act/tc_gate.h>
 #include <soc/mscc/ocelot.h>
 #include <linux/dsa/ocelot.h>
+#include <linux/pcs.h>
 #include <linux/pcs-lynx.h>
 #include <net/pkt_sched.h>
 #include <linux/iopoll.h>
@@ -1033,7 +1034,7 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
 		if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_INTERNAL)
 			continue;
 
-		phylink_pcs = lynx_pcs_create_mdiodev(felix->imdio, port);
+		phylink_pcs = lynx_pcs_create_mdiodev(dev, felix->imdio, port);
 		if (IS_ERR(phylink_pcs))
 			continue;
 
@@ -1050,12 +1051,8 @@ static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
 	struct felix *felix = ocelot_to_felix(ocelot);
 	int port;
 
-	for (port = 0; port < ocelot->num_phys_ports; port++) {
-		struct phylink_pcs *phylink_pcs = felix->pcs[port];
-
-		if (phylink_pcs)
-			lynx_pcs_destroy(phylink_pcs);
-	}
+	for (port = 0; port < ocelot->num_phys_ports; port++)
+		pcs_put(felix->pcs[port]);
 	mdiobus_unregister(felix->imdio);
 	mdiobus_free(felix->imdio);
 }
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index 28bcdef34a6c..627c0bd7a777 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -10,6 +10,7 @@
 #include <linux/mdio/mdio-mscc-miim.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of_mdio.h>
+#include <linux/pcs.h>
 #include <linux/pcs-lynx.h>
 #include <linux/dsa/ocelot.h>
 #include <linux/iopoll.h>
@@ -926,7 +927,7 @@ static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
 		if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_INTERNAL)
 			continue;
 
-		phylink_pcs = lynx_pcs_create_mdiodev(felix->imdio, addr);
+		phylink_pcs = lynx_pcs_create_mdiodev(dev, felix->imdio, addr);
 		if (IS_ERR(phylink_pcs))
 			continue;
 
@@ -943,12 +944,8 @@ static void vsc9953_mdio_bus_free(struct ocelot *ocelot)
 	struct felix *felix = ocelot_to_felix(ocelot);
 	int port;
 
-	for (port = 0; port < ocelot->num_phys_ports; port++) {
-		struct phylink_pcs *phylink_pcs = felix->pcs[port];
-
-		if (phylink_pcs)
-			lynx_pcs_destroy(phylink_pcs);
-	}
+	for (port = 0; port < ocelot->num_phys_ports; port++)
+		pcs_put(felix->pcs[port]);
 
 	/* mdiobus_unregister and mdiobus_free handled by devres */
 }
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 3f6204de9e6b..8bd4753a04bc 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -32,6 +32,7 @@
 #include <linux/of.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
+#include <linux/pcs.h>
 #include <linux/pcs-lynx.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
@@ -1412,7 +1413,7 @@ static int altera_tse_probe(struct platform_device *pdev)
 		goto err_init_pcs;
 	}
 
-	priv->pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
+	priv->pcs = lynx_pcs_create_mdiodev(&pdev->dev, pcs_bus, 0);
 	if (IS_ERR(priv->pcs)) {
 		ret = PTR_ERR(priv->pcs);
 		goto err_init_pcs;
@@ -1444,7 +1445,7 @@ static int altera_tse_probe(struct platform_device *pdev)
 
 	return 0;
 err_init_phylink:
-	lynx_pcs_destroy(priv->pcs);
+	pcs_put(priv->pcs);
 err_init_pcs:
 	unregister_netdev(ndev);
 err_register_netdev:
@@ -1466,7 +1467,7 @@ static void altera_tse_remove(struct platform_device *pdev)
 	altera_tse_mdio_destroy(ndev);
 	unregister_netdev(ndev);
 	phylink_destroy(priv->phylink);
-	lynx_pcs_destroy(priv->pcs);
+	pcs_put(priv->pcs);
 
 	free_netdev(ndev);
 }
diff --git a/drivers/net/ethernet/freescale/dpaa2/Kconfig b/drivers/net/ethernet/freescale/dpaa2/Kconfig
index d029b69c3f18..3309f5297255 100644
--- a/drivers/net/ethernet/freescale/dpaa2/Kconfig
+++ b/drivers/net/ethernet/freescale/dpaa2/Kconfig
@@ -2,6 +2,7 @@
 config FSL_DPAA2_ETH
 	tristate "Freescale DPAA2 Ethernet"
 	depends on FSL_MC_BUS && FSL_MC_DPIO
+	select OF_DYNAMIC
 	select PHYLINK
 	select PCS_LYNX
 	select FSL_XGMAC_MDIO
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index 422ce13a7c94..0dc0a265db51 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -2,6 +2,7 @@
 /* Copyright 2019 NXP */
 
 #include <linux/acpi.h>
+#include <linux/pcs.h>
 #include <linux/pcs-lynx.h>
 #include <linux/phy/phy.h>
 #include <linux/property.h>
@@ -262,7 +263,7 @@ static int dpaa2_pcs_create(struct dpaa2_mac *mac,
 		return 0;
 	}
 
-	pcs = lynx_pcs_create_fwnode(node);
+	pcs = lynx_pcs_create_fwnode(&mac->mc_dev->dev, node);
 	fwnode_handle_put(node);
 
 	if (pcs == ERR_PTR(-EPROBE_DEFER)) {
@@ -288,12 +289,8 @@ static int dpaa2_pcs_create(struct dpaa2_mac *mac,
 
 static void dpaa2_pcs_destroy(struct dpaa2_mac *mac)
 {
-	struct phylink_pcs *phylink_pcs = mac->pcs;
-
-	if (phylink_pcs) {
-		lynx_pcs_destroy(phylink_pcs);
-		mac->pcs = NULL;
-	}
+	pcs_put(mac->pcs);
+	mac->pcs = NULL;
 }
 
 static void dpaa2_mac_set_supported_interfaces(struct dpaa2_mac *mac)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index f63a29e2e031..8d0950c28190 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -34,12 +34,7 @@ static void enetc_pf_set_primary_mac_addr(struct enetc_hw *hw, int si,
 static struct phylink_pcs *enetc_pf_create_pcs(struct enetc_pf *pf,
 					       struct mii_bus *bus)
 {
-	return lynx_pcs_create_mdiodev(bus, 0);
-}
-
-static void enetc_pf_destroy_pcs(struct phylink_pcs *pcs)
-{
-	lynx_pcs_destroy(pcs);
+	return lynx_pcs_create_mdiodev(&pf->si->pdev->dev, bus, 0);
 }
 
 static void enetc_set_vlan_promisc(struct enetc_hw *hw, char si_map)
@@ -914,7 +909,6 @@ static const struct enetc_pf_ops enetc_pf_ops = {
 	.set_si_primary_mac = enetc_pf_set_primary_mac_addr,
 	.get_si_primary_mac = enetc_pf_get_primary_mac_addr,
 	.create_pcs = enetc_pf_create_pcs,
-	.destroy_pcs = enetc_pf_destroy_pcs,
 	.enable_psfp = enetc_psfp_enable,
 };
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index ae407e9e9ee7..be22b036df42 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -32,7 +32,6 @@ struct enetc_pf_ops {
 	void (*set_si_primary_mac)(struct enetc_hw *hw, int si, const u8 *addr);
 	void (*get_si_primary_mac)(struct enetc_hw *hw, int si, u8 *addr);
 	struct phylink_pcs *(*create_pcs)(struct enetc_pf *pf, struct mii_bus *bus);
-	void (*destroy_pcs)(struct phylink_pcs *pcs);
 	int (*enable_psfp)(struct enetc_ndev_priv *priv);
 };
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index edf14a95cab7..1c53036d17df 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -4,6 +4,7 @@
 #include <linux/fsl/enetc_mdio.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
+#include <linux/pcs.h>
 
 #include "enetc_pf_common.h"
 
@@ -248,8 +249,7 @@ static int enetc_imdio_create(struct enetc_pf *pf)
 
 static void enetc_imdio_remove(struct enetc_pf *pf)
 {
-	if (pf->pcs && pf->ops->destroy_pcs)
-		pf->ops->destroy_pcs(pf->pcs);
+	pcs_put(pf->pcs);
 
 	if (pf->imdio) {
 		mdiobus_unregister(pf->imdio);
diff --git a/drivers/net/ethernet/freescale/fman/Kconfig b/drivers/net/ethernet/freescale/fman/Kconfig
index a55542c1ad65..166fcde6100a 100644
--- a/drivers/net/ethernet/freescale/fman/Kconfig
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -3,10 +3,10 @@ config FSL_FMAN
 	tristate "FMan support"
 	depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
 	select GENERIC_ALLOCATOR
+	select OF_DYNAMIC
 	select PHYLINK
 	select PCS_LYNX
 	select CRC32
-	default n
 	help
 		Freescale Data-Path Acceleration Architecture Frame Manager
 		(FMan) support
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index 3925441143fa..a6064bc80ce7 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -11,6 +11,7 @@
 
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/pcs.h>
 #include <linux/pcs-lynx.h>
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
@@ -972,21 +973,21 @@ static int memac_init(struct fman_mac *memac)
 	return 0;
 }
 
-static void pcs_put(struct phylink_pcs *pcs)
+static void memac_pcs_put(struct phylink_pcs *pcs)
 {
 	if (IS_ERR_OR_NULL(pcs))
 		return;
 
-	lynx_pcs_destroy(pcs);
+	pcs_put(pcs);
 }
 
 static int memac_free(struct fman_mac *memac)
 {
 	free_init_resources(memac);
 
-	pcs_put(memac->sgmii_pcs);
-	pcs_put(memac->qsgmii_pcs);
-	pcs_put(memac->xfi_pcs);
+	memac_pcs_put(memac->sgmii_pcs);
+	memac_pcs_put(memac->qsgmii_pcs);
+	memac_pcs_put(memac->xfi_pcs);
 	kfree(memac->memac_drv_param);
 	kfree(memac);
 
@@ -1033,7 +1034,8 @@ static struct fman_mac *memac_config(struct mac_device *mac_dev,
 	return memac;
 }
 
-static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node,
+static struct phylink_pcs *memac_pcs_create(struct device *dev,
+					    struct device_node *mac_node,
 					    int index)
 {
 	struct device_node *node;
@@ -1043,7 +1045,7 @@ static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node,
 	if (!node)
 		return ERR_PTR(-ENODEV);
 
-	pcs = lynx_pcs_create_fwnode(of_fwnode_handle(node));
+	pcs = lynx_pcs_create_fwnode(dev, of_fwnode_handle(node));
 	of_node_put(node);
 
 	return pcs;
@@ -1100,7 +1102,7 @@ int memac_initialization(struct mac_device *mac_dev,
 
 	err = of_property_match_string(mac_node, "pcs-handle-names", "xfi");
 	if (err >= 0) {
-		memac->xfi_pcs = memac_pcs_create(mac_node, err);
+		memac->xfi_pcs = memac_pcs_create(mac_dev->dev, mac_node, err);
 		if (IS_ERR(memac->xfi_pcs)) {
 			err = PTR_ERR(memac->xfi_pcs);
 			dev_err_probe(mac_dev->dev, err, "missing xfi pcs\n");
@@ -1112,7 +1114,8 @@ int memac_initialization(struct mac_device *mac_dev,
 
 	err = of_property_match_string(mac_node, "pcs-handle-names", "qsgmii");
 	if (err >= 0) {
-		memac->qsgmii_pcs = memac_pcs_create(mac_node, err);
+		memac->qsgmii_pcs = memac_pcs_create(mac_dev->dev, mac_node,
+						     err);
 		if (IS_ERR(memac->qsgmii_pcs)) {
 			err = PTR_ERR(memac->qsgmii_pcs);
 			dev_err_probe(mac_dev->dev, err,
@@ -1128,11 +1131,11 @@ int memac_initialization(struct mac_device *mac_dev,
 	 */
 	err = of_property_match_string(mac_node, "pcs-handle-names", "sgmii");
 	if (err == -EINVAL || err == -ENODATA)
-		pcs = memac_pcs_create(mac_node, 0);
+		pcs = memac_pcs_create(mac_dev->dev, mac_node, 0);
 	else if (err < 0)
 		goto _return_fm_mac_free;
 	else
-		pcs = memac_pcs_create(mac_node, err);
+		pcs = memac_pcs_create(mac_dev->dev, mac_node, err);
 
 	if (IS_ERR(pcs)) {
 		err = PTR_ERR(pcs);
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 67fa879b1e52..cb4d5374d055 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -182,6 +182,7 @@ config DWMAC_SOCFPGA
 	tristate "SOCFPGA dwmac support"
 	default ARCH_INTEL_SOCFPGA
 	depends on OF && (ARCH_INTEL_SOCFPGA || COMPILE_TEST)
+	select OF_DYNAMIC
 	select MFD_SYSCON
 	select MDIO_REGMAP
 	select REGMAP_MMIO
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 72b50f6d72f4..325486c06511 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -8,6 +8,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_net.h>
+#include <linux/pcs.h>
 #include <linux/phy.h>
 #include <linux/regmap.h>
 #include <linux/mdio/mdio-regmap.h>
@@ -414,7 +415,7 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv)
 	if (IS_ERR(pcs_bus))
 		return PTR_ERR(pcs_bus);
 
-	pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
+	pcs = lynx_pcs_create_mdiodev(priv->device, pcs_bus, 0);
 	if (IS_ERR(pcs))
 		return PTR_ERR(pcs);
 
@@ -424,8 +425,7 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv)
 
 static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv)
 {
-	if (priv->hw->phylink_pcs)
-		lynx_pcs_destroy(priv->hw->phylink_pcs);
+	pcs_put(priv->hw->phylink_pcs);
 }
 
 static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv,
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index 6d19625b696d..f42839a0c332 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -26,10 +26,16 @@ config PCS_XPCS
 	  DesignWare XPCS controllers.
 
 config PCS_LYNX
-	tristate
+	tristate "NXP Lynx PCS driver"
+	select MDIO_BUS
+	select PCS
 	help
-	  This module provides helpers to phylink for managing the Lynx PCS
-	  which is part of the Layerscape and QorIQ Ethernet SERDES.
+	  This module provides driver support for the PCSs in Lynx 10g and 28g
+	  SerDes devices. These devices are present in NXP QorIQ SoCs,
+	  including the Layerscape series.
+
+	  If you want to use Ethernet on a QorIQ SoC, say "Y". If compiled as a
+	  module, it will be called "pcs-lynx".
 
 config PCS_MTK_LYNXI
 	tristate
diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c
index 23b40e9eacbb..2989a6f3e3a4 100644
--- a/drivers/net/pcs/pcs-lynx.c
+++ b/drivers/net/pcs/pcs-lynx.c
@@ -1,11 +1,14 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/* Copyright 2020 NXP
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2022 Sean Anderson <seanga2@gmail.com>
+ * Copyright 2020 NXP
  * Lynx PCS MDIO helpers
  */
 
 #include <linux/mdio.h>
-#include <linux/phylink.h>
+#include <linux/of.h>
+#include <linux/pcs.h>
 #include <linux/pcs-lynx.h>
+#include <linux/phylink.h>
 #include <linux/property.h>
 
 #define SGMII_CLOCK_PERIOD_NS		8 /* PCS is clocked at 125 MHz */
@@ -343,16 +346,16 @@ static const phy_interface_t lynx_interfaces[] = {
 	PHY_INTERFACE_MODE_USXGMII,
 };
 
-static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
+static int lynx_pcs_probe(struct mdio_device *mdio)
 {
+	struct device *dev = &mdio->dev;
 	struct lynx_pcs *lynx;
-	int i;
+	int i, ret;
 
-	lynx = kzalloc(sizeof(*lynx), GFP_KERNEL);
+	lynx = devm_kzalloc(dev, sizeof(*lynx), GFP_KERNEL);
 	if (!lynx)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
-	mdio_device_get(mdio);
 	lynx->mdio = mdio;
 	lynx->pcs.ops = &lynx_pcs_phylink_ops;
 	lynx->pcs.poll = true;
@@ -360,32 +363,66 @@ static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio)
 	for (i = 0; i < ARRAY_SIZE(lynx_interfaces); i++)
 		__set_bit(lynx_interfaces[i], lynx->pcs.supported_interfaces);
 
-	return lynx_to_phylink_pcs(lynx);
+	ret = devm_pcs_register(dev, &lynx->pcs);
+	if (ret)
+		return dev_err_probe(dev, ret, "could not register PCS\n");
+	dev_info(dev, "probed\n");
+	return 0;
 }
 
-struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr)
+#ifdef CONFIG_OF
+static const struct of_device_id lynx_pcs_of_match[] = {
+	{ .compatible = "fsl,lynx-pcs" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, lynx_pcs_of_match);
+#endif
+
+static struct mdio_driver lynx_pcs_driver = {
+	.probe = lynx_pcs_probe,
+	.mdiodrv.driver = {
+		.name = "lynx-pcs",
+		.of_match_table = of_match_ptr(lynx_pcs_of_match),
+	},
+};
+mdio_module_driver(lynx_pcs_driver);
+
+struct phylink_pcs *lynx_pcs_create_mdiodev(struct device *dev,
+					    struct mii_bus *bus, int addr)
 {
 	struct mdio_device *mdio;
 	struct phylink_pcs *pcs;
+	int err;
 
 	mdio = mdio_device_create(bus, addr);
 	if (IS_ERR(mdio))
 		return ERR_CAST(mdio);
 
-	pcs = lynx_pcs_create(mdio);
-
-	/* lynx_create() has taken a refcount on the mdiodev if it was
-	 * successful. If lynx_create() fails, this will free the mdio
-	 * device here. In any case, we don't need to hold our reference
-	 * anymore, and putting it here will allow mdio_device_put() in
-	 * lynx_destroy() to automatically free the mdio device.
-	 */
-	mdio_device_put(mdio);
+	mdio->bus_match = mdio_device_bus_match;
+	strscpy(mdio->modalias, "lynx-pcs");
+	err = mdio_device_register(mdio);
+	if (err) {
+		mdio_device_free(mdio);
+		return ERR_PTR(err);
+	}
 
+	pcs = pcs_get_by_dev(dev, &mdio->dev);
+	mdio_device_free(mdio);
 	return pcs;
 }
 EXPORT_SYMBOL(lynx_pcs_create_mdiodev);
 
+static int lynx_pcs_fixup(struct of_changeset *ocs,
+			  struct device_node *np, void *data)
+{
+#ifdef CONFIG_OF_DYNAMIC
+	return of_changeset_add_prop_string(ocs, np, "compatible",
+					    "fsl,lynx-pcs");
+#else
+	return -ENODEV;
+#endif
+}
+
 /*
  * lynx_pcs_create_fwnode() creates a lynx PCS instance from the fwnode
  * device indicated by node.
@@ -396,40 +433,12 @@ EXPORT_SYMBOL(lynx_pcs_create_mdiodev);
  *  -ENOMEM if we fail to allocate memory
  *  pointer to a phylink_pcs on success
  */
-struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node)
+struct phylink_pcs *lynx_pcs_create_fwnode(struct device *dev,
+					   struct fwnode_handle *node)
 {
-	struct mdio_device *mdio;
-	struct phylink_pcs *pcs;
-
-	if (!fwnode_device_is_available(node))
-		return ERR_PTR(-ENODEV);
-
-	mdio = fwnode_mdio_find_device(node);
-	if (!mdio)
-		return ERR_PTR(-EPROBE_DEFER);
-
-	pcs = lynx_pcs_create(mdio);
-
-	/* lynx_create() has taken a refcount on the mdiodev if it was
-	 * successful. If lynx_create() fails, this will free the mdio
-	 * device here. In any case, we don't need to hold our reference
-	 * anymore, and putting it here will allow mdio_device_put() in
-	 * lynx_destroy() to automatically free the mdio device.
-	 */
-	mdio_device_put(mdio);
-
-	return pcs;
+	return pcs_get_by_fwnode_compat(dev, node, lynx_pcs_fixup, NULL);
 }
 EXPORT_SYMBOL_GPL(lynx_pcs_create_fwnode);
 
-void lynx_pcs_destroy(struct phylink_pcs *pcs)
-{
-	struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs);
-
-	mdio_device_put(lynx->mdio);
-	kfree(lynx);
-}
-EXPORT_SYMBOL(lynx_pcs_destroy);
-
-MODULE_DESCRIPTION("NXP Lynx PCS phylink library");
-MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("NXP Lynx PCS phylink driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/pcs-lynx.h b/include/linux/pcs-lynx.h
index 7958cccd16f2..a95801337205 100644
--- a/include/linux/pcs-lynx.h
+++ b/include/linux/pcs-lynx.h
@@ -6,12 +6,13 @@
 #ifndef __LINUX_PCS_LYNX_H
 #define __LINUX_PCS_LYNX_H
 
-#include <linux/mdio.h>
-#include <linux/phylink.h>
+struct device;
+struct mii_bus;
+struct phylink_pcs;
 
-struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr);
-struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node);
-
-void lynx_pcs_destroy(struct phylink_pcs *pcs);
+struct phylink_pcs *lynx_pcs_create_mdiodev(struct device *dev,
+					    struct mii_bus *bus, int addr);
+struct phylink_pcs *lynx_pcs_create_fwnode(struct device *dev,
+					   struct fwnode_handle *node);
 
 #endif /* __LINUX_PCS_LYNX_H */
-- 
2.35.1.1320.gc452695387.dirty
Re: [net-next PATCH v6 05/10] net: pcs: lynx: Convert to an MDIO driver
Posted by kernel test robot 3 months, 4 weeks ago
Hi Sean,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Sean-Anderson/dt-bindings-net-Add-Xilinx-PCS/20250611-143544
base:   net-next/main
patch link:    https://lore.kernel.org/r/20250610233134.3588011-6-sean.anderson%40linux.dev
patch subject: [net-next PATCH v6 05/10] net: pcs: lynx: Convert to an MDIO driver
config: parisc-randconfig-002-20250613 (https://download.01.org/0day-ci/archive/20250613/202506131905.gKLnNnsQ-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250613/202506131905.gKLnNnsQ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202506131905.gKLnNnsQ-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from drivers/regulator/mt6358-regulator.c:8:
   include/linux/of.h: In function 'of_changeset_attach_node':
>> include/linux/of.h:1616:41: error: 'OF_RECONFIG_ATTACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1616 |         return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h:1616:41: note: each undeclared identifier is reported only once for each function it appears in
   include/linux/of.h: In function 'of_changeset_detach_node':
>> include/linux/of.h:1622:41: error: 'OF_RECONFIG_DETACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1622 |         return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h: In function 'of_changeset_add_property':
>> include/linux/of.h:1628:41: error: 'OF_RECONFIG_ADD_PROPERTY' undeclared (first use in this function)
    1628 |         return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_remove_property':
>> include/linux/of.h:1634:41: error: 'OF_RECONFIG_REMOVE_PROPERTY' undeclared (first use in this function)
    1634 |         return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_update_property':
>> include/linux/of.h:1640:41: error: 'OF_RECONFIG_UPDATE_PROPERTY' undeclared (first use in this function)
    1640 |         return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   In file included from drivers/regulator/pbias-regulator.c:27:
   include/linux/of.h: In function 'of_changeset_attach_node':
>> include/linux/of.h:1616:41: error: 'OF_RECONFIG_ATTACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1616 |         return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h:1616:41: note: each undeclared identifier is reported only once for each function it appears in
   include/linux/of.h: In function 'of_changeset_detach_node':
>> include/linux/of.h:1622:41: error: 'OF_RECONFIG_DETACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1622 |         return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h: In function 'of_changeset_add_property':
>> include/linux/of.h:1628:41: error: 'OF_RECONFIG_ADD_PROPERTY' undeclared (first use in this function)
    1628 |         return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_remove_property':
>> include/linux/of.h:1634:41: error: 'OF_RECONFIG_REMOVE_PROPERTY' undeclared (first use in this function)
    1634 |         return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_update_property':
>> include/linux/of.h:1640:41: error: 'OF_RECONFIG_UPDATE_PROPERTY' undeclared (first use in this function)
    1640 |         return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/regulator/pbias-regulator.c: At top level:
   drivers/regulator/pbias-regulator.c:136:34: warning: 'pbias_of_match' defined but not used [-Wunused-const-variable=]
     136 | static const struct of_device_id pbias_of_match[] = {
         |                                  ^~~~~~~~~~~~~~
--
   In file included from drivers/regulator/twl-regulator.c:14:
   include/linux/of.h: In function 'of_changeset_attach_node':
>> include/linux/of.h:1616:41: error: 'OF_RECONFIG_ATTACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1616 |         return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h:1616:41: note: each undeclared identifier is reported only once for each function it appears in
   include/linux/of.h: In function 'of_changeset_detach_node':
>> include/linux/of.h:1622:41: error: 'OF_RECONFIG_DETACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1622 |         return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h: In function 'of_changeset_add_property':
>> include/linux/of.h:1628:41: error: 'OF_RECONFIG_ADD_PROPERTY' undeclared (first use in this function)
    1628 |         return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_remove_property':
>> include/linux/of.h:1634:41: error: 'OF_RECONFIG_REMOVE_PROPERTY' undeclared (first use in this function)
    1634 |         return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_update_property':
>> include/linux/of.h:1640:41: error: 'OF_RECONFIG_UPDATE_PROPERTY' undeclared (first use in this function)
    1640 |         return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/regulator/twl-regulator.c: At top level:
   drivers/regulator/twl-regulator.c:552:34: warning: 'twl_of_match' defined but not used [-Wunused-const-variable=]
     552 | static const struct of_device_id twl_of_match[] = {
         |                                  ^~~~~~~~~~~~
--
   In file included from drivers/regulator/twl6030-regulator.c:15:
   include/linux/of.h: In function 'of_changeset_attach_node':
>> include/linux/of.h:1616:41: error: 'OF_RECONFIG_ATTACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1616 |         return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h:1616:41: note: each undeclared identifier is reported only once for each function it appears in
   include/linux/of.h: In function 'of_changeset_detach_node':
>> include/linux/of.h:1622:41: error: 'OF_RECONFIG_DETACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1622 |         return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h: In function 'of_changeset_add_property':
>> include/linux/of.h:1628:41: error: 'OF_RECONFIG_ADD_PROPERTY' undeclared (first use in this function)
    1628 |         return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_remove_property':
>> include/linux/of.h:1634:41: error: 'OF_RECONFIG_REMOVE_PROPERTY' undeclared (first use in this function)
    1634 |         return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_update_property':
>> include/linux/of.h:1640:41: error: 'OF_RECONFIG_UPDATE_PROPERTY' undeclared (first use in this function)
    1640 |         return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/regulator/twl6030-regulator.c: At top level:
   drivers/regulator/twl6030-regulator.c:645:34: warning: 'twl_of_match' defined but not used [-Wunused-const-variable=]
     645 | static const struct of_device_id twl_of_match[] = {
         |                                  ^~~~~~~~~~~~
--
   In file included from include/linux/irqdomain.h:14,
                    from include/linux/i2c.h:21,
                    from drivers/i2c/i2c-core-of-prober.c:14:
   include/linux/of.h: In function 'of_changeset_attach_node':
>> include/linux/of.h:1616:41: error: 'OF_RECONFIG_ATTACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1616 |         return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h:1616:41: note: each undeclared identifier is reported only once for each function it appears in
   include/linux/of.h: In function 'of_changeset_detach_node':
>> include/linux/of.h:1622:41: error: 'OF_RECONFIG_DETACH_NODE' undeclared (first use in this function); did you mean 'OF_RECONFIG_NO_CHANGE'?
    1622 |         return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~
         |                                         OF_RECONFIG_NO_CHANGE
   include/linux/of.h: In function 'of_changeset_add_property':
>> include/linux/of.h:1628:41: error: 'OF_RECONFIG_ADD_PROPERTY' undeclared (first use in this function)
    1628 |         return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_remove_property':
>> include/linux/of.h:1634:41: error: 'OF_RECONFIG_REMOVE_PROPERTY' undeclared (first use in this function)
    1634 |         return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h: In function 'of_changeset_update_property':
>> include/linux/of.h:1640:41: error: 'OF_RECONFIG_UPDATE_PROPERTY' undeclared (first use in this function)
    1640 |         return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
         |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/i2c/i2c-core-of-prober.c: In function 'i2c_of_probe_component':
>> include/linux/of.h:1478:14: error: implicit declaration of function 'of_get_next_child_with_prefix' [-Werror=implicit-function-declaration]
    1478 |              of_get_next_child_with_prefix(parent, NULL, prefix);       \
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/i2c/i2c-core-of-prober.c:146:9: note: in expansion of macro 'for_each_child_of_node_with_prefix'
     146 |         for_each_child_of_node_with_prefix(i2c_node, node, type)
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/of.h:1478:14: warning: initialization of 'struct device_node *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1478 |              of_get_next_child_with_prefix(parent, NULL, prefix);       \
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/i2c/i2c-core-of-prober.c:146:9: note: in expansion of macro 'for_each_child_of_node_with_prefix'
     146 |         for_each_child_of_node_with_prefix(i2c_node, node, type)
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/of.h:1477:9: error: declaration of non-variable 'of_get_next_child_with_prefix' in 'for' loop initial declaration
    1477 |         for (struct device_node *child __free(device_node) =            \
         |         ^~~
   drivers/i2c/i2c-core-of-prober.c:146:9: note: in expansion of macro 'for_each_child_of_node_with_prefix'
     146 |         for_each_child_of_node_with_prefix(i2c_node, node, type)
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/of.h:1480:20: warning: assignment to 'struct device_node *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1480 |              child = of_get_next_child_with_prefix(parent, child, prefix))
         |                    ^
   drivers/i2c/i2c-core-of-prober.c:146:9: note: in expansion of macro 'for_each_child_of_node_with_prefix'
     146 |         for_each_child_of_node_with_prefix(i2c_node, node, type)
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/of.h:1478:14: warning: initialization of 'struct device_node *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1478 |              of_get_next_child_with_prefix(parent, NULL, prefix);       \
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/i2c/i2c-core-of-prober.c:161:9: note: in expansion of macro 'for_each_child_of_node_with_prefix'
     161 |         for_each_child_of_node_with_prefix(i2c_node, node, type) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/of.h:1477:9: error: declaration of non-variable 'of_get_next_child_with_prefix' in 'for' loop initial declaration
    1477 |         for (struct device_node *child __free(device_node) =            \
         |         ^~~
   drivers/i2c/i2c-core-of-prober.c:161:9: note: in expansion of macro 'for_each_child_of_node_with_prefix'
     161 |         for_each_child_of_node_with_prefix(i2c_node, node, type) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/of.h:1480:20: warning: assignment to 'struct device_node *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1480 |              child = of_get_next_child_with_prefix(parent, child, prefix))
         |                    ^
   drivers/i2c/i2c-core-of-prober.c:161:9: note: in expansion of macro 'for_each_child_of_node_with_prefix'
     161 |         for_each_child_of_node_with_prefix(i2c_node, node, type) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for OF_DYNAMIC
   Depends on [n]: OF [=n]
   Selected by [y]:
   - FSL_FMAN [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_FREESCALE [=y] && (FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST [=y])


vim +1616 include/linux/of.h

e7a00e4210e4cc Sebastian Reichel         2014-04-06  1430  
f623ce95a51bae Joerg Roedel              2016-04-04  1431  #define of_for_each_phandle(it, err, np, ln, cn, cc)			\
f623ce95a51bae Joerg Roedel              2016-04-04  1432  	for (of_phandle_iterator_init((it), (np), (ln), (cn), (cc)),	\
f623ce95a51bae Joerg Roedel              2016-04-04  1433  	     err = of_phandle_iterator_next(it);			\
f623ce95a51bae Joerg Roedel              2016-04-04  1434  	     err == 0;							\
f623ce95a51bae Joerg Roedel              2016-04-04  1435  	     err = of_phandle_iterator_next(it))
f623ce95a51bae Joerg Roedel              2016-04-04  1436  
9722c3b66e21ff Luca Ceresoli             2024-07-24  1437  #define of_property_for_each_u32(np, propname, u)			\
9c63fea9acd077 Rob Herring (Arm          2024-10-10  1438) 	for (struct {const struct property *prop; const __be32 *item; } _it =	\
9722c3b66e21ff Luca Ceresoli             2024-07-24  1439  		{of_find_property(np, propname, NULL),			\
9722c3b66e21ff Luca Ceresoli             2024-07-24  1440  		 of_prop_next_u32(_it.prop, NULL, &u)};			\
9722c3b66e21ff Luca Ceresoli             2024-07-24  1441  	     _it.item;							\
9722c3b66e21ff Luca Ceresoli             2024-07-24  1442  	     _it.item = of_prop_next_u32(_it.prop, _it.item, &u))
2adfffa223500b Sebastian Andrzej Siewior 2013-06-17  1443  
2adfffa223500b Sebastian Andrzej Siewior 2013-06-17  1444  #define of_property_for_each_string(np, propname, prop, s)	\
2adfffa223500b Sebastian Andrzej Siewior 2013-06-17  1445  	for (prop = of_find_property(np, propname, NULL),	\
2adfffa223500b Sebastian Andrzej Siewior 2013-06-17  1446  		s = of_prop_next_string(prop, NULL);		\
2adfffa223500b Sebastian Andrzej Siewior 2013-06-17  1447  		s;						\
2adfffa223500b Sebastian Andrzej Siewior 2013-06-17  1448  		s = of_prop_next_string(prop, s))
2adfffa223500b Sebastian Andrzej Siewior 2013-06-17  1449  
662372e42e46d9 Rob Herring               2014-02-03  1450  #define for_each_node_by_name(dn, name) \
662372e42e46d9 Rob Herring               2014-02-03  1451  	for (dn = of_find_node_by_name(NULL, name); dn; \
662372e42e46d9 Rob Herring               2014-02-03  1452  	     dn = of_find_node_by_name(dn, name))
662372e42e46d9 Rob Herring               2014-02-03  1453  #define for_each_node_by_type(dn, type) \
662372e42e46d9 Rob Herring               2014-02-03  1454  	for (dn = of_find_node_by_type(NULL, type); dn; \
662372e42e46d9 Rob Herring               2014-02-03  1455  	     dn = of_find_node_by_type(dn, type))
662372e42e46d9 Rob Herring               2014-02-03  1456  #define for_each_compatible_node(dn, type, compatible) \
662372e42e46d9 Rob Herring               2014-02-03  1457  	for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
662372e42e46d9 Rob Herring               2014-02-03  1458  	     dn = of_find_compatible_node(dn, type, compatible))
662372e42e46d9 Rob Herring               2014-02-03  1459  #define for_each_matching_node(dn, matches) \
662372e42e46d9 Rob Herring               2014-02-03  1460  	for (dn = of_find_matching_node(NULL, matches); dn; \
662372e42e46d9 Rob Herring               2014-02-03  1461  	     dn = of_find_matching_node(dn, matches))
662372e42e46d9 Rob Herring               2014-02-03  1462  #define for_each_matching_node_and_match(dn, matches, match) \
662372e42e46d9 Rob Herring               2014-02-03  1463  	for (dn = of_find_matching_node_and_match(NULL, matches, match); \
662372e42e46d9 Rob Herring               2014-02-03  1464  	     dn; dn = of_find_matching_node_and_match(dn, matches, match))
662372e42e46d9 Rob Herring               2014-02-03  1465  
662372e42e46d9 Rob Herring               2014-02-03  1466  #define for_each_child_of_node(parent, child) \
662372e42e46d9 Rob Herring               2014-02-03  1467  	for (child = of_get_next_child(parent, NULL); child != NULL; \
662372e42e46d9 Rob Herring               2014-02-03  1468  	     child = of_get_next_child(parent, child))
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1469  
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1470  #define for_each_child_of_node_scoped(parent, child) \
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1471  	for (struct device_node *child __free(device_node) =		\
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1472  	     of_get_next_child(parent, NULL);				\
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1473  	     child != NULL;						\
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1474  	     child = of_get_next_child(parent, child))
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1475  
1fcc67e3a35486 Chen-Yu Tsai              2024-11-06  1476  #define for_each_child_of_node_with_prefix(parent, child, prefix)	\
1fcc67e3a35486 Chen-Yu Tsai              2024-11-06 @1477  	for (struct device_node *child __free(device_node) =		\
1fcc67e3a35486 Chen-Yu Tsai              2024-11-06 @1478  	     of_get_next_child_with_prefix(parent, NULL, prefix);	\
1fcc67e3a35486 Chen-Yu Tsai              2024-11-06  1479  	     child != NULL;						\
1fcc67e3a35486 Chen-Yu Tsai              2024-11-06 @1480  	     child = of_get_next_child_with_prefix(parent, child, prefix))
1fcc67e3a35486 Chen-Yu Tsai              2024-11-06  1481  
662372e42e46d9 Rob Herring               2014-02-03  1482  #define for_each_available_child_of_node(parent, child) \
662372e42e46d9 Rob Herring               2014-02-03  1483  	for (child = of_get_next_available_child(parent, NULL); child != NULL; \
662372e42e46d9 Rob Herring               2014-02-03  1484  	     child = of_get_next_available_child(parent, child))
28c5d4e40752fc Kuninori Morimoto         2024-01-10  1485  #define for_each_reserved_child_of_node(parent, child)			\
28c5d4e40752fc Kuninori Morimoto         2024-01-10  1486  	for (child = of_get_next_reserved_child(parent, NULL); child != NULL; \
28c5d4e40752fc Kuninori Morimoto         2024-01-10  1487  	     child = of_get_next_reserved_child(parent, child))
662372e42e46d9 Rob Herring               2014-02-03  1488  
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1489  #define for_each_available_child_of_node_scoped(parent, child) \
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1490  	for (struct device_node *child __free(device_node) =		\
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1491  	     of_get_next_available_child(parent, NULL);			\
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1492  	     child != NULL;						\
34af4554fb0ce1 Jonathan Cameron          2024-02-25  1493  	     child = of_get_next_available_child(parent, child))
662372e42e46d9 Rob Herring               2014-02-03  1494  
f1f207e43b8a49 Rob Herring               2018-08-22  1495  #define for_each_of_cpu_node(cpu) \
f1f207e43b8a49 Rob Herring               2018-08-22  1496  	for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \
f1f207e43b8a49 Rob Herring               2018-08-22  1497  	     cpu = of_get_next_cpu_node(cpu))
f1f207e43b8a49 Rob Herring               2018-08-22  1498  
662372e42e46d9 Rob Herring               2014-02-03  1499  #define for_each_node_with_property(dn, prop_name) \
662372e42e46d9 Rob Herring               2014-02-03  1500  	for (dn = of_find_node_with_property(NULL, prop_name); dn; \
662372e42e46d9 Rob Herring               2014-02-03  1501  	     dn = of_find_node_with_property(dn, prop_name))
662372e42e46d9 Rob Herring               2014-02-03  1502  
662372e42e46d9 Rob Herring               2014-02-03  1503  static inline int of_get_child_count(const struct device_node *np)
662372e42e46d9 Rob Herring               2014-02-03  1504  {
662372e42e46d9 Rob Herring               2014-02-03  1505  	struct device_node *child;
662372e42e46d9 Rob Herring               2014-02-03  1506  	int num = 0;
662372e42e46d9 Rob Herring               2014-02-03  1507  
662372e42e46d9 Rob Herring               2014-02-03  1508  	for_each_child_of_node(np, child)
662372e42e46d9 Rob Herring               2014-02-03  1509  		num++;
662372e42e46d9 Rob Herring               2014-02-03  1510  
662372e42e46d9 Rob Herring               2014-02-03  1511  	return num;
662372e42e46d9 Rob Herring               2014-02-03  1512  }
662372e42e46d9 Rob Herring               2014-02-03  1513  
662372e42e46d9 Rob Herring               2014-02-03  1514  static inline int of_get_available_child_count(const struct device_node *np)
662372e42e46d9 Rob Herring               2014-02-03  1515  {
662372e42e46d9 Rob Herring               2014-02-03  1516  	struct device_node *child;
662372e42e46d9 Rob Herring               2014-02-03  1517  	int num = 0;
662372e42e46d9 Rob Herring               2014-02-03  1518  
662372e42e46d9 Rob Herring               2014-02-03  1519  	for_each_available_child_of_node(np, child)
662372e42e46d9 Rob Herring               2014-02-03  1520  		num++;
662372e42e46d9 Rob Herring               2014-02-03  1521  
662372e42e46d9 Rob Herring               2014-02-03  1522  	return num;
662372e42e46d9 Rob Herring               2014-02-03  1523  }
662372e42e46d9 Rob Herring               2014-02-03  1524  
67a066b35765d1 Dmitry Osipenko           2021-06-10  1525  #define _OF_DECLARE_STUB(table, name, compat, fn, fn_type)		\
67a066b35765d1 Dmitry Osipenko           2021-06-10  1526  	static const struct of_device_id __of_table_##name		\
67a066b35765d1 Dmitry Osipenko           2021-06-10  1527  		__attribute__((unused))					\
67a066b35765d1 Dmitry Osipenko           2021-06-10  1528  		 = { .compatible = compat,				\
67a066b35765d1 Dmitry Osipenko           2021-06-10  1529  		     .data = (fn == (fn_type)NULL) ? fn : fn }
67a066b35765d1 Dmitry Osipenko           2021-06-10  1530  
71f50c6d9a2276 Masahiro Yamada           2016-01-22  1531  #if defined(CONFIG_OF) && !defined(MODULE)
54196ccbe0ba1f Rob Herring               2014-05-08  1532  #define _OF_DECLARE(table, name, compat, fn, fn_type)			\
54196ccbe0ba1f Rob Herring               2014-05-08  1533  	static const struct of_device_id __of_table_##name		\
33def8498fdde1 Joe Perches               2020-10-21  1534  		__used __section("__" #table "_of_table")		\
5812b32e01c6d8 Johan Hovold              2020-11-23  1535  		__aligned(__alignof__(struct of_device_id))		\
54196ccbe0ba1f Rob Herring               2014-05-08  1536  		 = { .compatible = compat,				\
54196ccbe0ba1f Rob Herring               2014-05-08  1537  		     .data = (fn == (fn_type)NULL) ? fn : fn  }
54196ccbe0ba1f Rob Herring               2014-05-08  1538  #else
54196ccbe0ba1f Rob Herring               2014-05-08  1539  #define _OF_DECLARE(table, name, compat, fn, fn_type)			\
67a066b35765d1 Dmitry Osipenko           2021-06-10  1540  	_OF_DECLARE_STUB(table, name, compat, fn, fn_type)
54196ccbe0ba1f Rob Herring               2014-05-08  1541  #endif
54196ccbe0ba1f Rob Herring               2014-05-08  1542  
54196ccbe0ba1f Rob Herring               2014-05-08  1543  typedef int (*of_init_fn_2)(struct device_node *, struct device_node *);
c35d9292fee047 Daniel Lezcano            2016-04-18  1544  typedef int (*of_init_fn_1_ret)(struct device_node *);
54196ccbe0ba1f Rob Herring               2014-05-08  1545  typedef void (*of_init_fn_1)(struct device_node *);
54196ccbe0ba1f Rob Herring               2014-05-08  1546  
54196ccbe0ba1f Rob Herring               2014-05-08  1547  #define OF_DECLARE_1(table, name, compat, fn) \
54196ccbe0ba1f Rob Herring               2014-05-08  1548  		_OF_DECLARE(table, name, compat, fn, of_init_fn_1)
c35d9292fee047 Daniel Lezcano            2016-04-18  1549  #define OF_DECLARE_1_RET(table, name, compat, fn) \
c35d9292fee047 Daniel Lezcano            2016-04-18  1550  		_OF_DECLARE(table, name, compat, fn, of_init_fn_1_ret)
54196ccbe0ba1f Rob Herring               2014-05-08  1551  #define OF_DECLARE_2(table, name, compat, fn) \
54196ccbe0ba1f Rob Herring               2014-05-08  1552  		_OF_DECLARE(table, name, compat, fn, of_init_fn_2)
54196ccbe0ba1f Rob Herring               2014-05-08  1553  
201c910bd6898d Pantelis Antoniou         2014-07-04  1554  /**
201c910bd6898d Pantelis Antoniou         2014-07-04  1555   * struct of_changeset_entry	- Holds a changeset entry
201c910bd6898d Pantelis Antoniou         2014-07-04  1556   *
201c910bd6898d Pantelis Antoniou         2014-07-04  1557   * @node:	list_head for the log list
201c910bd6898d Pantelis Antoniou         2014-07-04  1558   * @action:	notifier action
201c910bd6898d Pantelis Antoniou         2014-07-04  1559   * @np:		pointer to the device node affected
201c910bd6898d Pantelis Antoniou         2014-07-04  1560   * @prop:	pointer to the property affected
201c910bd6898d Pantelis Antoniou         2014-07-04  1561   * @old_prop:	hold a pointer to the original property
201c910bd6898d Pantelis Antoniou         2014-07-04  1562   *
201c910bd6898d Pantelis Antoniou         2014-07-04  1563   * Every modification of the device tree during a changeset
201c910bd6898d Pantelis Antoniou         2014-07-04  1564   * is held in a list of of_changeset_entry structures.
201c910bd6898d Pantelis Antoniou         2014-07-04  1565   * That way we can recover from a partial application, or we can
201c910bd6898d Pantelis Antoniou         2014-07-04  1566   * revert the changeset
201c910bd6898d Pantelis Antoniou         2014-07-04  1567   */
201c910bd6898d Pantelis Antoniou         2014-07-04  1568  struct of_changeset_entry {
201c910bd6898d Pantelis Antoniou         2014-07-04  1569  	struct list_head node;
201c910bd6898d Pantelis Antoniou         2014-07-04  1570  	unsigned long action;
201c910bd6898d Pantelis Antoniou         2014-07-04  1571  	struct device_node *np;
201c910bd6898d Pantelis Antoniou         2014-07-04  1572  	struct property *prop;
201c910bd6898d Pantelis Antoniou         2014-07-04  1573  	struct property *old_prop;
201c910bd6898d Pantelis Antoniou         2014-07-04  1574  };
201c910bd6898d Pantelis Antoniou         2014-07-04  1575  
201c910bd6898d Pantelis Antoniou         2014-07-04  1576  /**
201c910bd6898d Pantelis Antoniou         2014-07-04  1577   * struct of_changeset - changeset tracker structure
201c910bd6898d Pantelis Antoniou         2014-07-04  1578   *
201c910bd6898d Pantelis Antoniou         2014-07-04  1579   * @entries:	list_head for the changeset entries
201c910bd6898d Pantelis Antoniou         2014-07-04  1580   *
201c910bd6898d Pantelis Antoniou         2014-07-04  1581   * changesets are a convenient way to apply bulk changes to the
201c910bd6898d Pantelis Antoniou         2014-07-04  1582   * live tree. In case of an error, changes are rolled-back.
201c910bd6898d Pantelis Antoniou         2014-07-04  1583   * changesets live on after initial application, and if not
201c910bd6898d Pantelis Antoniou         2014-07-04  1584   * destroyed after use, they can be reverted in one single call.
201c910bd6898d Pantelis Antoniou         2014-07-04  1585   */
201c910bd6898d Pantelis Antoniou         2014-07-04  1586  struct of_changeset {
201c910bd6898d Pantelis Antoniou         2014-07-04  1587  	struct list_head entries;
201c910bd6898d Pantelis Antoniou         2014-07-04  1588  };
201c910bd6898d Pantelis Antoniou         2014-07-04  1589  
b53a2340d0d304 Pantelis Antoniou         2014-10-28  1590  enum of_reconfig_change {
b53a2340d0d304 Pantelis Antoniou         2014-10-28  1591  	OF_RECONFIG_NO_CHANGE = 0,
b53a2340d0d304 Pantelis Antoniou         2014-10-28  1592  	OF_RECONFIG_CHANGE_ADD,
b53a2340d0d304 Pantelis Antoniou         2014-10-28  1593  	OF_RECONFIG_CHANGE_REMOVE,
b53a2340d0d304 Pantelis Antoniou         2014-10-28  1594  };
b53a2340d0d304 Pantelis Antoniou         2014-10-28  1595  
2e8fff668dc14e Rob Herring               2023-03-29  1596  struct notifier_block;
2e8fff668dc14e Rob Herring               2023-03-29  1597  
201c910bd6898d Pantelis Antoniou         2014-07-04  1598  #ifdef CONFIG_OF_DYNAMIC
f6892d193fb9d6 Grant Likely              2014-11-21  1599  extern int of_reconfig_notifier_register(struct notifier_block *);
f6892d193fb9d6 Grant Likely              2014-11-21  1600  extern int of_reconfig_notifier_unregister(struct notifier_block *);
f5242e5a883bf1 Grant Likely              2014-11-24  1601  extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd);
f5242e5a883bf1 Grant Likely              2014-11-24  1602  extern int of_reconfig_get_state_change(unsigned long action,
f5242e5a883bf1 Grant Likely              2014-11-24  1603  					struct of_reconfig_data *arg);
f6892d193fb9d6 Grant Likely              2014-11-21  1604  
201c910bd6898d Pantelis Antoniou         2014-07-04  1605  extern void of_changeset_init(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou         2014-07-04  1606  extern void of_changeset_destroy(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou         2014-07-04  1607  extern int of_changeset_apply(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou         2014-07-04  1608  extern int of_changeset_revert(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou         2014-07-04  1609  extern int of_changeset_action(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou         2014-07-04  1610  		unsigned long action, struct device_node *np,
201c910bd6898d Pantelis Antoniou         2014-07-04  1611  		struct property *prop);
201c910bd6898d Pantelis Antoniou         2014-07-04  1612  
201c910bd6898d Pantelis Antoniou         2014-07-04  1613  static inline int of_changeset_attach_node(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou         2014-07-04  1614  		struct device_node *np)
201c910bd6898d Pantelis Antoniou         2014-07-04  1615  {
201c910bd6898d Pantelis Antoniou         2014-07-04 @1616  	return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
201c910bd6898d Pantelis Antoniou         2014-07-04  1617  }
201c910bd6898d Pantelis Antoniou         2014-07-04  1618  
201c910bd6898d Pantelis Antoniou         2014-07-04  1619  static inline int of_changeset_detach_node(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou         2014-07-04  1620  		struct device_node *np)
201c910bd6898d Pantelis Antoniou         2014-07-04  1621  {
201c910bd6898d Pantelis Antoniou         2014-07-04 @1622  	return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
201c910bd6898d Pantelis Antoniou         2014-07-04  1623  }
201c910bd6898d Pantelis Antoniou         2014-07-04  1624  
201c910bd6898d Pantelis Antoniou         2014-07-04  1625  static inline int of_changeset_add_property(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou         2014-07-04  1626  		struct device_node *np, struct property *prop)
201c910bd6898d Pantelis Antoniou         2014-07-04  1627  {
201c910bd6898d Pantelis Antoniou         2014-07-04 @1628  	return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
201c910bd6898d Pantelis Antoniou         2014-07-04  1629  }
201c910bd6898d Pantelis Antoniou         2014-07-04  1630  
201c910bd6898d Pantelis Antoniou         2014-07-04  1631  static inline int of_changeset_remove_property(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou         2014-07-04  1632  		struct device_node *np, struct property *prop)
201c910bd6898d Pantelis Antoniou         2014-07-04  1633  {
201c910bd6898d Pantelis Antoniou         2014-07-04 @1634  	return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
201c910bd6898d Pantelis Antoniou         2014-07-04  1635  }
201c910bd6898d Pantelis Antoniou         2014-07-04  1636  
201c910bd6898d Pantelis Antoniou         2014-07-04  1637  static inline int of_changeset_update_property(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou         2014-07-04  1638  		struct device_node *np, struct property *prop)
201c910bd6898d Pantelis Antoniou         2014-07-04  1639  {
201c910bd6898d Pantelis Antoniou         2014-07-04 @1640  	return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
201c910bd6898d Pantelis Antoniou         2014-07-04  1641  }
b544fc2b8606d7 Lizhi Hou                 2023-08-15  1642  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki