The code in sja1105_mdio.c does the same thing as the one added by Serge
Semin in drivers/net/pcs/pcs-xpcs-plat.c (implements a virtual MDIO bus,
backed by either a direct or an indirect register access method), except
the latter is generic after the conversion to regmap.
The SJA1105 binding now has a way of specifying sub-devices in the
switch's address space, using the 'regs' container node. However,
specifying the XPCS in the device tree is optional, yet it is a critical
component for the SGMII protocol (which is supported as of today). So we
must continue to instantiate the pcs-xpcs-plat.c driver somehow.
I've tried various ways of using that driver while avoiding major DT
bindings changes for this switch, like fwnode_create_software_node() and
custom platform data. Platform data was ugly and software nodes didn't
work at all, for reasons explained here:
https://lore.kernel.org/lkml/20230223203713.hcse3mkbq3m6sogb@skbuf/
I have to give huge credits to Andy Shevchenko, who after more than one
year remembered the discussion and referenced Hervé Codina's work on PCI
DT overlays, as well as a presentation from Lizhi Hou and Rob Herring.
I think I found the compromise solution that allows me to make progress,
which is to create a dynamic OF changeset that attaches the PCS node to
the live device tree, if it wasn't described already in the DTS, or use
the one from the DTS if it's already there. With a proper OF node, the
xpcs-plat driver probes just fine.
There also exists a use case where the XPCS is manually described
in the device tree, and that is when the board author needs to describe
SGMII lane polarity inversion via 'rx-polarity' or 'tx-polarity'. In
that case, sja1105_fill_device_tree() detects which PCS nodes are
present and fills in default descriptions only for the rest.
Nobody probes these ethernet-pcs devices just yet, because the custom
bus code is missing. SGMII continues to be supported through the
sja1105_mdiobus_pcs_register() and sja1105_mdiobus_pcs_unregister() code
path.
Cc: Serge Semin <fancer.lancer@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Herve Codina <herve.codina@bootlin.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2:
- use devres for sja1105_fill_device_tree()
- fill correct default tx-polarity in ethernet-pcs node rather than
expect XPCS driver to have SJA1105-specific correct default value
- drop cell_name from struct sja1105_pcs_resource after no longer making
use of MFD
- rewrite of_child_node_exists() using of_node_full_name()
- print phys_addr_t using unsigned long long and %llx
drivers/net/dsa/sja1105/Kconfig | 1 +
drivers/net/dsa/sja1105/sja1105.h | 11 ++
drivers/net/dsa/sja1105/sja1105_main.c | 7 +
drivers/net/dsa/sja1105/sja1105_spi.c | 37 ++++-
drivers/net/dsa/sja1105/sja1105_subdev.c | 190 +++++++++++++++++++++++
drivers/net/dsa/sja1105/sja1105_subdev.h | 1 +
6 files changed, 246 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/sja1105/Kconfig b/drivers/net/dsa/sja1105/Kconfig
index 1291bba3f3b6..55ce8f6a2758 100644
--- a/drivers/net/dsa/sja1105/Kconfig
+++ b/drivers/net/dsa/sja1105/Kconfig
@@ -7,6 +7,7 @@ tristate "NXP SJA1105 Ethernet switch family support"
select PCS_XPCS
select PACKING
select CRC32
+ select OF_DYNAMIC
help
This is the driver for the NXP SJA1105 (5-port) and SJA1110 (10-port)
automotive Ethernet switch family. These are managed over an SPI
diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h
index cf718e7c2b7b..1b52beba62d4 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -113,6 +113,13 @@ enum sja1105_internal_phy_t {
SJA1105_PHY_BASE_T1,
};
+struct sja1105_pcs_resource {
+ struct resource res;
+ int port;
+ u32 tx_polarity;
+ const char *compatible;
+};
+
struct sja1105_info {
u64 device_id;
/* Needed for distinction between P and R, and between Q and S
@@ -165,6 +172,8 @@ struct sja1105_info {
bool supports_2500basex[SJA1105_MAX_NUM_PORTS];
enum sja1105_internal_phy_t internal_phy[SJA1105_MAX_NUM_PORTS];
const u64 port_speed[SJA1105_SPEED_MAX];
+ const struct sja1105_pcs_resource *pcs_resources;
+ size_t num_pcs_resources;
};
enum sja1105_key_type {
@@ -278,6 +287,8 @@ struct sja1105_private {
struct sja1105_cbs_entry *cbs;
struct mii_bus *mdio_pcs;
struct phylink_pcs *pcs[SJA1105_MAX_NUM_PORTS];
+ struct fwnode_handle *pcs_fwnode[SJA1105_MAX_NUM_PORTS];
+ struct of_changeset of_cs;
struct sja1105_ptp_data ptp_data;
struct sja1105_tas_data tas_data;
};
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index d3fb42772071..84c0f7c676e2 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -3330,6 +3330,13 @@ static int sja1105_probe(struct spi_device *spi)
return rc;
}
+ rc = devm_sja1105_fill_device_tree(ds);
+ if (rc) {
+ dev_err(ds->dev, "Failed to fill device tree: %pe\n",
+ ERR_PTR(rc));
+ return rc;
+ }
+
rc = devm_sja1105_add_subdevs(ds);
if (rc) {
dev_err(ds->dev, "Failed to create child devices: %pe\n",
diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c
index 20757e166b08..4d4da69b3c30 100644
--- a/drivers/net/dsa/sja1105/sja1105_spi.c
+++ b/drivers/net/dsa/sja1105/sja1105_spi.c
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: BSD-3-Clause
-/* Copyright 2016-2018 NXP
+/* Copyright 2016-2018, 2026 NXP
* Copyright (c) 2018, Sensor-Technik Wiedemann GmbH
* Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
*/
+#include <linux/phy/phy-common-props.h>
#include <linux/spi/spi.h>
#include <linux/packing.h>
#include "sja1105.h"
@@ -619,6 +620,28 @@ static const struct sja1105_regs sja1110_regs = {
SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
};
+/* See port compatibility matrix in Documentation/networking/dsa/sja1105.rst */
+static const struct sja1105_pcs_resource sja1105rs_pcs_resources[] = {
+ { DEFINE_RES_REG_NAMED(0x0, 0x800000, "direct"), 4,
+ PHY_POL_INVERT, "nxp,sja1105-pcs"
+ },
+};
+
+static const struct sja1105_pcs_resource sja1110_pcs_resources[] = {
+ { DEFINE_RES_REG_NAMED(0x705000, 0x1000, "indirect"), 1,
+ PHY_POL_NORMAL, "nxp,sja1110-pcs"
+ },
+ { DEFINE_RES_REG_NAMED(0x706000, 0x1000, "indirect"), 2,
+ PHY_POL_NORMAL, "nxp,sja1110-pcs"
+ },
+ { DEFINE_RES_REG_NAMED(0x707000, 0x1000, "indirect"), 3,
+ PHY_POL_NORMAL, "nxp,sja1110-pcs"
+ },
+ { DEFINE_RES_REG_NAMED(0x708000, 0x1000, "indirect"), 4,
+ PHY_POL_NORMAL, "nxp,sja1110-pcs"
+ },
+};
+
const struct sja1105_info sja1105e_info = {
.device_id = SJA1105E_DEVICE_ID,
.part_no = SJA1105ET_PART_NO,
@@ -782,6 +805,8 @@ const struct sja1105_info sja1105r_info = {
.supports_rmii = {true, true, true, true, true},
.supports_rgmii = {true, true, true, true, true},
.supports_sgmii = {false, false, false, false, true},
+ .pcs_resources = sja1105rs_pcs_resources,
+ .num_pcs_resources = ARRAY_SIZE(sja1105rs_pcs_resources),
.name = "SJA1105R",
};
@@ -818,6 +843,8 @@ const struct sja1105_info sja1105s_info = {
.supports_rmii = {true, true, true, true, true},
.supports_rgmii = {true, true, true, true, true},
.supports_sgmii = {false, false, false, false, true},
+ .pcs_resources = sja1105rs_pcs_resources,
+ .num_pcs_resources = ARRAY_SIZE(sja1105rs_pcs_resources),
.name = "SJA1105S",
};
@@ -869,6 +896,8 @@ const struct sja1105_info sja1110a_info = {
SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
SJA1105_PHY_BASE_T1},
+ .pcs_resources = sja1110_pcs_resources,
+ .num_pcs_resources = ARRAY_SIZE(sja1110_pcs_resources),
.name = "SJA1110A",
};
@@ -920,6 +949,8 @@ const struct sja1105_info sja1110b_info = {
SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
SJA1105_NO_PHY},
+ .pcs_resources = &sja1110_pcs_resources[2], /* ports 3 and 4 */
+ .num_pcs_resources = ARRAY_SIZE(sja1110_pcs_resources) - 2,
.name = "SJA1110B",
};
@@ -971,6 +1002,8 @@ const struct sja1105_info sja1110c_info = {
SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
SJA1105_NO_PHY, SJA1105_NO_PHY,
SJA1105_NO_PHY},
+ .pcs_resources = &sja1110_pcs_resources[3], /* port 4 */
+ .num_pcs_resources = ARRAY_SIZE(sja1110_pcs_resources) - 3,
.name = "SJA1110C",
};
@@ -1022,5 +1055,7 @@ const struct sja1105_info sja1110d_info = {
SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1,
SJA1105_NO_PHY, SJA1105_NO_PHY,
SJA1105_NO_PHY},
+ .pcs_resources = sja1110_pcs_resources,
+ .num_pcs_resources = ARRAY_SIZE(sja1110_pcs_resources),
.name = "SJA1110D",
};
diff --git a/drivers/net/dsa/sja1105/sja1105_subdev.c b/drivers/net/dsa/sja1105/sja1105_subdev.c
index 06957d44f084..085d77947dc3 100644
--- a/drivers/net/dsa/sja1105/sja1105_subdev.c
+++ b/drivers/net/dsa/sja1105/sja1105_subdev.c
@@ -152,3 +152,193 @@ int devm_sja1105_add_subdevs(struct dsa_switch *ds)
return 0;
}
+
+static bool of_child_node_exists(struct device_node *np, const char *name)
+{
+ for_each_child_of_node_scoped(np, child)
+ if (!strcmp(of_node_full_name(child), name))
+ return true;
+
+ return false;
+}
+
+static int sja1105_create_pcs_nodes(struct sja1105_private *priv,
+ struct device_node *regs_node)
+{
+ struct dsa_switch *ds = priv->ds;
+ struct device *dev = ds->dev;
+ struct device_node *pcs_node;
+ char node_name[32];
+ u32 reg_props[2];
+ int rc;
+
+ for (int i = 0; i < priv->info->num_pcs_resources; i++) {
+ const struct sja1105_pcs_resource *pcs_res;
+
+ pcs_res = &priv->info->pcs_resources[i];
+
+ /* phys_addr_t has variable size depending on the value of
+ * CONFIG_PHYS_ADDR_T_64BIT, cast to the larger unsigned long
+ * long type for printf.
+ */
+ snprintf(node_name, sizeof(node_name), "ethernet-pcs@%llx",
+ (unsigned long long)pcs_res->res.start);
+
+ if (of_child_node_exists(regs_node, node_name))
+ continue;
+
+ pcs_node = of_changeset_create_node(&priv->of_cs, regs_node,
+ node_name);
+ if (!pcs_node) {
+ dev_err(dev, "Failed to create PCS node %s\n", node_name);
+ return -ENOMEM;
+ }
+
+ rc = of_changeset_add_prop_string(&priv->of_cs, pcs_node,
+ "compatible",
+ pcs_res->compatible);
+ if (rc) {
+ dev_err(dev, "Failed to add compatible property to %s: %pe\n",
+ node_name, ERR_PTR(rc));
+ return rc;
+ }
+
+ reg_props[0] = pcs_res->res.start;
+ reg_props[1] = resource_size(&pcs_res->res);
+ rc = of_changeset_add_prop_u32_array(&priv->of_cs, pcs_node,
+ "reg", reg_props, 2);
+ if (rc) {
+ dev_err(dev, "Failed to add reg property to %s: %pe\n",
+ node_name, ERR_PTR(rc));
+ return rc;
+ }
+
+ rc = of_changeset_add_prop_string(&priv->of_cs, pcs_node,
+ "reg-names",
+ pcs_res->res.name);
+ if (rc) {
+ dev_err(dev, "Failed to add reg-names property to %s: %pe\n",
+ node_name, ERR_PTR(rc));
+ return rc;
+ }
+
+ rc = of_changeset_add_prop_u32(&priv->of_cs, pcs_node,
+ "reg-io-width", 4);
+ if (rc) {
+ dev_err(dev, "Failed to add reg-io-width property to %s: %pe\n",
+ node_name, ERR_PTR(rc));
+ return rc;
+ }
+
+ /* The SJA1105 XPCS is integrated with a TX-inverting custom
+ * PMA. We need to invert the polarity in the PCS to obtain a
+ * non-inverted signal at the pins.
+ */
+ rc = of_changeset_add_prop_u32(&priv->of_cs, pcs_node, "tx-polarity",
+ pcs_res->tx_polarity);
+ if (rc) {
+ dev_err(dev, "Failed to add tx-polarity property to %s: %pe\n",
+ node_name, ERR_PTR(rc));
+ return rc;
+ }
+
+ dev_dbg(dev, "Created OF node %pOF\n", pcs_node);
+ priv->pcs_fwnode[pcs_res->port] = of_fwnode_handle(pcs_node);
+ }
+
+ return 0;
+}
+
+static struct device_node *sja1105_create_regs_node(struct sja1105_private *priv,
+ struct device_node *switch_node)
+{
+ struct device *dev = priv->ds->dev;
+ struct device_node *regs_node;
+ int rc;
+
+ regs_node = of_changeset_create_node(&priv->of_cs, switch_node, "regs");
+ if (!regs_node) {
+ dev_err(dev, "Failed to create 'regs' device tree node\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ rc = of_changeset_add_prop_u32(&priv->of_cs, regs_node, "#address-cells", 1);
+ if (rc) {
+ dev_err(dev, "Failed to add #address-cells property: %pe\n",
+ ERR_PTR(rc));
+ return ERR_PTR(rc);
+ }
+
+ rc = of_changeset_add_prop_u32(&priv->of_cs, regs_node, "#size-cells", 1);
+ if (rc) {
+ dev_err(dev, "Failed to add #size-cells property: %pe\n",
+ ERR_PTR(rc));
+ return ERR_PTR(rc);
+ }
+
+ return regs_node;
+}
+
+static void sja1105_restore_device_tree(void *data)
+{
+ struct sja1105_private *priv = data;
+ struct device *dev = priv->ds->dev;
+ int rc;
+
+ rc = of_changeset_revert(&priv->of_cs);
+ if (rc) {
+ dev_err(dev, "Failed to revert device tree changeset: %pe\n",
+ ERR_PTR(rc));
+ }
+
+ of_changeset_destroy(&priv->of_cs);
+}
+
+int devm_sja1105_fill_device_tree(struct dsa_switch *ds)
+{
+ struct device_node *switch_node, *regs_node;
+ struct sja1105_private *priv = ds->priv;
+ bool regs_node_created = false;
+ struct device *dev = ds->dev;
+ int rc;
+
+ if (!priv->info->num_pcs_resources)
+ return 0;
+
+ switch_node = dev_of_node(dev);
+ of_changeset_init(&priv->of_cs);
+
+ regs_node = of_get_child_by_name(switch_node, "regs");
+ if (!regs_node) {
+ regs_node = sja1105_create_regs_node(priv, switch_node);
+ if (IS_ERR(regs_node)) {
+ rc = PTR_ERR(regs_node);
+ goto out_destroy_changeset;
+ }
+
+ regs_node_created = true;
+ dev_dbg(dev, "Created OF node %pOF\n", regs_node);
+ }
+
+ rc = sja1105_create_pcs_nodes(priv, regs_node);
+ if (rc)
+ goto out_destroy_changeset;
+
+ rc = of_changeset_apply(&priv->of_cs);
+ if (rc) {
+ dev_err(dev, "Failed to apply device tree changeset: %pe\n",
+ ERR_PTR(rc));
+ goto out_destroy_changeset;
+ }
+
+ rc = devm_add_action_or_reset(dev, sja1105_restore_device_tree, priv);
+ goto out_put_regs_node;
+
+out_destroy_changeset:
+ of_changeset_destroy(&priv->of_cs);
+out_put_regs_node:
+ if (!regs_node_created)
+ of_node_put(regs_node);
+
+ return rc;
+}
diff --git a/drivers/net/dsa/sja1105/sja1105_subdev.h b/drivers/net/dsa/sja1105/sja1105_subdev.h
index 9b5a02401399..1507ff3c44d1 100644
--- a/drivers/net/dsa/sja1105/sja1105_subdev.h
+++ b/drivers/net/dsa/sja1105/sja1105_subdev.h
@@ -5,5 +5,6 @@
#define _SJA1105_SUBDEV_H
int devm_sja1105_add_subdevs(struct dsa_switch *ds);
+int devm_sja1105_fill_device_tree(struct dsa_switch *ds);
#endif
--
2.34.1
Hi Vladimir,
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/Vladimir-Oltean/net-mdio-regmap-permit-working-with-non-MMIO-regmaps/20260122-192934
base: net-next/main
patch link: https://lore.kernel.org/r/20260122105654.105600-12-vladimir.oltean%40nxp.com
patch subject: [PATCH v2 net-next 11/15] net: dsa: sja1105: fill device tree with ethernet-pcs sub-devices under "regs" node
config: mips-randconfig-r112-20260123 (https://download.01.org/0day-ci/archive/20260124/202601240325.L4Ejl6qH-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260124/202601240325.L4Ejl6qH-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/202601240325.L4Ejl6qH-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from arch/mips/kernel/asm-offsets.c:26:
In file included from include/linux/kvm_host.h:5:
In file included from include/linux/entry-virt.h:10:
In file included from include/linux/tick.h:8:
In file included from include/linux/clockchips.h:14:
In file included from include/linux/clocksource.h:19:
>> include/linux/of.h:1645:34: error: use of undeclared identifier 'OF_RECONFIG_ATTACH_NODE'; did you mean 'OF_RECONFIG_NO_CHANGE'?
1645 | return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
| ^~~~~~~~~~~~~~~~~~~~~~~
| OF_RECONFIG_NO_CHANGE
include/linux/of.h:1620:2: note: 'OF_RECONFIG_NO_CHANGE' declared here
1620 | OF_RECONFIG_NO_CHANGE = 0,
| ^
>> include/linux/of.h:1651:34: error: use of undeclared identifier 'OF_RECONFIG_DETACH_NODE'; did you mean 'OF_RECONFIG_NO_CHANGE'?
1651 | return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
| ^~~~~~~~~~~~~~~~~~~~~~~
| OF_RECONFIG_NO_CHANGE
include/linux/of.h:1620:2: note: 'OF_RECONFIG_NO_CHANGE' declared here
1620 | OF_RECONFIG_NO_CHANGE = 0,
| ^
>> include/linux/of.h:1657:34: error: use of undeclared identifier 'OF_RECONFIG_ADD_PROPERTY'
1657 | return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
| ^
>> include/linux/of.h:1663:34: error: use of undeclared identifier 'OF_RECONFIG_REMOVE_PROPERTY'
1663 | return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
| ^
>> include/linux/of.h:1669:34: error: use of undeclared identifier 'OF_RECONFIG_UPDATE_PROPERTY'
1669 | return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
| ^
5 errors generated.
make[3]: *** [scripts/Makefile.build:182: arch/mips/kernel/asm-offsets.s] Error 1
make[3]: Target 'prepare' not remade because of errors.
make[2]: *** [Makefile:1314: prepare0] Error 2
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:248: __sub-make] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:248: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for OF_DYNAMIC
Depends on [n]: OF [=n]
Selected by [m]:
- NET_DSA_SJA1105 [=m] && NETDEVICES [=y] && NET_DSA [=m] && SPI [=y] && PTP_1588_CLOCK_OPTIONAL [=y]
vim +1645 include/linux/of.h
201c910bd6898d Pantelis Antoniou 2014-07-04 1618
b53a2340d0d304 Pantelis Antoniou 2014-10-28 1619 enum of_reconfig_change {
b53a2340d0d304 Pantelis Antoniou 2014-10-28 @1620 OF_RECONFIG_NO_CHANGE = 0,
b53a2340d0d304 Pantelis Antoniou 2014-10-28 1621 OF_RECONFIG_CHANGE_ADD,
b53a2340d0d304 Pantelis Antoniou 2014-10-28 1622 OF_RECONFIG_CHANGE_REMOVE,
b53a2340d0d304 Pantelis Antoniou 2014-10-28 1623 };
b53a2340d0d304 Pantelis Antoniou 2014-10-28 1624
2e8fff668dc14e Rob Herring 2023-03-29 1625 struct notifier_block;
2e8fff668dc14e Rob Herring 2023-03-29 1626
201c910bd6898d Pantelis Antoniou 2014-07-04 1627 #ifdef CONFIG_OF_DYNAMIC
f6892d193fb9d6 Grant Likely 2014-11-21 1628 extern int of_reconfig_notifier_register(struct notifier_block *);
f6892d193fb9d6 Grant Likely 2014-11-21 1629 extern int of_reconfig_notifier_unregister(struct notifier_block *);
f5242e5a883bf1 Grant Likely 2014-11-24 1630 extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd);
f5242e5a883bf1 Grant Likely 2014-11-24 1631 extern int of_reconfig_get_state_change(unsigned long action,
f5242e5a883bf1 Grant Likely 2014-11-24 1632 struct of_reconfig_data *arg);
f6892d193fb9d6 Grant Likely 2014-11-21 1633
201c910bd6898d Pantelis Antoniou 2014-07-04 1634 extern void of_changeset_init(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou 2014-07-04 1635 extern void of_changeset_destroy(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou 2014-07-04 1636 extern int of_changeset_apply(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou 2014-07-04 1637 extern int of_changeset_revert(struct of_changeset *ocs);
201c910bd6898d Pantelis Antoniou 2014-07-04 1638 extern int of_changeset_action(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou 2014-07-04 1639 unsigned long action, struct device_node *np,
201c910bd6898d Pantelis Antoniou 2014-07-04 1640 struct property *prop);
201c910bd6898d Pantelis Antoniou 2014-07-04 1641
201c910bd6898d Pantelis Antoniou 2014-07-04 1642 static inline int of_changeset_attach_node(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou 2014-07-04 1643 struct device_node *np)
201c910bd6898d Pantelis Antoniou 2014-07-04 1644 {
201c910bd6898d Pantelis Antoniou 2014-07-04 @1645 return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL);
201c910bd6898d Pantelis Antoniou 2014-07-04 1646 }
201c910bd6898d Pantelis Antoniou 2014-07-04 1647
201c910bd6898d Pantelis Antoniou 2014-07-04 1648 static inline int of_changeset_detach_node(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou 2014-07-04 1649 struct device_node *np)
201c910bd6898d Pantelis Antoniou 2014-07-04 1650 {
201c910bd6898d Pantelis Antoniou 2014-07-04 @1651 return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL);
201c910bd6898d Pantelis Antoniou 2014-07-04 1652 }
201c910bd6898d Pantelis Antoniou 2014-07-04 1653
201c910bd6898d Pantelis Antoniou 2014-07-04 1654 static inline int of_changeset_add_property(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou 2014-07-04 1655 struct device_node *np, struct property *prop)
201c910bd6898d Pantelis Antoniou 2014-07-04 1656 {
201c910bd6898d Pantelis Antoniou 2014-07-04 @1657 return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop);
201c910bd6898d Pantelis Antoniou 2014-07-04 1658 }
201c910bd6898d Pantelis Antoniou 2014-07-04 1659
201c910bd6898d Pantelis Antoniou 2014-07-04 1660 static inline int of_changeset_remove_property(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou 2014-07-04 1661 struct device_node *np, struct property *prop)
201c910bd6898d Pantelis Antoniou 2014-07-04 1662 {
201c910bd6898d Pantelis Antoniou 2014-07-04 @1663 return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop);
201c910bd6898d Pantelis Antoniou 2014-07-04 1664 }
201c910bd6898d Pantelis Antoniou 2014-07-04 1665
201c910bd6898d Pantelis Antoniou 2014-07-04 1666 static inline int of_changeset_update_property(struct of_changeset *ocs,
201c910bd6898d Pantelis Antoniou 2014-07-04 1667 struct device_node *np, struct property *prop)
201c910bd6898d Pantelis Antoniou 2014-07-04 1668 {
201c910bd6898d Pantelis Antoniou 2014-07-04 @1669 return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop);
201c910bd6898d Pantelis Antoniou 2014-07-04 1670 }
b544fc2b8606d7 Lizhi Hou 2023-08-15 1671
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.