On Tue, Jan 21, 2020 at 10:23:17AM +0000, Andre Przywara wrote: > From: Maxime Ripard <maxime.rip...@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.rip...@bootlin.com> > Reviewed-by: Rob Herring <r...@kernel.org> > Signed-off-by: Andre Przywara <andre.przyw...@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
signature.asc
Description: PGP signature