diff options
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r-- | drivers/of/fdt.c | 76 |
1 files changed, 43 insertions, 33 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index dcc1dd96911a..ba17a80b8c79 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -205,7 +205,7 @@ static void populate_properties(const void *blob, *pprev = NULL; } -static bool populate_node(const void *blob, +static int populate_node(const void *blob, int offset, void **mem, struct device_node *dad, @@ -214,24 +214,24 @@ static bool populate_node(const void *blob, { struct device_node *np; const char *pathp; - unsigned int l, allocl; + int len; - pathp = fdt_get_name(blob, offset, &l); + pathp = fdt_get_name(blob, offset, &len); if (!pathp) { *pnp = NULL; - return false; + return len; } - allocl = ++l; + len++; - np = unflatten_dt_alloc(mem, sizeof(struct device_node) + allocl, + np = unflatten_dt_alloc(mem, sizeof(struct device_node) + len, __alignof__(struct device_node)); if (!dryrun) { char *fn; of_node_init(np); np->full_name = fn = ((char *)np) + sizeof(*np); - memcpy(fn, pathp, l); + memcpy(fn, pathp, len); if (dad != NULL) { np->parent = dad; @@ -282,7 +282,7 @@ static void reverse_nodes(struct device_node *parent) * @dad: Parent struct device_node * @nodepp: The device_node tree created by the call * - * It returns the size of unflattened device tree or error code + * Return: The size of unflattened device tree or error code */ static int unflatten_dt_nodes(const void *blob, void *mem, @@ -295,6 +295,7 @@ static int unflatten_dt_nodes(const void *blob, struct device_node *nps[FDT_MAX_DEPTH]; void *base = mem; bool dryrun = !base; + int ret; if (nodepp) *nodepp = NULL; @@ -322,9 +323,10 @@ static int unflatten_dt_nodes(const void *blob, !of_fdt_device_is_available(blob, offset)) continue; - if (!populate_node(blob, offset, &mem, nps[depth], - &nps[depth+1], dryrun)) - return mem - base; + ret = populate_node(blob, offset, &mem, nps[depth], + &nps[depth+1], dryrun); + if (ret < 0) + return ret; if (!dryrun && nodepp && !*nodepp) *nodepp = nps[depth+1]; @@ -349,11 +351,6 @@ static int unflatten_dt_nodes(const void *blob, /** * __unflatten_device_tree - create tree of device_nodes from flat blob - * - * unflattens a device-tree, creating the - * tree of struct device_node. It also fills the "name" and "type" - * pointers of the nodes so the normal device-tree walking functions - * can be used. * @blob: The blob to expand * @dad: Parent device node * @mynodes: The device_node tree created by the call @@ -361,7 +358,11 @@ static int unflatten_dt_nodes(const void *blob, * for the resulting tree * @detached: if true set OF_DETACHED on @mynodes * - * Returns NULL on failure or the memory chunk containing the unflattened + * unflattens a device-tree, creating the tree of struct device_node. It also + * fills the "name" and "type" pointers of the nodes so the normal device-tree + * walking functions can be used. + * + * Return: NULL on failure or the memory chunk containing the unflattened * device tree on success. */ void *__unflatten_device_tree(const void *blob, @@ -372,6 +373,10 @@ void *__unflatten_device_tree(const void *blob, { int size; void *mem; + int ret; + + if (mynodes) + *mynodes = NULL; pr_debug(" -> unflatten_device_tree()\n"); @@ -392,7 +397,7 @@ void *__unflatten_device_tree(const void *blob, /* First pass, scan for size */ size = unflatten_dt_nodes(blob, NULL, dad, NULL); - if (size < 0) + if (size <= 0) return NULL; size = ALIGN(size, 4); @@ -410,12 +415,16 @@ void *__unflatten_device_tree(const void *blob, pr_debug(" unflattening %p...\n", mem); /* Second pass, do actual unflattening */ - unflatten_dt_nodes(blob, mem, dad, mynodes); + ret = unflatten_dt_nodes(blob, mem, dad, mynodes); + if (be32_to_cpup(mem + size) != 0xdeadbeef) pr_warn("End of tree marker overwritten: %08x\n", be32_to_cpup(mem + size)); - if (detached && mynodes) { + if (ret <= 0) + return NULL; + + if (detached && mynodes && *mynodes) { of_node_set_flag(*mynodes, OF_DETACHED); pr_debug("unflattened tree is detached\n"); } @@ -442,7 +451,7 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex); * pointers of the nodes so the normal device-tree walking functions * can be used. * - * Returns NULL on failure or the memory chunk containing the unflattened + * Return: NULL on failure or the memory chunk containing the unflattened * device tree on success. */ void *of_fdt_unflatten_tree(const unsigned long *blob, @@ -470,7 +479,7 @@ void *initial_boot_params __ro_after_init; static u32 of_fdt_crc32; -/** +/* * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property */ static int __init __reserved_mem_reserve_reg(unsigned long node, @@ -516,7 +525,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, return 0; } -/** +/* * __reserved_mem_check_root() - check if #size-cells, #address-cells provided * in /reserved-memory matches the values supported by the current implementation, * also check if ranges property has been provided @@ -539,8 +548,8 @@ static int __init __reserved_mem_check_root(unsigned long node) return 0; } -/** - * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory +/* + * __fdt_scan_reserved_mem() - scan a single FDT node for reserved memory */ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname, int depth, void *data) @@ -650,6 +659,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, /** * of_scan_flat_dt_subnodes - scan sub-nodes of a node call callback on each. + * @parent: parent node * @it: callback function * @data: context data pointer * @@ -689,7 +699,7 @@ int __init of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname) return fdt_subnode_offset(initial_boot_params, node, uname); } -/** +/* * of_get_flat_dt_root - find the root node in the flat blob */ unsigned long __init of_get_flat_dt_root(void) @@ -697,7 +707,7 @@ unsigned long __init of_get_flat_dt_root(void) return 0; } -/** +/* * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr * * This function can be used within scan_flattened_dt callback to get @@ -716,7 +726,7 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name, * @node: node to test * @compat: compatible string to compare with compatible list. * - * On match, returns a non-zero value with smaller values returned for more + * Return: a non-zero value on match with smaller values returned for more * specific compatible values. */ static int of_fdt_is_compatible(const void *blob, @@ -751,7 +761,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) return of_fdt_is_compatible(initial_boot_params, node, compat); } -/** +/* * of_flat_dt_match - Return true if node matches a list of compatible values */ static int __init of_flat_dt_match(unsigned long node, const char *const *compat) @@ -771,8 +781,8 @@ static int __init of_flat_dt_match(unsigned long node, const char *const *compat return score; } -/** - * of_get_flat_dt_prop - Given a node in the flat blob, return the phandle +/* + * of_get_flat_dt_phandle - Given a node in the flat blob, return the phandle */ uint32_t __init of_get_flat_dt_phandle(unsigned long node) { @@ -947,7 +957,7 @@ int __init early_init_dt_scan_chosen_stdout(void) } #endif -/** +/* * early_init_dt_scan_root - fetch the top level address and size cells */ int __init early_init_dt_scan_root(unsigned long node, const char *uname, @@ -983,7 +993,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp) return of_read_number(p, s); } -/** +/* * early_init_dt_scan_memory - Look for and parse memory nodes */ int __init early_init_dt_scan_memory(unsigned long node, const char *uname, |