diff options
author | Simon Glass | 2023-09-26 08:14:42 -0600 |
---|---|---|
committer | Tom Rini | 2023-10-06 14:38:13 -0400 |
commit | 67fb2159fb3438359fa0fc3f8cb491ffe8d57c0f (patch) | |
tree | 6a61f1cb1fe3ecc763fac9bdb6b1ac17e67490e6 /drivers | |
parent | c15862ffdd5f7797338808cf7645786109bcddc3 (diff) |
dm: core: Add a way to delete a node
Add a function to delete a node in an existing tree.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/core/of_access.c | 65 | ||||
-rw-r--r-- | drivers/core/ofnode.c | 23 |
2 files changed, 88 insertions, 0 deletions
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 1bb4d8eab70..c8db743f529 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -1040,3 +1040,68 @@ int of_add_subnode(struct device_node *parent, const char *name, int len, return 0; } + +int __of_remove_property(struct device_node *np, struct property *prop) +{ + struct property **next; + + for (next = &np->properties; *next; next = &(*next)->next) { + if (*next == prop) + break; + } + if (!*next) + return -ENODEV; + + /* found the node */ + *next = prop->next; + + return 0; +} + +int of_remove_property(struct device_node *np, struct property *prop) +{ + int rc; + + mutex_lock(&of_mutex); + + rc = __of_remove_property(np, prop); + + mutex_unlock(&of_mutex); + + return rc; +} + +int of_remove_node(struct device_node *to_remove) +{ + struct device_node *parent = to_remove->parent; + struct device_node *np, *prev; + + if (!parent) + return -EPERM; + prev = NULL; + __for_each_child_of_node(parent, np) { + if (np == to_remove) + break; + prev = np; + } + if (!np) + return -EFAULT; + + /* if there is a previous node, link it to this one's sibling */ + if (prev) + prev->sibling = np->sibling; + else + parent->child = np->sibling; + + /* + * don't free it, since if this is an unflattened tree, all the memory + * was alloced in one block; this pointer will be somewhere in the + * middle of that + * + * TODO(sjg@chromium.org): Consider marking nodes as 'allocated'? + * + * free(np); + */ + + return 0; +} diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 403ee06ad94..a5efedf6af3 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1779,6 +1779,29 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) return ret; /* 0 or -EEXIST */ } +int ofnode_delete(ofnode *nodep) +{ + ofnode node = *nodep; + int ret; + + assert(ofnode_valid(node)); + if (ofnode_is_np(node)) { + ret = of_remove_node(ofnode_to_np(node)); + } else { + void *fdt = ofnode_to_fdt(node); + int offset = ofnode_to_offset(node); + + ret = fdt_del_node(fdt, offset); + if (ret) + ret = -EFAULT; + } + if (ret) + return ret; + *nodep = ofnode_null(); + + return 0; +} + int ofnode_copy_props(ofnode dst, ofnode src) { struct ofprop prop; |