summaryrefslogtreecommitdiff
path: root/drivers/core/ofnode.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2022-09-06 20:27:02 -0600
committerTom Rini <trini@konsulko.com>2022-09-29 16:07:58 -0400
commitffe90392497898ccd8000e695901853e192a9007 (patch)
tree0331cda0c368be1cf676f0ea4e8c99e28125b8d0 /drivers/core/ofnode.c
parent5ecba3ba40cebd5e4340f6fd422683bde773689c (diff)
dm: core: Allow adding ofnode subnodes
Add this feature to the ofnode interface, supporting both livetree and flattree. If the node exists it is returned, along with a -EEXIST error. Update the functions it calls to handle this too. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/core/ofnode.c')
-rw-r--r--drivers/core/ofnode.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index b241be3b9fc..8683e03c330 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -1289,3 +1289,38 @@ phy_interface_t ofnode_read_phy_mode(ofnode node)
return PHY_INTERFACE_MODE_NA;
}
+
+int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep)
+{
+ ofnode subnode;
+ int ret = 0;
+
+ assert(ofnode_valid(node));
+
+ if (ofnode_is_np(node)) {
+ struct device_node *np, *child;
+
+ np = (struct device_node *)ofnode_to_np(node);
+ ret = of_add_subnode(np, name, -1, &child);
+ if (ret && ret != -EEXIST)
+ return ret;
+ subnode = np_to_ofnode(child);
+ } else {
+ void *fdt = (void *)gd->fdt_blob;
+ int poffset = ofnode_to_offset(node);
+ int offset;
+
+ offset = fdt_add_subnode(fdt, poffset, name);
+ if (offset == -FDT_ERR_EXISTS) {
+ offset = fdt_subnode_offset(fdt, poffset, name);
+ ret = -EEXIST;
+ }
+ if (offset < 0)
+ return -EINVAL;
+ subnode = offset_to_ofnode(offset);
+ }
+
+ *subnodep = subnode;
+
+ return ret; /* 0 or -EEXIST */
+}