diff options
Diffstat (limited to 'scripts/dtc/livetree.c')
-rw-r--r-- | scripts/dtc/livetree.c | 103 |
1 files changed, 72 insertions, 31 deletions
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index 032df5878ccc..49f723002f85 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -36,27 +36,27 @@ void delete_labels(struct label **labels) label->deleted = 1; } -struct property *build_property(char *name, struct data val, +struct property *build_property(const char *name, struct data val, struct srcpos *srcpos) { struct property *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); - new->name = name; + new->name = xstrdup(name); new->val = val; new->srcpos = srcpos_copy(srcpos); return new; } -struct property *build_property_delete(char *name) +struct property *build_property_delete(const char *name) { struct property *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); - new->name = name; + new->name = xstrdup(name); new->deleted = 1; return new; @@ -116,11 +116,11 @@ struct node *build_node_delete(struct srcpos *srcpos) return new; } -struct node *name_node(struct node *node, char *name) +struct node *name_node(struct node *node, const char *name) { assert(node->name == NULL); - node->name = name; + node->name = xstrdup(name); return node; } @@ -250,6 +250,7 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) name_node(new_node, "__overlay__"); node = build_node(p, new_node, NULL); name_node(node, name); + free(name); add_child(dt, node); return dt; @@ -438,9 +439,9 @@ cell_t propval_cell(struct property *prop) return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); } -cell_t propval_cell_n(struct property *prop, int n) +cell_t propval_cell_n(struct property *prop, unsigned int n) { - assert(prop->val.len / sizeof(cell_t) >= n); + assert(prop->val.len / sizeof(cell_t) > n); return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); } @@ -526,7 +527,7 @@ struct node *get_node_by_path(struct node *tree, const char *path) p = strchr(path, '/'); for_each_child(tree, child) { - if (p && strprefixeq(path, p - path, child->name)) + if (p && strprefixeq(path, (size_t)(p - path), child->name)) return get_node_by_path(child, p+1); else if (!p && streq(path, child->name)) return child; @@ -559,7 +560,7 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) { struct node *child, *node; - if ((phandle == 0) || (phandle == -1)) { + if (!phandle_is_valid(phandle)) { assert(generate_fixups); return NULL; } @@ -581,20 +582,62 @@ 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 *target = tree; + const char *label = NULL, *path = NULL; + if (streq(ref, "/")) return tree; - else if (ref[0] == '/') - return get_node_by_path(tree, ref); + + if (ref[0] == '/') + path = ref; else - return get_node_by_label(tree, ref); + label = ref; + + if (label) { + const char *slash = strchr(label, '/'); + char *buf = NULL; + + if (slash) { + buf = xstrndup(label, slash - label); + label = buf; + path = slash + 1; + } + + target = get_node_by_label(tree, label); + + free(buf); + + if (!target) + return NULL; + } + + if (path) + target = get_node_by_path(target, path); + + return target; +} + +static void add_phandle_property(struct node *node, + const char *name, int format) +{ + struct data d; + + if (!(phandle_format & format)) + return; + if (get_property(node, name)) + return; + + d = data_add_marker(empty_data, TYPE_UINT32, NULL); + d = data_append_cell(d, node->phandle); + + add_property(node, build_property(name, d, NULL)); } cell_t get_node_phandle(struct node *root, struct node *node) { static cell_t phandle = 1; /* FIXME: ick, static local */ - struct data d = empty_data; - if ((node->phandle != 0) && (node->phandle != -1)) + if (phandle_is_valid(node->phandle)) return node->phandle; while (get_node_by_phandle(root, phandle)) @@ -602,16 +645,8 @@ cell_t get_node_phandle(struct node *root, struct node *node) node->phandle = phandle; - d = data_add_marker(d, TYPE_UINT32, NULL); - d = data_append_cell(d, phandle); - - if (!get_property(node, "linux,phandle") - && (phandle_format & PHANDLE_LEGACY)) - add_property(node, build_property("linux,phandle", d, NULL)); - - if (!get_property(node, "phandle") - && (phandle_format & PHANDLE_EPAPR)) - add_property(node, build_property("phandle", d, NULL)); + add_phandle_property(node, "linux,phandle", PHANDLE_LEGACY); + add_phandle_property(node, "phandle", PHANDLE_EPAPR); /* If the node *does* have a phandle property, we must * be dealing with a self-referencing phandle, which will be @@ -781,18 +816,18 @@ void sort_tree(struct dt_info *dti) } /* utility helper to avoid code duplication */ -static struct node *build_and_name_child_node(struct node *parent, char *name) +static struct node *build_and_name_child_node(struct node *parent, const char *name) { struct node *node; node = build_node(NULL, NULL, NULL); - name_node(node, xstrdup(name)); + name_node(node, name); add_child(parent, node); return node; } -static struct node *build_root_node(struct node *dt, char *name) +static struct node *build_root_node(struct node *dt, const char *name) { struct node *an; @@ -892,6 +927,12 @@ static void add_fixup_entry(struct dt_info *dti, struct node *fn, /* m->ref can only be a REF_PHANDLE, but check anyway */ assert(m->type == REF_PHANDLE); + /* The format only permits fixups for references to label, not + * references to path */ + if (strchr(m->ref, '/')) + die("Can't generate fixup for reference to path &{%s}\n", + m->ref); + /* there shouldn't be any ':' in the arguments */ if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) die("arguments should not contain ':'\n"); @@ -1007,7 +1048,7 @@ static void generate_local_fixups_tree_internal(struct dt_info *dti, generate_local_fixups_tree_internal(dti, lfn, c); } -void generate_label_tree(struct dt_info *dti, char *name, bool allocph) +void generate_label_tree(struct dt_info *dti, const char *name, bool allocph) { if (!any_label_tree(dti, dti->dt)) return; @@ -1015,7 +1056,7 @@ void generate_label_tree(struct dt_info *dti, char *name, bool allocph) dti->dt, allocph); } -void generate_fixups_tree(struct dt_info *dti, char *name) +void generate_fixups_tree(struct dt_info *dti, const char *name) { if (!any_fixup_tree(dti, dti->dt)) return; @@ -1023,7 +1064,7 @@ void generate_fixups_tree(struct dt_info *dti, char *name) dti->dt); } -void generate_local_fixups_tree(struct dt_info *dti, char *name) +void generate_local_fixups_tree(struct dt_info *dti, const char *name) { if (!any_local_fixup_tree(dti, dti->dt)) return; |