[PATCH 3/4] Allow nodes at the root to be specified by path as well as by label.

Grant Likely grant.likely at secretlab.ca
Thu Oct 21 15:36:00 EST 2010


On Wed, Oct 20, 2010 at 02:45:13PM -0700, John Bonesio wrote:
> Changes to allow us to specify a node by it's path. A path can be used in
> place of a label.
> 
> This is particularly useful when overriding existing nodes.
> This way we don't have to label every possible node in a device tree we know
> is a base device tree for a class of systems, and we know the tree will be
> modified for the specific systems.
> 
> Signed-off-by: John Bonesio <bones at secretlab.ca>

As already mentioned, but I'm reposting here for the list archive
record, this syntax conflicts with existing convention for referencing
nodes by names defined in the /aliases node.

One more comment below.

> ---
> 
>  dtc-lexer.l  |   26 ++++++++++++++++++++++----
>  dtc-parser.y |   10 ++++------
>  livetree.c   |   20 +++++++++++++++++++-
>  3 files changed, 45 insertions(+), 11 deletions(-)
> 
> diff --git a/dtc-lexer.l b/dtc-lexer.l
> index 80a886a..216a3d2 100644
> --- a/dtc-lexer.l
> +++ b/dtc-lexer.l
> @@ -115,13 +115,31 @@ static int pop_input_file(void);
>  			return DT_LITERAL;
>  		}
>  
> -<*>\&{LABEL}	{	/* label reference */
> -			DPRINT("Ref: %s\n", yytext+1);
> -			yylval.labelref = xstrdup(yytext+1);
> +
> +<*>\&{LABEL}    {       /* label reference without the braces*/
> +                        DPRINT("Ref: %s\n", yytext+1);
> +                        yylval.labelref = xstrdup(yytext+1);
> +                        return DT_REF;
> +		}
> +
> +<*>"&{"{LABEL}{PATHCHAR}*\} { /* label and/or path refererence with braces */
> +			/*
> +			 * Possibly this could be parsed by the parser rather
> +			 * than as a lexical element.
> +			 *
> +			 * What is intended here is to support the following
> +			 * type of references:
> +			 * a) &{/path/to/the/node/reference}
> +			 * b) &{label}
> +			 * c) &{label/path/from/labeled/node/to/reference}
> +			 */
> +			yytext[yyleng-1] = '\0';
> +			DPRINT("Ref: %s\n", yytext+2);
> +			yylval.labelref = xstrdup(yytext+2);
>  			return DT_REF;
>  		}
>  
> -"&{/"{PATHCHAR}+\}	{	/* new-style path reference */
> +<*>"&{/"{PATHCHAR}+\}	{	/* new-style path reference (with braces) */
>  			yytext[yyleng-1] = '\0';
>  			DPRINT("Ref: %s\n", yytext+2);
>  			yylval.labelref = xstrdup(yytext+2);
> diff --git a/dtc-parser.y b/dtc-parser.y
> index 1ba0478..0a74c86 100644
> --- a/dtc-parser.y
> +++ b/dtc-parser.y
> @@ -132,24 +132,22 @@ devicetree:
>  		}
>  	| devicetree DT_REF nodedef
>  		{
> -			struct node *target;
> +			struct node *target = get_node_by_ref($1, $2);
>  
> -			target = get_node_by_label($1, $2);
>  			if (target)
>  				merge_nodes(target, $3);
>  			else
> -				print_error("label, '%s' not found", $2);
> +				print_error("label or path, '%s', not found", $2);

For clarity, the above hunk should be in a separate patch applied
between patches #1 and #2.  That will avoid having one patch introduce
the DT_REMOVENODE hunk below, and then immediately modify it again in
this patch.  The switch to get_node_by_ref() is useful even without
the label+path syntax, and it should also include a matching testcase.

>  			$$ = $1;
>  		}
>  	| devicetree DT_REMOVENODE DT_REF ';'
>  		{
> -			struct node *target;
> +			struct node *target = get_node_by_ref($1, $3);
>  
> -			target = get_node_by_label($1, $3);
>  			if (target)
>  				remove_child(target->parent, target);
>  			else
> -				print_error("label, '%s' not found", $3);
> +				print_error("label or path, '%s', not found", $3);
>  		}
>  	;
>  
> diff --git a/livetree.c b/livetree.c
> index 21a4c48..bf8796b 100644
> --- a/livetree.c
> +++ b/livetree.c
> @@ -429,10 +429,28 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
>  
>  struct node *get_node_by_ref(struct node *tree, const char *ref)
>  {
> +	struct node *node;
> +
>  	if (ref[0] == '/')
>  		return get_node_by_path(tree, ref);
> -	else
> +	else {
> +		/*
> +		 * Support finding a node reference that is rooted by
> +		 * a label reference.
> +		 *
> +		 * References rooted by a label have a '/' in them.
> +		 */
> +		char *p = strchr(ref, '/');
> +
> +		if (p) {
> +			*p = '\0';
> +			node = get_node_by_label(tree, ref);
> +			*p = '/';
> +			return get_node_by_path(node, p+1);
> +		}
> +
>  		return get_node_by_label(tree, ref);
> +	}
>  }
>  
>  cell_t get_node_phandle(struct node *root, struct node *node)
> 


More information about the devicetree-discuss mailing list