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
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
© 2016 - 2025 Red Hat, Inc.