diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2015-08-17 14:49:53 +0800 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-08-17 17:04:14 +1000 |
commit | a1218c9589404211d01c633e6c41c95caf2002b0 (patch) | |
tree | ab4e3c7c5e44094b538ac709e3f3263477b97475 /core/device.c | |
parent | 9510db25586dee6868a8171607d93174e3d735c8 (diff) | |
download | skiboot-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.c | 38 |
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; |