summaryrefslogtreecommitdiff
path: root/drivers/of/dynamic.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-11-17 22:31:32 +0000
committerGrant Likely <grant.likely@linaro.org>2014-11-24 22:24:41 +0000
commite51795815ef1a7adc018cbaf05aac46e3d24eda8 (patch)
tree2cea4517a9df4e5dc4a699e25e93b2a8af2e4256 /drivers/of/dynamic.c
parentef8bbd73a76197cf8362a2b43aaadc5717bd0746 (diff)
of: Refactor __of_node_alloc() into __of_node_dup()
Add a node argument to __of_node_alloc() and rename it to __of_node_dup() so that it can also be used to duplicate a node with its properties. This is important for the overlay code so that it can create new nodes without using separate changeset items for every single property. At the same time rework the overlay code to use the new function and drop the extra changeset items. Signed-off-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers/of/dynamic.c')
-rw-r--r--drivers/of/dynamic.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index af1b1ecd6a3d..661ad2f5c00c 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -272,15 +272,16 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
}
/**
- * __of_node_alloc() - Create an empty device node dynamically.
- * @full_name: Full name of the new device node
+ * __of_node_dup() - Duplicate or create an empty device node dynamically.
+ * @fmt: Format string (plus vargs) for new full name of the device node
*
- * Create an empty device tree node, suitable for further modification.
- * The node data are dynamically allocated and all the node flags
- * have the OF_DYNAMIC & OF_DETACHED bits set.
- * Returns the newly allocated node or NULL on out of memory error.
+ * Create an device tree node, either by duplicating an empty node or by allocating
+ * an empty one suitable for further modification. The node data are
+ * dynamically allocated and all the node flags have the OF_DYNAMIC &
+ * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of
+ * memory error.
*/
-struct device_node *__of_node_alloc(const char *fmt, ...)
+struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...)
{
va_list vargs;
struct device_node *node;
@@ -291,17 +292,34 @@ struct device_node *__of_node_alloc(const char *fmt, ...)
va_start(vargs, fmt);
node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs);
va_end(vargs);
- if (!node->full_name)
- goto err_free;
+ if (!node->full_name) {
+ kfree(node);
+ return NULL;
+ }
of_node_set_flag(node, OF_DYNAMIC);
of_node_set_flag(node, OF_DETACHED);
of_node_init(node);
+ /* Iterate over and duplicate all properties */
+ if (np) {
+ struct property *pp, *new_pp;
+ for_each_property_of_node(np, pp) {
+ new_pp = __of_prop_dup(pp, GFP_KERNEL);
+ if (!new_pp)
+ goto err_prop;
+ if (__of_add_property(node, new_pp)) {
+ kfree(new_pp->name);
+ kfree(new_pp->value);
+ kfree(new_pp);
+ goto err_prop;
+ }
+ }
+ }
return node;
- err_free:
- kfree(node);
+ err_prop:
+ of_node_put(node); /* Frees the node and properties */
return NULL;
}