[PATCH] dtc: add ability to make nodes conditional on them being referenced
Tom Rini
trini at konsulko.com
Sat Jan 25 17:20:28 CET 2020
On Tue, Jan 21, 2020 at 10:23:17AM +0000, Andre Przywara wrote:
> From: Maxime Ripard <maxime.ripard at bootlin.com>
>
> This is needed when importing mainline DTs into U-Boot, as some started
> using this /omit-if-no-ref/ tag, so won't compile with U-Boot's current
> dtc copy. This is just a cherry-pick of the patch introducing this
> feature.
> Original commit message from Maxime:
> ------------------
> A number of platforms have a need to reduce the number of DT nodes,
> mostly because of two similar constraints: the size of the DT blob, and
> the time it takes to parse it.
>
> As the DT is used in more and more SoCs, and by more projects, some
> constraints start to appear in bootloaders running from SRAM with an
> order of magnitude of 10kB. A typical DT is in the same order of
> magnitude, so any effort to reduce the blob size is welcome in such an
> environment.
>
> Some platforms also want to reach very fast boot time, and the time it
> takes to parse a typical DT starts to be noticeable.
>
> Both of these issues can be mitigated by reducing the number of nodes in
> the DT. The biggest provider of nodes is usually the pin controller and
> its subnodes, usually one for each valid pin configuration in a given
> SoC.
>
> Obviously, a single, fixed, set of these nodes will be used by a given
> board, so we can introduce a node property that will tell the DT
> compiler to drop the nodes when they are not referenced in the tree, and
> as such wouldn't be useful in the targetted system.
>
> Signed-off-by: Maxime Ripard <maxime.ripard at bootlin.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
> scripts/dtc/checks.c | 13 +++++++++++++
> scripts/dtc/dtc-lexer.l | 7 +++++++
> scripts/dtc/dtc-parser.y | 17 +++++++++++++++++
> scripts/dtc/dtc.h | 4 ++++
> scripts/dtc/livetree.c | 14 ++++++++++++++
> 5 files changed, 55 insertions(+)
>
> diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
> index c07ba4da9e..40879677c8 100644
> --- a/scripts/dtc/checks.c
> +++ b/scripts/dtc/checks.c
> @@ -579,6 +579,8 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
>
> phandle = get_node_phandle(dt, refnode);
> *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
> +
> + reference_node(refnode);
> }
> }
> }
> @@ -609,11 +611,21 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
> path = refnode->fullpath;
> prop->val = data_insert_at_marker(prop->val, m, path,
> strlen(path) + 1);
> +
> + reference_node(refnode);
> }
> }
> }
> ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
>
> +static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti,
> + struct node *node)
> +{
> + if (node->omit_if_unused && !node->is_referenced)
> + delete_node(node);
> +}
> +ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references);
> +
> /*
> * Semantic checks
> */
> @@ -1367,6 +1379,7 @@ static struct check *check_table[] = {
>
> &explicit_phandles,
> &phandle_references, &path_references,
> + &omit_unused_nodes,
>
> &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
> &device_type_is_string, &model_is_string, &status_is_string,
> diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
> index fd825ebba6..615b7ec658 100644
> --- a/scripts/dtc/dtc-lexer.l
> +++ b/scripts/dtc/dtc-lexer.l
> @@ -153,6 +153,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
> return DT_DEL_NODE;
> }
>
> +<*>"/omit-if-no-ref/" {
> + DPRINT("Keyword: /omit-if-no-ref/\n");
> + DPRINT("<PROPNODENAME>\n");
> + BEGIN(PROPNODENAME);
> + return DT_OMIT_NO_REF;
> + }
> +
> <*>{LABEL}: {
> DPRINT("Label: %s\n", yytext);
> yylval.labelref = xstrdup(yytext);
> diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
> index 44af170abf..66ff7f7d8e 100644
> --- a/scripts/dtc/dtc-parser.y
> +++ b/scripts/dtc/dtc-parser.y
> @@ -63,6 +63,7 @@ extern bool treesource_error;
> %token DT_BITS
> %token DT_DEL_PROP
> %token DT_DEL_NODE
> +%token DT_OMIT_NO_REF
> %token <propnodename> DT_PROPNODENAME
> %token <integer> DT_LITERAL
> %token <integer> DT_CHAR_LITERAL
> @@ -217,6 +218,18 @@ devicetree:
> ERROR(&@3, "Label or path %s not found", $3);
>
>
> + $$ = $1;
> + }
> + | devicetree DT_OMIT_NO_REF DT_REF ';'
> + {
> + struct node *target = get_node_by_ref($1, $3);
> +
> + if (target)
> + omit_node_if_unused(target);
> + else
> + ERROR(&@3, "Label or path %s not found", $3);
> +
> +
> $$ = $1;
> }
> ;
> @@ -523,6 +536,10 @@ subnode:
> {
> $$ = name_node(build_node_delete(), $2);
> }
> + | DT_OMIT_NO_REF subnode
> + {
> + $$ = omit_node_if_unused($2);
> + }
> | DT_LABEL subnode
> {
> add_label(&$2->labels, $1);
> diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
> index 3b18a42b86..6d667701ab 100644
> --- a/scripts/dtc/dtc.h
> +++ b/scripts/dtc/dtc.h
> @@ -168,6 +168,8 @@ struct node {
>
> struct label *labels;
> const struct bus_type *bus;
> +
> + bool omit_if_unused, is_referenced;
> };
>
> #define for_each_label_withdel(l0, l) \
> @@ -202,6 +204,8 @@ struct property *reverse_properties(struct property *first);
> struct node *build_node(struct property *proplist, struct node *children);
> struct node *build_node_delete(void);
> struct node *name_node(struct node *node, char *name);
> +struct node *omit_node_if_unused(struct node *node);
> +struct node *reference_node(struct node *node);
> struct node *chain_node(struct node *first, struct node *list);
> struct node *merge_nodes(struct node *old_node, struct node *new_node);
> struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
> diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
> index 57b7db2ed1..81b6c48454 100644
> --- a/scripts/dtc/livetree.c
> +++ b/scripts/dtc/livetree.c
> @@ -134,6 +134,20 @@ struct node *name_node(struct node *node, char *name)
> return node;
> }
>
> +struct node *omit_node_if_unused(struct node *node)
> +{
> + node->omit_if_unused = 1;
> +
> + return node;
> +}
> +
> +struct node *reference_node(struct node *node)
> +{
> + node->is_referenced = 1;
> +
> + return node;
> +}
> +
> struct node *merge_nodes(struct node *old_node, struct node *new_node)
> {
> struct property *new_prop, *old_prop;
OK, what does this flag _do_ ? I've not been able to make it discard
anything in some tests where I scatter it all over dts files. Is there
some other flag we also need to pass to dtc to have this be used? I
would like to explore this option to help with platforms like tbs2910
(rather than if we can the patch Anatolij did) if we can. Thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20200125/f588f671/attachment.sig>
More information about the U-Boot
mailing list