diff options
-rw-r--r-- | scripts/dtc/checks.c | 13 | ||||
-rw-r--r-- | scripts/dtc/dtc-lexer.l | 7 | ||||
-rw-r--r-- | scripts/dtc/dtc-parser.y | 17 | ||||
-rw-r--r-- | scripts/dtc/dtc.h | 4 | ||||
-rw-r--r-- | scripts/dtc/livetree.c | 14 |
5 files changed, 55 insertions, 0 deletions
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 24af549977..d3694d6cf2 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -152,6 +152,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 @@ -219,6 +220,18 @@ devicetree: $$ = $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; + } ; nodedef: @@ -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; |