From ec2917363c948b0a7b0a5a831c4b6902ce897c8f Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Wed, 7 Dec 2016 12:48:22 +0800 Subject: overlay: Add syntactic sugar version of overlays For simple overlays that use a single target there exists a simpler syntax version. &foo { }; generates an overlay with a single target at foo. Signed-off-by: Pantelis Antoniou Downloaded from https://marc.info/?l=devicetree&m=148111493325866&w=4 Change-Id: I7bf2ff20133ee37888e8dc6031b5539b0d6168e7 --- dtc-parser.y | 20 +++++++++++++++++--- dtc.h | 1 + livetree.c | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index ca3f500..affc81a 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -182,10 +182,19 @@ devicetree: { struct node *target = get_node_by_ref($1, $2); - if (target) + if (target) { merge_nodes(target, $3); - else - ERROR(&@2, "Label or path %s not found", $2); + } else { + /* + * We rely on the rule being always: + * versioninfo plugindecl memreserves devicetree + * so $-1 is what we want (plugindecl) + */ + if ($-1 & DTSF_PLUGIN) + add_orphan_node($1, $3, $2); + else + ERROR(&@2, "Label or path %s not found", $2); + } $$ = $1; } | devicetree DT_DEL_NODE DT_REF ';' @@ -200,6 +209,11 @@ devicetree: $$ = $1; } + | /* empty */ + { + /* build empty node */ + $$ = name_node(build_node(NULL, NULL), ""); + } ; nodedef: diff --git a/dtc.h b/dtc.h index c6f125c..092bef9 100644 --- a/dtc.h +++ b/dtc.h @@ -198,6 +198,7 @@ struct node *build_node_delete(void); struct node *name_node(struct node *node, char *name); struct node *chain_node(struct node *first, struct node *list); struct node *merge_nodes(struct node *old_node, struct node *new_node); +void add_orphan_node(struct node *old_node, struct node *new_node, char *ref); void add_property(struct node *node, struct property *prop); void delete_property_by_name(struct node *node, char *name); diff --git a/livetree.c b/livetree.c index 36be9af..bead747 100644 --- a/livetree.c +++ b/livetree.c @@ -216,6 +216,28 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) return old_node; } +void add_orphan_node(struct node *dt, struct node *new_node, char *ref) +{ + static unsigned int next_orphan_fragment = 0; + struct node *node; + struct property *p; + struct data d = empty_data; + char *name; + + d = data_add_marker(d, REF_PHANDLE, ref); + d = data_append_integer(d, 0xffffffff, 32); + + p = build_property("target", d); + + xasprintf(&name, "fragment@%u", + next_orphan_fragment++); + name_node(new_node, "__overlay__"); + node = build_node(p, new_node); + name_node(node, name); + + add_child(dt, node); +} + struct node *chain_node(struct node *first, struct node *list) { assert(first->next_sibling == NULL); -- cgit v1.2.3