aboutsummaryrefslogtreecommitdiff
path: root/core/device.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-08-17 14:49:53 +0800
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-08-17 17:04:14 +1000
commita1218c9589404211d01c633e6c41c95caf2002b0 (patch)
treeab4e3c7c5e44094b538ac709e3f3263477b97475 /core/device.c
parent9510db25586dee6868a8171607d93174e3d735c8 (diff)
downloadskiboot-a1218c9589404211d01c633e6c41c95caf2002b0.zip
skiboot-a1218c9589404211d01c633e6c41c95caf2002b0.tar.gz
skiboot-a1218c9589404211d01c633e6c41c95caf2002b0.tar.bz2
core: Add dt_copy
This change adds a new function to copy a device tree node to a new parent. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/device.c')
-rw-r--r--core/device.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/core/device.c b/core/device.c
index 807764c..483baec 100644
--- a/core/device.c
+++ b/core/device.c
@@ -152,6 +152,44 @@ struct dt_node *dt_new_2addr(struct dt_node *parent, const char *name,
return new;
}
+static struct dt_node *__dt_copy(struct dt_node *node, struct dt_node *parent,
+ bool root)
+{
+ struct dt_property *prop, *new_prop;
+ struct dt_node *new_node, *child;
+
+ new_node = dt_new(parent, node->name);
+ if (!new_node)
+ return NULL;
+
+ list_for_each(&node->properties, prop, list) {
+ new_prop = dt_add_property(new_node, prop->name, prop->prop,
+ prop->len);
+ if (!new_prop)
+ goto fail;
+ }
+
+ list_for_each(&node->children, child, list) {
+ child = __dt_copy(child, new_node, false);
+ if (!child)
+ goto fail;
+ }
+
+ return new_node;
+
+fail:
+ /* dt_free will recurse for us, so only free when we unwind to the
+ * top-level failure */
+ if (root)
+ dt_free(new_node);
+ return NULL;
+}
+
+struct dt_node *dt_copy(struct dt_node *node, struct dt_node *parent)
+{
+ return __dt_copy(node, parent, true);
+}
+
char *dt_get_path(const struct dt_node *node)
{
unsigned int len = 0;