* [PATCH] Implements new features for updating existing device tree nodes.
@ 2010-10-16 1:07 John Bonesio
2010-10-16 2:35 ` Grant Likely
2010-10-18 0:27 ` David Gibson
0 siblings, 2 replies; 19+ messages in thread
From: John Bonesio @ 2010-10-16 1:07 UTC (permalink / raw)
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
This is interesting when the /include/ "<filename>" feature is used. This way
we can create base device tree source files for a family of systems and modify
the device tree for a specific system.
The current sytem allows an existing node to be extended with new properties
and subnodes.
The new features allow an existing node to be replaced completely by the new
properties and subnodes. The new features also allow an existing node to be
deleted.
This patch does not yet provide a way to remove properties.
- John
---
dtc-lexer.l | 12 ++++++++++
dtc-parser.y | 24 ++++++++++++++++++++
dtc.h | 2 ++
livetree.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 107 insertions(+), 0 deletions(-)
diff --git a/dtc-lexer.l b/dtc-lexer.l
index 081e13a..a24edf5 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -96,6 +96,18 @@ static int pop_input_file(void);
return DT_MEMRESERVE;
}
+<*>"/trim-node/" {
+ DPRINT("Keyword: /trim-node/\n");
+ BEGIN_DEFAULT();
+ return DT_REPLACENODE;
+ }
+
+<*>"/remove-node/" {
+ DPRINT("Keyword: /remove-node/\n");
+ BEGIN_DEFAULT();
+ return DT_REMOVENODE;
+ }
+
<*>{LABEL}: {
DPRINT("Label: %s\n", yytext);
yylval.labelref = xstrdup(yytext);
diff --git a/dtc-parser.y b/dtc-parser.y
index aa250f1..a9cde72 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -54,6 +54,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
%token DT_V1
%token DT_MEMRESERVE
+%token DT_REPLACENODE
+%token DT_REMOVENODE
%token <propnodename> DT_PROPNODENAME
%token <literal> DT_LITERAL
%token <cbase> DT_BASE
@@ -140,6 +142,28 @@ devicetree:
" node extension", $2);
$$ = $1;
}
+ | devicetree DT_REPLACENODE DT_REF nodedef
+ {
+ struct node *target;
+
+ target = get_node_by_label($1, $3);
+ if (target)
+ replace_nodes(target, $4);
+ else
+ yyerror("label, '%s' does not exist in"
+ " node redefinition", $3);
+ $$ = $1;
+ }
+ | devicetree DT_REMOVENODE DT_REF ';'
+ {
+ struct node *target;
+
+ target = get_node_by_label($1, $3);
+ if (target)
+ remove_nodes(target);
+ else
+ yyerror("label, '%s' does not exist in"
+ " node removal", $3);
;
nodedef:
diff --git a/dtc.h b/dtc.h
index b36ac5d..1340568 100644
--- a/dtc.h
+++ b/dtc.h
@@ -175,6 +175,8 @@ struct node *build_node(struct property *proplist, struct node *children);
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);
+struct node *replace_nodes(struct node *old_node, struct node *new_node);
+struct node *remove_nodes(struct node *node);
void add_property(struct node *node, struct property *prop);
void add_child(struct node *parent, struct node *child);
diff --git a/livetree.c b/livetree.c
index 13c5f10..5e32510 100644
--- a/livetree.c
+++ b/livetree.c
@@ -167,6 +167,75 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
return old_node;
}
+struct node *remove_nodes(struct node *node) {
+ struct property *prop;
+ struct node *child, *parent;
+
+ while (node->proplist) {
+ /* Pop the property off the list */
+ prop = node->proplist;
+ node->proplist = prop->next;
+ prop->next = NULL;
+
+ free(prop);
+ }
+
+ /* Free up the node's children */
+ /* This assumes we have a tree and not a cylic or acylic graph */
+ while (node->children) {
+ /* Pop the child node off the list */
+ child = node->children;
+ node->children = child->next_sibling;
+ child->parent = NULL;
+ child->next_sibling = NULL;
+
+ child = remove_nodes(child);
+ }
+
+ /* Remove the node from it's parent's child list */
+ if (node->parent) {
+ int found = 0;
+
+ parent = node->parent;
+
+ /* if the node is the first child ... */
+ if (parent->children == node) {
+ parent->children = node->next_sibling;
+ found = 1;
+ } else {
+ for_each_child(parent, child) {
+ if (child->next_sibling == node) {
+ child->next_sibling = node->next_sibling;
+ found = 1;
+ break;
+ }
+ }
+ }
+ assert(found); /* Woah! We've got an inconsistent tree here */
+ node->parent = NULL;
+ node->next_sibling = NULL;
+ }
+
+ free(node);
+
+ return NULL;
+}
+
+struct node *replace_nodes(struct node *old_node, struct node *new_node)
+{
+ struct label *l;
+
+ /* Add old node labels to new node, so we can still refer to the
+ * new node by the old labels. */
+ for_each_label(old_node->labels, l)
+ add_label(&new_node->labels, l->label);
+
+ /* Free up the old_node */
+ remove_nodes(old_node);
+
+ return new_node;
+}
+
struct node *chain_node(struct node *first, struct node *list)
{
assert(first->next_sibling == NULL);
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-16 1:07 [PATCH] Implements new features for updating existing device tree nodes John Bonesio
@ 2010-10-16 2:35 ` Grant Likely
[not found] ` <AANLkTimx4z-YkH+PXcnKYJpq3MEd3oJZ+ow7mWJzn1BN-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-18 0:27 ` David Gibson
1 sibling, 1 reply; 19+ messages in thread
From: Grant Likely @ 2010-10-16 2:35 UTC (permalink / raw)
To: John Bonesio; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Hi John.
On Fri, Oct 15, 2010 at 7:07 PM, John Bonesio <bones-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> This is interesting when the /include/ "<filename>" feature is used. This way
> we can create base device tree source files for a family of systems and modify
> the device tree for a specific system.
>
> The current sytem allows an existing node to be extended with new properties
> and subnodes.
>
> The new features allow an existing node to be replaced completely by the new
> properties and subnodes. The new features also allow an existing node to be
> deleted.
>
> This patch does not yet provide a way to remove properties.
>
> - John
Also need s-o-b line, and anything that doesn't belong as part of the
commit message, such as '- John', needs to be below the '---' line so
that git will ignore it.
The patch looks pretty good, but I cannot comment fully until the
keyword handling works when deeper in the tree (see below).
> ---
>
> dtc-lexer.l | 12 ++++++++++
> dtc-parser.y | 24 ++++++++++++++++++++
> dtc.h | 2 ++
> livetree.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 107 insertions(+), 0 deletions(-)
>
> diff --git a/dtc-lexer.l b/dtc-lexer.l
> index 081e13a..a24edf5 100644
> --- a/dtc-lexer.l
> +++ b/dtc-lexer.l
> @@ -96,6 +96,18 @@ static int pop_input_file(void);
> return DT_MEMRESERVE;
> }
>
> +<*>"/trim-node/" {
> + DPRINT("Keyword: /trim-node/\n");
> + BEGIN_DEFAULT();
> + return DT_REPLACENODE;
> + }
> +
> +<*>"/remove-node/" {
> + DPRINT("Keyword: /remove-node/\n");
> + BEGIN_DEFAULT();
> + return DT_REMOVENODE;
> + }
> +
> <*>{LABEL}: {
> DPRINT("Label: %s\n", yytext);
> yylval.labelref = xstrdup(yytext);
> diff --git a/dtc-parser.y b/dtc-parser.y
> index aa250f1..a9cde72 100644
> --- a/dtc-parser.y
> +++ b/dtc-parser.y
> @@ -54,6 +54,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
>
> %token DT_V1
> %token DT_MEMRESERVE
> +%token DT_REPLACENODE
> +%token DT_REMOVENODE
> %token <propnodename> DT_PROPNODENAME
> %token <literal> DT_LITERAL
> %token <cbase> DT_BASE
> @@ -140,6 +142,28 @@ devicetree:
> " node extension", $2);
> $$ = $1;
> }
> + | devicetree DT_REPLACENODE DT_REF nodedef
> + {
> + struct node *target;
> +
> + target = get_node_by_label($1, $3);
> + if (target)
> + replace_nodes(target, $4);
> + else
> + yyerror("label, '%s' does not exist in"
> + " node redefinition", $3);
> + $$ = $1;
> + }
> + | devicetree DT_REMOVENODE DT_REF ';'
> + {
> + struct node *target;
> +
> + target = get_node_by_label($1, $3);
> + if (target)
> + remove_nodes(target);
> + else
> + yyerror("label, '%s' does not exist in"
> + " node removal", $3);
> ;
This handles the syntax at the top level, but doesn't deal with the
/*-node/ keywords when they are within the overlay tree.
Also, I don't know if you'll be able to handle it in the same way when
it comes to handling the new tokens embedded within an overlay tree
because it isn't so easy to resolve the node to be removed. In order
to handle both cases in the same way, it might be better to set a
'replace' flag in struct node that defers the actual remove of the
original node until merge_nodes() time.
>
> nodedef:
> diff --git a/dtc.h b/dtc.h
> index b36ac5d..1340568 100644
> --- a/dtc.h
> +++ b/dtc.h
> @@ -175,6 +175,8 @@ struct node *build_node(struct property *proplist, struct node *children);
> 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);
> +struct node *replace_nodes(struct node *old_node, struct node *new_node);
> +struct node *remove_nodes(struct node *node);
>
> void add_property(struct node *node, struct property *prop);
> void add_child(struct node *parent, struct node *child);
> diff --git a/livetree.c b/livetree.c
> index 13c5f10..5e32510 100644
> --- a/livetree.c
> +++ b/livetree.c
> @@ -167,6 +167,75 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
> return old_node;
> }
>
> +struct node *remove_nodes(struct node *node) {
Can be void. The return value of remove_nodes() is never used.
> + struct property *prop;
> + struct node *child, *parent;
> +
> + while (node->proplist) {
> + /* Pop the property off the list */
> + prop = node->proplist;
> + node->proplist = prop->next;
> + prop->next = NULL;
> +
> + free(prop);
> + }
It would be useful to have a 'pop_property()' macro so this could be
simplified to:
while (prop = pop_child_node(&node->proplist))
free(prop);
But then on the other hand, most of the list management is open coded
in dtc. It would be nice to use the list_head macros like used in the
kernel, but that is probably work for another day. (if it is even worth
the effort).
http://ccan.ozlabs.org/info/list.html
> +
> + /* Free up the node's children */
> + /* This assumes we have a tree and not a cylic or acylic graph */
> + while (node->children) {
> + /* Pop the child node off the list */
> + child = node->children;
> + node->children = child->next_sibling;
> + child->parent = NULL;
> + child->next_sibling = NULL;
> +
> + child = remove_nodes(child);
> + }
Ditto here, except as pop_child_node().
> +
> + /* Remove the node from it's parent's child list */
> + if (node->parent) {
> + int found = 0;
> +
> + parent = node->parent;
> +
> + /* if the node is the first child ... */
> + if (parent->children == node) {
> + parent->children = node->next_sibling;
> + found = 1;
> + } else {
> + for_each_child(parent, child) {
> + if (child->next_sibling == node) {
> + child->next_sibling = node->next_sibling;
> + found = 1;
> + break;
> + }
> + }
> + }
> + assert(found); /* Woah! We've got an inconsistent tree here */
> + node->parent = NULL;
> + node->next_sibling = NULL;
> + }
This hunk is redundantly located because recursive calls have already
removed the node from the parent. Should split into a separate
function called by dtc-parse.y so that the recursive bit is simpler.
> +
> + free(node);
> +
> + return NULL;
> +}
This block looks correct to me. It seemed a little verbose, but when
I went through it line by line I saw that it pretty much needs to be
that way. Especially with the list operations being open coded.
> +
> +struct node *replace_nodes(struct node *old_node, struct node *new_node)
> +{
> + struct label *l;
> +
> + /* Add old node labels to new node, so we can still refer to the
> + * new node by the old labels. */
> + for_each_label(old_node->labels, l)
> + add_label(&new_node->labels, l->label);
> +
> + /* Free up the old_node */
> + remove_nodes(old_node);
> +
> + return new_node;
> +}
> +
> struct node *chain_node(struct node *first, struct node *list)
> {
> assert(first->next_sibling == NULL);
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <AANLkTimx4z-YkH+PXcnKYJpq3MEd3oJZ+ow7mWJzn1BN-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2010-10-16 3:21 ` John Bonesio
2010-10-16 6:47 ` David Gibson
2010-10-18 0:51 ` David Gibson
1 sibling, 1 reply; 19+ messages in thread
From: John Bonesio @ 2010-10-16 3:21 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Fri, 2010-10-15 at 20:35 -0600, Grant Likely wrote:
> Hi John.
>
> On Fri, Oct 15, 2010 at 7:07 PM, John Bonesio <bones-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> > This is interesting when the /include/ "<filename>" feature is used. This way
> > we can create base device tree source files for a family of systems and modify
> > the device tree for a specific system.
> >
> > The current sytem allows an existing node to be extended with new properties
> > and subnodes.
> >
> > The new features allow an existing node to be replaced completely by the new
> > properties and subnodes. The new features also allow an existing node to be
> > deleted.
> >
> > This patch does not yet provide a way to remove properties.
> >
> > - John
>
> Also need s-o-b line, and anything that doesn't belong as part of the
> commit message, such as '- John', needs to be below the '---' line so
> that git will ignore it.
>
> The patch looks pretty good, but I cannot comment fully until the
> keyword handling works when deeper in the tree (see below).
>
> > ---
> >
> > dtc-lexer.l | 12 ++++++++++
> > dtc-parser.y | 24 ++++++++++++++++++++
> > dtc.h | 2 ++
> > livetree.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 4 files changed, 107 insertions(+), 0 deletions(-)
> >
> > diff --git a/dtc-lexer.l b/dtc-lexer.l
> > index 081e13a..a24edf5 100644
> > --- a/dtc-lexer.l
> > +++ b/dtc-lexer.l
> > @@ -96,6 +96,18 @@ static int pop_input_file(void);
> > return DT_MEMRESERVE;
> > }
> >
> > +<*>"/trim-node/" {
> > + DPRINT("Keyword: /trim-node/\n");
> > + BEGIN_DEFAULT();
> > + return DT_REPLACENODE;
> > + }
> > +
> > +<*>"/remove-node/" {
> > + DPRINT("Keyword: /remove-node/\n");
> > + BEGIN_DEFAULT();
> > + return DT_REMOVENODE;
> > + }
> > +
> > <*>{LABEL}: {
> > DPRINT("Label: %s\n", yytext);
> > yylval.labelref = xstrdup(yytext);
> > diff --git a/dtc-parser.y b/dtc-parser.y
> > index aa250f1..a9cde72 100644
> > --- a/dtc-parser.y
> > +++ b/dtc-parser.y
> > @@ -54,6 +54,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
> >
> > %token DT_V1
> > %token DT_MEMRESERVE
> > +%token DT_REPLACENODE
> > +%token DT_REMOVENODE
> > %token <propnodename> DT_PROPNODENAME
> > %token <literal> DT_LITERAL
> > %token <cbase> DT_BASE
> > @@ -140,6 +142,28 @@ devicetree:
> > " node extension", $2);
> > $$ = $1;
> > }
> > + | devicetree DT_REPLACENODE DT_REF nodedef
> > + {
> > + struct node *target;
> > +
> > + target = get_node_by_label($1, $3);
> > + if (target)
> > + replace_nodes(target, $4);
> > + else
> > + yyerror("label, '%s' does not exist in"
> > + " node redefinition", $3);
> > + $$ = $1;
> > + }
> > + | devicetree DT_REMOVENODE DT_REF ';'
> > + {
> > + struct node *target;
> > +
> > + target = get_node_by_label($1, $3);
> > + if (target)
> > + remove_nodes(target);
> > + else
> > + yyerror("label, '%s' does not exist in"
> > + " node removal", $3);
> > ;
>
> This handles the syntax at the top level, but doesn't deal with the
> /*-node/ keywords when they are within the overlay tree.
>
> Also, I don't know if you'll be able to handle it in the same way when
> it comes to handling the new tokens embedded within an overlay tree
> because it isn't so easy to resolve the node to be removed. In order
> to handle both cases in the same way, it might be better to set a
> 'replace' flag in struct node that defers the actual remove of the
> original node until merge_nodes() time.
Ok, so maybe I misunderstood. I thought we had decided that node
modifications would only happen at the top level, but now that I'm
looking back through your examples earlier today, and I see this isn't
true.
I'll take a look at changing the implementation.
>
> >
> > nodedef:
> > diff --git a/dtc.h b/dtc.h
> > index b36ac5d..1340568 100644
> > --- a/dtc.h
> > +++ b/dtc.h
> > @@ -175,6 +175,8 @@ struct node *build_node(struct property *proplist, struct node *children);
> > 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);
> > +struct node *replace_nodes(struct node *old_node, struct node *new_node);
> > +struct node *remove_nodes(struct node *node);
> >
> > void add_property(struct node *node, struct property *prop);
> > void add_child(struct node *parent, struct node *child);
> > diff --git a/livetree.c b/livetree.c
> > index 13c5f10..5e32510 100644
> > --- a/livetree.c
> > +++ b/livetree.c
> > @@ -167,6 +167,75 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
> > return old_node;
> > }
> >
> > +struct node *remove_nodes(struct node *node) {
>
> Can be void. The return value of remove_nodes() is never used.
>
> > + struct property *prop;
> > + struct node *child, *parent;
> > +
> > + while (node->proplist) {
> > + /* Pop the property off the list */
> > + prop = node->proplist;
> > + node->proplist = prop->next;
> > + prop->next = NULL;
> > +
> > + free(prop);
> > + }
>
> It would be useful to have a 'pop_property()' macro so this could be
> simplified to:
>
> while (prop = pop_child_node(&node->proplist))
> free(prop);
>
> But then on the other hand, most of the list management is open coded
> in dtc. It would be nice to use the list_head macros like used in the
> kernel, but that is probably work for another day. (if it is even worth
> the effort).
>
> http://ccan.ozlabs.org/info/list.html
>
> > +
> > + /* Free up the node's children */
> > + /* This assumes we have a tree and not a cylic or acylic graph */
> > + while (node->children) {
> > + /* Pop the child node off the list */
> > + child = node->children;
> > + node->children = child->next_sibling;
> > + child->parent = NULL;
> > + child->next_sibling = NULL;
> > +
> > + child = remove_nodes(child);
> > + }
>
> Ditto here, except as pop_child_node().
>
> > +
> > + /* Remove the node from it's parent's child list */
> > + if (node->parent) {
> > + int found = 0;
> > +
> > + parent = node->parent;
> > +
> > + /* if the node is the first child ... */
> > + if (parent->children == node) {
> > + parent->children = node->next_sibling;
> > + found = 1;
> > + } else {
> > + for_each_child(parent, child) {
> > + if (child->next_sibling == node) {
> > + child->next_sibling = node->next_sibling;
> > + found = 1;
> > + break;
> > + }
> > + }
> > + }
> > + assert(found); /* Woah! We've got an inconsistent tree here */
> > + node->parent = NULL;
> > + node->next_sibling = NULL;
> > + }
>
> This hunk is redundantly located because recursive calls have already
> removed the node from the parent. Should split into a separate
> function called by dtc-parse.y so that the recursive bit is simpler.
>
> > +
> > + free(node);
> > +
> > + return NULL;
> > +}
>
> This block looks correct to me. It seemed a little verbose, but when
> I went through it line by line I saw that it pretty much needs to be
> that way. Especially with the list operations being open coded.
>
> > +
> > +struct node *replace_nodes(struct node *old_node, struct node *new_node)
> > +{
> > + struct label *l;
> > +
> > + /* Add old node labels to new node, so we can still refer to the
> > + * new node by the old labels. */
> > + for_each_label(old_node->labels, l)
> > + add_label(&new_node->labels, l->label);
> > +
> > + /* Free up the old_node */
> > + remove_nodes(old_node);
> > +
> > + return new_node;
> > +}
> > +
> > struct node *chain_node(struct node *first, struct node *list)
> > {
> > assert(first->next_sibling == NULL);
> >
> > _______________________________________________
> > devicetree-discuss mailing list
> > devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> > https://lists.ozlabs.org/listinfo/devicetree-discuss
> >
>
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-16 3:21 ` John Bonesio
@ 2010-10-16 6:47 ` David Gibson
2010-10-16 8:10 ` Grant Likely
0 siblings, 1 reply; 19+ messages in thread
From: David Gibson @ 2010-10-16 6:47 UTC (permalink / raw)
To: John Bonesio; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
> On Fri, 2010-10-15 at 20:35 -0600, Grant Likely wrote:
[snip]
> > > + | devicetree DT_REMOVENODE DT_REF ';'
> > > + {
> > > + struct node *target;
> > > +
> > > + target = get_node_by_label($1, $3);
> > > + if (target)
> > > + remove_nodes(target);
> > > + else
> > > + yyerror("label, '%s' does not exist in"
> > > + " node removal", $3);
> > > ;
> >
> > This handles the syntax at the top level, but doesn't deal with the
> > /*-node/ keywords when they are within the overlay tree.
> >
> > Also, I don't know if you'll be able to handle it in the same way when
> > it comes to handling the new tokens embedded within an overlay tree
> > because it isn't so easy to resolve the node to be removed. In order
> > to handle both cases in the same way, it might be better to set a
> > 'replace' flag in struct node that defers the actual remove of the
> > original node until merge_nodes() time.
>
> Ok, so maybe I misunderstood. I thought we had decided that node
> modifications would only happen at the top level, but now that I'm
> looking back through your examples earlier today, and I see this isn't
> true.
Um.. that part of the discussion got confusing. I think only allowing
the operations (and I still don't think the set implemented here are
quite right, though they're close) at the top-level is a better idea.
Grant, is there a reason you think we need to have replacement as an
option within each tree, rather than a "per-overlay-sheet" option.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-16 6:47 ` David Gibson
@ 2010-10-16 8:10 ` Grant Likely
[not found] ` <20101016081012.GH653-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
0 siblings, 1 reply; 19+ messages in thread
From: Grant Likely @ 2010-10-16 8:10 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Sat, Oct 16, 2010 at 05:47:44PM +1100, David Gibson wrote:
> On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
> > On Fri, 2010-10-15 at 20:35 -0600, Grant Likely wrote:
> [snip]
> > > > + | devicetree DT_REMOVENODE DT_REF ';'
> > > > + {
> > > > + struct node *target;
> > > > +
> > > > + target = get_node_by_label($1, $3);
> > > > + if (target)
> > > > + remove_nodes(target);
> > > > + else
> > > > + yyerror("label, '%s' does not exist in"
> > > > + " node removal", $3);
> > > > ;
> > >
> > > This handles the syntax at the top level, but doesn't deal with the
> > > /*-node/ keywords when they are within the overlay tree.
> > >
> > > Also, I don't know if you'll be able to handle it in the same way when
> > > it comes to handling the new tokens embedded within an overlay tree
> > > because it isn't so easy to resolve the node to be removed. In order
> > > to handle both cases in the same way, it might be better to set a
> > > 'replace' flag in struct node that defers the actual remove of the
> > > original node until merge_nodes() time.
> >
> > Ok, so maybe I misunderstood. I thought we had decided that node
> > modifications would only happen at the top level, but now that I'm
> > looking back through your examples earlier today, and I see this isn't
> > true.
>
> Um.. that part of the discussion got confusing. I think only allowing
> the operations (and I still don't think the set implemented here are
> quite right, though they're close) at the top-level is a better idea.
>
> Grant, is there a reason you think we need to have replacement as an
> option within each tree, rather than a "per-overlay-sheet" option.
Yes, because I need the ability to remove/replace a child of a
labelled node. Not every node that needs to be manipulated will
necessarily have a label.
For example; I could have a labelled spi bus node with child nodes for
each of the spi devices. I want to be able to remove/replace the
child nodes without having to label them first.
g.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101016081012.GH653-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-10-16 9:05 ` David Gibson
2010-10-16 13:45 ` John Bonesio
1 sibling, 0 replies; 19+ messages in thread
From: David Gibson @ 2010-10-16 9:05 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Sat, Oct 16, 2010 at 02:10:12AM -0600, Grant Likely wrote:
> On Sat, Oct 16, 2010 at 05:47:44PM +1100, David Gibson wrote:
> > On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
> > > On Fri, 2010-10-15 at 20:35 -0600, Grant Likely wrote:
[snip]
> > > Ok, so maybe I misunderstood. I thought we had decided that node
> > > modifications would only happen at the top level, but now that I'm
> > > looking back through your examples earlier today, and I see this isn't
> > > true.
> >
> > Um.. that part of the discussion got confusing. I think only allowing
> > the operations (and I still don't think the set implemented here are
> > quite right, though they're close) at the top-level is a better idea.
> >
> > Grant, is there a reason you think we need to have replacement as an
> > option within each tree, rather than a "per-overlay-sheet" option.
>
> Yes, because I need the ability to remove/replace a child of a
> labelled node. Not every node that needs to be manipulated will
> necessarily have a label.
>
> For example; I could have a labelled spi bus node with child nodes for
> each of the spi devices. I want to be able to remove/replace the
> child nodes without having to label them first.
Ah, I see. This could also be accomplished if we allowed overlays to
be targeted at (label + relative path) which we were talking about
anyway.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101016081012.GH653-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-16 9:05 ` David Gibson
@ 2010-10-16 13:45 ` John Bonesio
2010-10-16 18:32 ` Grant Likely
1 sibling, 1 reply; 19+ messages in thread
From: John Bonesio @ 2010-10-16 13:45 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Sat, 2010-10-16 at 02:10 -0600, Grant Likely wrote:
> On Sat, Oct 16, 2010 at 05:47:44PM +1100, David Gibson wrote:
> > On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
> > > On Fri, 2010-10-15 at 20:35 -0600, Grant Likely wrote:
> > [snip]
> > > > > + | devicetree DT_REMOVENODE DT_REF ';'
> > > > > + {
> > > > > + struct node *target;
> > > > > +
> > > > > + target = get_node_by_label($1, $3);
> > > > > + if (target)
> > > > > + remove_nodes(target);
> > > > > + else
> > > > > + yyerror("label, '%s' does not exist in"
> > > > > + " node removal", $3);
> > > > > ;
> > > >
> > > > This handles the syntax at the top level, but doesn't deal with the
> > > > /*-node/ keywords when they are within the overlay tree.
> > > >
> > > > Also, I don't know if you'll be able to handle it in the same way when
> > > > it comes to handling the new tokens embedded within an overlay tree
> > > > because it isn't so easy to resolve the node to be removed. In order
> > > > to handle both cases in the same way, it might be better to set a
> > > > 'replace' flag in struct node that defers the actual remove of the
> > > > original node until merge_nodes() time.
> > >
> > > Ok, so maybe I misunderstood. I thought we had decided that node
> > > modifications would only happen at the top level, but now that I'm
> > > looking back through your examples earlier today, and I see this isn't
> > > true.
> >
> > Um.. that part of the discussion got confusing. I think only allowing
> > the operations (and I still don't think the set implemented here are
> > quite right, though they're close) at the top-level is a better idea.
> >
> > Grant, is there a reason you think we need to have replacement as an
> > option within each tree, rather than a "per-overlay-sheet" option.
>
> Yes, because I need the ability to remove/replace a child of a
> labelled node. Not every node that needs to be manipulated will
> necessarily have a label.
>
> For example; I could have a labelled spi bus node with child nodes for
> each of the spi devices. I want to be able to remove/replace the
> child nodes without having to label them first.
>
> g.
>
Why not just add the label to the node you need first?
- John
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-16 13:45 ` John Bonesio
@ 2010-10-16 18:32 ` Grant Likely
[not found] ` <20101016183217.GA3774-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
0 siblings, 1 reply; 19+ messages in thread
From: Grant Likely @ 2010-10-16 18:32 UTC (permalink / raw)
To: John Bonesio; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Sat, Oct 16, 2010 at 06:45:47AM -0700, John Bonesio wrote:
> On Sat, 2010-10-16 at 02:10 -0600, Grant Likely wrote:
> > On Sat, Oct 16, 2010 at 05:47:44PM +1100, David Gibson wrote:
> > > On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
> > > > Ok, so maybe I misunderstood. I thought we had decided that node
> > > > modifications would only happen at the top level, but now that I'm
> > > > looking back through your examples earlier today, and I see this isn't
> > > > true.
> > >
> > > Um.. that part of the discussion got confusing. I think only allowing
> > > the operations (and I still don't think the set implemented here are
> > > quite right, though they're close) at the top-level is a better idea.
> > >
> > > Grant, is there a reason you think we need to have replacement as an
> > > option within each tree, rather than a "per-overlay-sheet" option.
> >
> > Yes, because I need the ability to remove/replace a child of a
> > labelled node. Not every node that needs to be manipulated will
> > necessarily have a label.
> >
> > For example; I could have a labelled spi bus node with child nodes for
> > each of the spi devices. I want to be able to remove/replace the
> > child nodes without having to label them first.
> >
> > g.
> >
>
> Why not just add the label to the node you need first?
That may not be possible and/or desirable. For instance, when the
tree is extracted from /proc. Or if the base tree in stored in the
kernel source and an external tool is modifying it for a specific
purpose (when unable to patch the kernel tree). Or for generated
device trees from the Xilinx toolchain for FPGAs. Modifying the
source data isn't always an option.
Plus I want the ability to logically group related changes. ie.
delete a device and add a device to the same bus at the same time. Or
delete a phy node, add a replacement phy node at a different address,
and update the ethernet phy-device phandle in the same block.
g.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101016183217.GA3774-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-10-18 0:11 ` David Gibson
2010-10-18 16:01 ` Grant Likely
0 siblings, 1 reply; 19+ messages in thread
From: David Gibson @ 2010-10-18 0:11 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Sat, Oct 16, 2010 at 12:32:17PM -0600, Grant Likely wrote:
> On Sat, Oct 16, 2010 at 06:45:47AM -0700, John Bonesio wrote:
> > On Sat, 2010-10-16 at 02:10 -0600, Grant Likely wrote:
> > > On Sat, Oct 16, 2010 at 05:47:44PM +1100, David Gibson wrote:
> > > > On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
[snip]
> > > For example; I could have a labelled spi bus node with child nodes for
> > > each of the spi devices. I want to be able to remove/replace the
> > > child nodes without having to label them first.
> > >
> > > g.
> >
> > Why not just add the label to the node you need first?
>
> That may not be possible and/or desirable. For instance, when the
> tree is extracted from /proc. Or if the base tree in stored in the
> kernel source and an external tool is modifying it for a specific
> purpose (when unable to patch the kernel tree). Or for generated
> device trees from the Xilinx toolchain for FPGAs. Modifying the
> source data isn't always an option.
You can apply your overlays by path in this case..
> Plus I want the ability to logically group related changes. ie.
> delete a device and add a device to the same bus at the same time.
> Or delete a phy node, add a replacement phy node at a different
> address, and update the ethernet phy-device phandle in the same
> block.
Hrm, I really don't think this is a good argument. You're conflating
the grouping of logically related changes with the tree structure
which I think is a mistake. Putting the changes in the same file
and/or adjusting your spacing and comments to show the logical
grouping seems less likely to cause other problems.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-16 1:07 [PATCH] Implements new features for updating existing device tree nodes John Bonesio
2010-10-16 2:35 ` Grant Likely
@ 2010-10-18 0:27 ` David Gibson
1 sibling, 0 replies; 19+ messages in thread
From: David Gibson @ 2010-10-18 0:27 UTC (permalink / raw)
To: John Bonesio; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Fri, Oct 15, 2010 at 06:07:50PM -0700, John Bonesio wrote:
> This is interesting when the /include/ "<filename>" feature is used. This way
> we can create base device tree source files for a family of systems and modify
> the device tree for a specific system.
>
> The current sytem allows an existing node to be extended with new properties
> and subnodes.
>
> The new features allow an existing node to be replaced completely by the new
> properties and subnodes. The new features also allow an existing node to be
> deleted.
>
> This patch does not yet provide a way to remove properties.
Detailed comments below.
> dtc-lexer.l | 12 ++++++++++
> dtc-parser.y | 24 ++++++++++++++++++++
> dtc.h | 2 ++
> livetree.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 107 insertions(+), 0 deletions(-)
>
> diff --git a/dtc-lexer.l b/dtc-lexer.l
> index 081e13a..a24edf5 100644
> --- a/dtc-lexer.l
> +++ b/dtc-lexer.l
> @@ -96,6 +96,18 @@ static int pop_input_file(void);
> return DT_MEMRESERVE;
> }
>
> +<*>"/trim-node/" {
> + DPRINT("Keyword: /trim-node/\n");
> + BEGIN_DEFAULT();
> + return DT_REPLACENODE;
> + }
Hrm. The keyword is "/trim-node/", but the C symbol is REPLACENODE.
Potentially confusing.
Also, while "trim-node" seemed a reasonable option to me in some
contexts, with the semantics implemented in this patch, I think
"replace-node" would be far clearer.
> +<*>"/remove-node/" {
> + DPRINT("Keyword: /remove-node/\n");
> + BEGIN_DEFAULT();
> + return DT_REMOVENODE;
> + }
> +
> <*>{LABEL}: {
> DPRINT("Label: %s\n", yytext);
> yylval.labelref = xstrdup(yytext);
> diff --git a/dtc-parser.y b/dtc-parser.y
> index aa250f1..a9cde72 100644
> --- a/dtc-parser.y
> +++ b/dtc-parser.y
> @@ -54,6 +54,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
>
> %token DT_V1
> %token DT_MEMRESERVE
> +%token DT_REPLACENODE
> +%token DT_REMOVENODE
> %token <propnodename> DT_PROPNODENAME
> %token <literal> DT_LITERAL
> %token <cbase> DT_BASE
> @@ -140,6 +142,28 @@ devicetree:
> " node extension", $2);
> $$ = $1;
> }
> + | devicetree DT_REPLACENODE DT_REF nodedef
> + {
> + struct node *target;
> +
> + target = get_node_by_label($1, $3);
> + if (target)
> + replace_nodes(target, $4);
> + else
> + yyerror("label, '%s' does not exist in"
> + " node redefinition", $3);
> + $$ = $1;
> + }
> + | devicetree DT_REMOVENODE DT_REF ';'
> + {
> + struct node *target;
> +
> + target = get_node_by_label($1, $3);
> + if (target)
> + remove_nodes(target);
> + else
> + yyerror("label, '%s' does not exist in"
> + " node removal", $3);
> ;
>
> nodedef:
> diff --git a/dtc.h b/dtc.h
> index b36ac5d..1340568 100644
> --- a/dtc.h
> +++ b/dtc.h
> @@ -175,6 +175,8 @@ struct node *build_node(struct property *proplist, struct node *children);
> 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);
> +struct node *replace_nodes(struct node *old_node, struct node *new_node);
> +struct node *remove_nodes(struct node *node);
>
> void add_property(struct node *node, struct property *prop);
> void add_child(struct node *parent, struct node *child);
> diff --git a/livetree.c b/livetree.c
> index 13c5f10..5e32510 100644
> --- a/livetree.c
> +++ b/livetree.c
> @@ -167,6 +167,75 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
> return old_node;
> }
>
> +struct node *remove_nodes(struct node *node) {
> + struct property *prop;
> + struct node *child, *parent;
> +
> + while (node->proplist) {
> + /* Pop the property off the list */
> + prop = node->proplist;
> + node->proplist = prop->next;
> + prop->next = NULL;
> +
> + free(prop);
> + }
> +
> + /* Free up the node's children */
> + /* This assumes we have a tree and not a cylic or acylic graph */
> + while (node->children) {
> + /* Pop the child node off the list */
> + child = node->children;
> + node->children = child->next_sibling;
> + child->parent = NULL;
> + child->next_sibling = NULL;
> +
> + child = remove_nodes(child);
> + }
> +
> + /* Remove the node from it's parent's child list */
> + if (node->parent) {
> + int found = 0;
This should go first, before the recursive free()ing. I know we don't
have any concurrency to worry about in dtc, but as a general habit it
should always be remove from the structure first, then do the
disposal.
And then, don't bother with the disposal. I'm pretty sure we already
have some leaks and I really don't care. dtc is a strictly transient
process, so we can basically treating malloc() as a pool allocator
with exactly one pool, freed at exit. If we do need something more
subtle infuture, we can use an actual pool allocator (talloc, for
preference). The fact that in dts parsing we build the tree from the
leaves, but in dtb parsing we bulid it from the root makes lifetimes
complex enough that fully correct explicit free()ing is actually quite
a pain.
(Oh, and, in the case where you're removing, not replacing, you
already leak the labels. See my point :)
> + parent = node->parent;
> +
> + /* if the node is the first child ... */
> + if (parent->children == node) {
> + parent->children = node->next_sibling;
> + found = 1;
> + } else {
> + for_each_child(parent, child) {
> + if (child->next_sibling == node) {
> + child->next_sibling = node->next_sibling;
> + found = 1;
> + break;
> + }
> + }
> + }
You can do better:
ptr = &parent->children;
for_each_child(...) {
if (child == node) {
*ptr = child->next_sibling;
found = 1;
ptr = &child->next_sibling;
}
}
This pointer-to-pointer idiom is used in a number of other places.
> + assert(found); /* Woah! We've got an inconsistent tree here */
> + node->parent = NULL;
> + node->next_sibling = NULL;
> + }
> +
> + free(node);
> +
> + return NULL;
> +}
> +
> +struct node *replace_nodes(struct node *old_node, struct node *new_node)
> +{
> + struct label *l;
> +
> + /* Add old node labels to new node, so we can still refer to the
> + * new node by the old labels. */
> + for_each_label(old_node->labels, l)
> + add_label(&new_node->labels, l->label);
Yeah. labels to subnodes of the original still disappear without
trace, and could therefore be re-used. I think this has the potential
to be very confusing. We need to be more careful with the label
semantics.
> + /* Free up the old_node */
> + remove_nodes(old_node);
> +
> + return new_node;
> +}
> +
> struct node *chain_node(struct node *first, struct node *list)
> {
> assert(first->next_sibling == NULL);
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <AANLkTimx4z-YkH+PXcnKYJpq3MEd3oJZ+ow7mWJzn1BN-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-16 3:21 ` John Bonesio
@ 2010-10-18 0:51 ` David Gibson
1 sibling, 0 replies; 19+ messages in thread
From: David Gibson @ 2010-10-18 0:51 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Fri, Oct 15, 2010 at 08:35:56PM -0600, Grant Likely wrote:
> Hi John.
>
> On Fri, Oct 15, 2010 at 7:07 PM, John Bonesio <bones-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> > This is interesting when the /include/ "<filename>" feature is used. This way
> > we can create base device tree source files for a family of systems and modify
> > the device tree for a specific system.
> >
> > The current sytem allows an existing node to be extended with new properties
> > and subnodes.
> >
> > The new features allow an existing node to be replaced completely by the new
> > properties and subnodes. The new features also allow an existing node to be
> > deleted.
> >
> > This patch does not yet provide a way to remove properties.
> >
> > - John
>
> Also need s-o-b line, and anything that doesn't belong as part of the
> commit message, such as '- John', needs to be below the '---' line so
> that git will ignore it.
>
> The patch looks pretty good, but I cannot comment fully until the
> keyword handling works when deeper in the tree (see below).
[snip]
> > + struct property *prop;
> > + struct node *child, *parent;
> > +
> > + while (node->proplist) {
> > + /* Pop the property off the list */
> > + prop = node->proplist;
> > + node->proplist = prop->next;
> > + prop->next = NULL;
> > +
> > + free(prop);
> > + }
>
> It would be useful to have a 'pop_property()' macro so this could be
> simplified to:
>
> while (prop = pop_child_node(&node->proplist))
> free(prop);
>
> But then on the other hand, most of the list management is open coded
> in dtc. It would be nice to use the list_head macros like used in the
> kernel, but that is probably work for another day. (if it is even worth
> the effort).
I had a look into this at one point. The way we build up the tree in
a kinda-sorta functional programming like way in dts parsing actually
makes using the list.h form kind of hard. At least without a fancier
allocator (maybe I should bite the bullet and do a talloc conversion).
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-18 0:11 ` David Gibson
@ 2010-10-18 16:01 ` Grant Likely
[not found] ` <20101018160115.GN19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
0 siblings, 1 reply; 19+ messages in thread
From: Grant Likely @ 2010-10-18 16:01 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, Oct 18, 2010 at 11:11:35AM +1100, David Gibson wrote:
> On Sat, Oct 16, 2010 at 12:32:17PM -0600, Grant Likely wrote:
> > On Sat, Oct 16, 2010 at 06:45:47AM -0700, John Bonesio wrote:
> > > On Sat, 2010-10-16 at 02:10 -0600, Grant Likely wrote:
> > > > On Sat, Oct 16, 2010 at 05:47:44PM +1100, David Gibson wrote:
> > > > > On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
> [snip]
> > > > For example; I could have a labelled spi bus node with child nodes for
> > > > each of the spi devices. I want to be able to remove/replace the
> > > > child nodes without having to label them first.
> > > >
> > > > g.
> > >
> > > Why not just add the label to the node you need first?
> >
> > That may not be possible and/or desirable. For instance, when the
> > tree is extracted from /proc. Or if the base tree in stored in the
> > kernel source and an external tool is modifying it for a specific
> > purpose (when unable to patch the kernel tree). Or for generated
> > device trees from the Xilinx toolchain for FPGAs. Modifying the
> > source data isn't always an option.
>
> You can apply your overlays by path in this case..
Right, but my argument is that in this case it is a useful syntax to
be able to delve deep into the tree, or deeper off of a label and
delete nodes within it. And it is actually a really simple thing to
implement cleanly (as shown in the patch I posted).
>
> > Plus I want the ability to logically group related changes. ie.
> > delete a device and add a device to the same bus at the same time.
> > Or delete a phy node, add a replacement phy node at a different
> > address, and update the ethernet phy-device phandle in the same
> > block.
>
> Hrm, I really don't think this is a good argument. You're conflating
> the grouping of logically related changes with the tree structure
> which I think is a mistake. Putting the changes in the same file
> and/or adjusting your spacing and comments to show the logical
> grouping seems less likely to cause other problems.
Though I'm not happy with it, I can live with only allowing removal of
nodes at the top level. In fact, that constraint also completely
removes the need for a /replace-node/ keyword since the remove
operation is performed at the top level where ordering is explicitly
allowed. So, instead of:
/{
node { oldprop; };
};
/{
/replace-node/ the-node { newprop; };
};
do this instead:
/{
node { oldprop; };
};
/remove-node/ &{/the-node};
/{
the-node { newprop; };
};
It means only the /remove-node/ keyword needs to be defined. However,
it does mean that the syntax for full path references must be defined
immediately before it is useful.
g.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101018160115.GN19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-10-18 17:42 ` Scott Wood
[not found] ` <20101018124220.50a4c097-N/eSCTBpGwP7j4BuCOFQISmX4OfbXNuMKnGXBo5VDl8@public.gmane.org>
2010-10-19 0:54 ` David Gibson
2010-10-19 1:06 ` David Gibson
2 siblings, 1 reply; 19+ messages in thread
From: Scott Wood @ 2010-10-18 17:42 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, 18 Oct 2010 10:01:15 -0600
Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> On Mon, Oct 18, 2010 at 11:11:35AM +1100, David Gibson wrote:
> > On Sat, Oct 16, 2010 at 12:32:17PM -0600, Grant Likely wrote:
> > > Plus I want the ability to logically group related changes. ie.
> > > delete a device and add a device to the same bus at the same time.
> > > Or delete a phy node, add a replacement phy node at a different
> > > address, and update the ethernet phy-device phandle in the same
> > > block.
> >
> > Hrm, I really don't think this is a good argument. You're conflating
> > the grouping of logically related changes with the tree structure
> > which I think is a mistake. Putting the changes in the same file
> > and/or adjusting your spacing and comments to show the logical
> > grouping seems less likely to cause other problems.
Shouldn't the tree structure, if practical, represent the logical
structure? The actual operations (as the user intends them) are on
particular properties or subnodes, not on top-level trees.
Likewise with the extension of nodes being unordered in the output
tree (or allowing forward references) to disallowing any
situation where ordering of dts statements matters. It seems to be
sticking with a certain design idea just for the sake of it (or
possibly for the convenience of the existing dtc implementation?), at
the cost of readability/intuitiveness.
It's not an unbearable cost, but I wonder what we really gain from it.
> Though I'm not happy with it, I can live with only allowing removal of
> nodes at the top level. In fact, that constraint also completely
> removes the need for a /replace-node/ keyword since the remove
> operation is performed at the top level where ordering is explicitly
> allowed. So, instead of:
>
> /{
> node { oldprop; };
> };
> /{
> /replace-node/ the-node { newprop; };
> };
>
> do this instead:
>
> /{
> node { oldprop; };
> };
> /remove-node/ &{/the-node};
> /{
> the-node { newprop; };
> };
>
> It means only the /remove-node/ keyword needs to be defined.
What about property removal? Or do you mean the only one related to
nodes?
-Scott
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101018124220.50a4c097-N/eSCTBpGwP7j4BuCOFQISmX4OfbXNuMKnGXBo5VDl8@public.gmane.org>
@ 2010-10-18 19:56 ` Grant Likely
[not found] ` <20101018195629.GB2259-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
0 siblings, 1 reply; 19+ messages in thread
From: Grant Likely @ 2010-10-18 19:56 UTC (permalink / raw)
To: Scott Wood; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, Oct 18, 2010 at 12:42:20PM -0500, Scott Wood wrote:
> On Mon, 18 Oct 2010 10:01:15 -0600
> Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
>
> > On Mon, Oct 18, 2010 at 11:11:35AM +1100, David Gibson wrote:
> > > On Sat, Oct 16, 2010 at 12:32:17PM -0600, Grant Likely wrote:
> > > > Plus I want the ability to logically group related changes. ie.
> > > > delete a device and add a device to the same bus at the same time.
> > > > Or delete a phy node, add a replacement phy node at a different
> > > > address, and update the ethernet phy-device phandle in the same
> > > > block.
> > >
> > > Hrm, I really don't think this is a good argument. You're conflating
> > > the grouping of logically related changes with the tree structure
> > > which I think is a mistake. Putting the changes in the same file
> > > and/or adjusting your spacing and comments to show the logical
> > > grouping seems less likely to cause other problems.
>
> Shouldn't the tree structure, if practical, represent the logical
> structure? The actual operations (as the user intends them) are on
> particular properties or subnodes, not on top-level trees.
>
> Likewise with the extension of nodes being unordered in the output
> tree (or allowing forward references) to disallowing any
> situation where ordering of dts statements matters. It seems to be
> sticking with a certain design idea just for the sake of it (or
> possibly for the convenience of the existing dtc implementation?), at
> the cost of readability/intuitiveness.
The current structure of dtc is allowed to be quite simple because it
builds up each top level tree in memory and then merge them wholesale.
It doesn't have to merge at two levels (ie. merge each node as it is
added, and then merge the trees again at the top level), and the
parser doesn't need to have any context about the rest of the tree
until the trees get merged.
It really does keep things simple without being too onerous on the
user. At the very least, I don't have any use cases that require the
ability to reference the same node twice from within a single top
level tree.
> It's not an unbearable cost, but I wonder what we really gain from it.
>
> > Though I'm not happy with it, I can live with only allowing removal of
> > nodes at the top level. In fact, that constraint also completely
> > removes the need for a /replace-node/ keyword since the remove
> > operation is performed at the top level where ordering is explicitly
> > allowed. So, instead of:
> >
> > /{
> > node { oldprop; };
> > };
> > /{
> > /replace-node/ the-node { newprop; };
> > };
> >
> > do this instead:
> >
> > /{
> > node { oldprop; };
> > };
> > /remove-node/ &{/the-node};
> > /{
> > the-node { newprop; };
> > };
> >
> > It means only the /remove-node/ keyword needs to be defined.
>
> What about property removal? Or do you mean the only one related to
> nodes?
Property removal will have its own syntax because it isn't the same
thing, and properties live in a different namespace from nodes. Also,
the use case is simpler because 'extend' isn't assumed for properties
like it is for nodes. Properties can either be replaced, or removed
outright. If we ever do have an extend syntax it will mostly likely
just be another form of replace which a syntax to pull in parts of the
old value (or parts of another properties value).
So anyway, the property removal syntax will be implemented in a
separate patch.
g.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101018160115.GN19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 17:42 ` Scott Wood
@ 2010-10-19 0:54 ` David Gibson
2010-10-19 1:06 ` David Gibson
2 siblings, 0 replies; 19+ messages in thread
From: David Gibson @ 2010-10-19 0:54 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, Oct 18, 2010 at 10:01:15AM -0600, Grant Likely wrote:
> On Mon, Oct 18, 2010 at 11:11:35AM +1100, David Gibson wrote:
> > On Sat, Oct 16, 2010 at 12:32:17PM -0600, Grant Likely wrote:
> > > On Sat, Oct 16, 2010 at 06:45:47AM -0700, John Bonesio wrote:
> > > > On Sat, 2010-10-16 at 02:10 -0600, Grant Likely wrote:
> > > > > On Sat, Oct 16, 2010 at 05:47:44PM +1100, David Gibson wrote:
> > > > > > On Fri, Oct 15, 2010 at 08:21:17PM -0700, John Bonesio wrote:
> > [snip]
> > > > > For example; I could have a labelled spi bus node with child nodes for
> > > > > each of the spi devices. I want to be able to remove/replace the
> > > > > child nodes without having to label them first.
> > > > >
> > > > > g.
> > > >
> > > > Why not just add the label to the node you need first?
> > >
> > > That may not be possible and/or desirable. For instance, when the
> > > tree is extracted from /proc. Or if the base tree in stored in the
> > > kernel source and an external tool is modifying it for a specific
> > > purpose (when unable to patch the kernel tree). Or for generated
> > > device trees from the Xilinx toolchain for FPGAs. Modifying the
> > > source data isn't always an option.
> >
> > You can apply your overlays by path in this case..
>
> Right, but my argument is that in this case it is a useful syntax to
> be able to delve deep into the tree, or deeper off of a label and
> delete nodes within it. And it is actually a really simple thing to
> implement cleanly (as shown in the patch I posted).
Oh, it's perfectly easy to implement, yes. It's the step up in
complexity of the mental model required that concerns me about it (now
each overlay in the stack can have some "transparent" and some
"opaque" parts).
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101018195629.GB2259-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-10-19 1:02 ` David Gibson
2010-10-19 3:42 ` Grant Likely
0 siblings, 1 reply; 19+ messages in thread
From: David Gibson @ 2010-10-19 1:02 UTC (permalink / raw)
To: Grant Likely; +Cc: Scott Wood, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, Oct 18, 2010 at 01:56:29PM -0600, Grant Likely wrote:
> On Mon, Oct 18, 2010 at 12:42:20PM -0500, Scott Wood wrote:
> > On Mon, 18 Oct 2010 10:01:15 -0600
> > Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
[snip]
> > Likewise with the extension of nodes being unordered in the output
> > tree (or allowing forward references) to disallowing any
> > situation where ordering of dts statements matters. It seems to be
> > sticking with a certain design idea just for the sake of it (or
> > possibly for the convenience of the existing dtc implementation?), at
> > the cost of readability/intuitiveness.
>
> The current structure of dtc is allowed to be quite simple because it
> builds up each top level tree in memory and then merge them wholesale.
> It doesn't have to merge at two levels (ie. merge each node as it is
> added, and then merge the trees again at the top level), and the
> parser doesn't need to have any context about the rest of the tree
> until the trees get merged.
>
> It really does keep things simple without being too onerous on the
> user. At the very least, I don't have any use cases that require the
> ability to reference the same node twice from within a single top
> level tree.
It does simplify the implementation a little, but that's not the real
reason for it. The main reason is that:
somebus {
ethernet@100100 {
reg = <0x100100>;
...
};
ethernet@100100 {
reg = <0x100200>;
...
};
};
Is probably just a mistake, forgetting to adjust unit address when
they copy/pasted for the second ethernet. But if we allowed
merging/overriding everywhere, not just at the top level it would be
silently accepted, clobbering most of the first ethernet node's info
with stuff intended for the second.
Allowing the extension only at the top level makes the user do
something explicit to signal that they intend to update/override
existing parts of the tree.
> > It's not an unbearable cost, but I wonder what we really gain from it.
> >
> > > Though I'm not happy with it, I can live with only allowing removal of
> > > nodes at the top level. In fact, that constraint also completely
> > > removes the need for a /replace-node/ keyword since the remove
> > > operation is performed at the top level where ordering is explicitly
> > > allowed. So, instead of:
> > >
> > > /{
> > > node { oldprop; };
> > > };
> > > /{
> > > /replace-node/ the-node { newprop; };
> > > };
> > >
> > > do this instead:
> > >
> > > /{
> > > node { oldprop; };
> > > };
> > > /remove-node/ &{/the-node};
> > > /{
> > > the-node { newprop; };
> > > };
> > >
> > > It means only the /remove-node/ keyword needs to be defined.
> >
> > What about property removal? Or do you mean the only one related to
> > nodes?
>
> Property removal will have its own syntax because it isn't the same
> thing, and properties live in a different namespace from nodes. Also,
> the use case is simpler because 'extend' isn't assumed for properties
> like it is for nodes. Properties can either be replaced, or removed
> outright. If we ever do have an extend syntax it will mostly likely
> just be another form of replace which a syntax to pull in parts of the
> old value (or parts of another properties value).
Right. I think property value expressions are pretty much a
prerequisite for a sane implementation of this.
> So anyway, the property removal syntax will be implemented in a
> separate patch.
I'd actually prefer to see that patch come first, I have far less
doubts about how best to implement that than I do with the node
removing/replacing stuff.
Specifically, I'd happily ack a patch which implemented
someprop = /undef-prop/;
immediately.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
[not found] ` <20101018160115.GN19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 17:42 ` Scott Wood
2010-10-19 0:54 ` David Gibson
@ 2010-10-19 1:06 ` David Gibson
2010-10-19 3:41 ` Grant Likely
2 siblings, 1 reply; 19+ messages in thread
From: David Gibson @ 2010-10-19 1:06 UTC (permalink / raw)
To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, Oct 18, 2010 at 10:01:15AM -0600, Grant Likely wrote:
[snip]
> It means only the /remove-node/ keyword needs to be defined. However,
> it does mean that the syntax for full path references must be defined
> immediately before it is useful.
Actually, because of the way DT_REF is lexed, I believe
&{/some/path} {
prop = "new-value";
};
Will work already.
Or do you mean implementing references to a label + relative path?
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-19 1:06 ` David Gibson
@ 2010-10-19 3:41 ` Grant Likely
0 siblings, 0 replies; 19+ messages in thread
From: Grant Likely @ 2010-10-19 3:41 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, Oct 18, 2010 at 7:06 PM, David Gibson
<david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org> wrote:
> On Mon, Oct 18, 2010 at 10:01:15AM -0600, Grant Likely wrote:
> [snip]
>> It means only the /remove-node/ keyword needs to be defined. However,
>> it does mean that the syntax for full path references must be defined
>> immediately before it is useful.
>
> Actually, because of the way DT_REF is lexed, I believe
>
> &{/some/path} {
> prop = "new-value";
> };
>
> Will work already.
>
> Or do you mean implementing references to a label + relative path?
yes.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Implements new features for updating existing device tree nodes.
2010-10-19 1:02 ` David Gibson
@ 2010-10-19 3:42 ` Grant Likely
0 siblings, 0 replies; 19+ messages in thread
From: Grant Likely @ 2010-10-19 3:42 UTC (permalink / raw)
To: David Gibson; +Cc: Scott Wood, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Mon, Oct 18, 2010 at 7:02 PM, David Gibson
<david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org> wrote:
> Specifically, I'd happily ack a patch which implemented
> someprop = /undef-prop/;
> immediately.
I would to.
g.
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2010-10-19 3:42 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-16 1:07 [PATCH] Implements new features for updating existing device tree nodes John Bonesio
2010-10-16 2:35 ` Grant Likely
[not found] ` <AANLkTimx4z-YkH+PXcnKYJpq3MEd3oJZ+ow7mWJzn1BN-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-10-16 3:21 ` John Bonesio
2010-10-16 6:47 ` David Gibson
2010-10-16 8:10 ` Grant Likely
[not found] ` <20101016081012.GH653-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-16 9:05 ` David Gibson
2010-10-16 13:45 ` John Bonesio
2010-10-16 18:32 ` Grant Likely
[not found] ` <20101016183217.GA3774-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 0:11 ` David Gibson
2010-10-18 16:01 ` Grant Likely
[not found] ` <20101018160115.GN19399-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-18 17:42 ` Scott Wood
[not found] ` <20101018124220.50a4c097-N/eSCTBpGwP7j4BuCOFQISmX4OfbXNuMKnGXBo5VDl8@public.gmane.org>
2010-10-18 19:56 ` Grant Likely
[not found] ` <20101018195629.GB2259-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-10-19 1:02 ` David Gibson
2010-10-19 3:42 ` Grant Likely
2010-10-19 0:54 ` David Gibson
2010-10-19 1:06 ` David Gibson
2010-10-19 3:41 ` Grant Likely
2010-10-18 0:51 ` David Gibson
2010-10-18 0:27 ` David Gibson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.