phandle = get_node_phandle(dt, refnode);
*((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
+
+ reference_node(refnode);
}
}
}
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
*/
&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,
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);
%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
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;
}
;
{
$$ = name_node(build_node_delete(), $2);
}
+ | DT_OMIT_NO_REF subnode
+ {
+ $$ = omit_node_if_unused($2);
+ }
| DT_LABEL subnode
{
add_label(&$2->labels, $1);
struct label *labels;
const struct bus_type *bus;
+
+ bool omit_if_unused, is_referenced;
};
#define for_each_label_withdel(l0, l) \
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);
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;