diff options
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r-- | drivers/of/fdt.c | 91 |
1 files changed, 30 insertions, 61 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index ce30c9a588a4..4675e5ac4d11 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -132,6 +132,19 @@ bool of_fdt_is_big_endian(const void *blob, unsigned long node) return false; } +static bool of_fdt_device_is_available(const void *blob, unsigned long node) +{ + const char *status = fdt_getprop(blob, node, "status", NULL); + + if (!status) + return true; + + if (!strcmp(status, "ok") || !strcmp(status, "okay")) + return true; + + return false; +} + /** * of_fdt_match - Return true if node matches a list of compatible values */ @@ -266,74 +279,32 @@ static void populate_properties(const void *blob, *pprev = NULL; } -static unsigned int populate_node(const void *blob, - int offset, - void **mem, - struct device_node *dad, - unsigned int fpsize, - struct device_node **pnp, - bool dryrun) +static bool populate_node(const void *blob, + int offset, + void **mem, + struct device_node *dad, + struct device_node **pnp, + bool dryrun) { struct device_node *np; const char *pathp; unsigned int l, allocl; - int new_format = 0; pathp = fdt_get_name(blob, offset, &l); if (!pathp) { *pnp = NULL; - return 0; + return false; } allocl = ++l; - /* version 0x10 has a more compact unit name here instead of the full - * path. we accumulate the full path size using "fpsize", we'll rebuild - * it later. We detect this because the first character of the name is - * not '/'. - */ - if ((*pathp) != '/') { - new_format = 1; - if (fpsize == 0) { - /* root node: special case. fpsize accounts for path - * plus terminating zero. root node only has '/', so - * fpsize should be 2, but we want to avoid the first - * level nodes to have two '/' so we use fpsize 1 here - */ - fpsize = 1; - allocl = 2; - l = 1; - pathp = ""; - } else { - /* account for '/' and path size minus terminal 0 - * already in 'l' - */ - fpsize += l; - allocl = fpsize; - } - } - np = unflatten_dt_alloc(mem, sizeof(struct device_node) + allocl, __alignof__(struct device_node)); if (!dryrun) { char *fn; of_node_init(np); np->full_name = fn = ((char *)np) + sizeof(*np); - if (new_format) { - /* rebuild full path for new format */ - if (dad && dad->parent) { - strcpy(fn, dad->full_name); -#ifdef DEBUG - if ((strlen(fn) + l + 1) != allocl) { - pr_debug("%s: p: %d, l: %d, a: %d\n", - pathp, (int)strlen(fn), - l, allocl); - } -#endif - fn += strlen(fn); - } - *(fn++) = '/'; - } + memcpy(fn, pathp, l); if (dad != NULL) { @@ -355,7 +326,7 @@ static unsigned int populate_node(const void *blob, } *pnp = np; - return fpsize; + return true; } static void reverse_nodes(struct device_node *parent) @@ -399,7 +370,6 @@ static int unflatten_dt_nodes(const void *blob, struct device_node *root; int offset = 0, depth = 0, initial_depth = 0; #define FDT_MAX_DEPTH 64 - unsigned int fpsizes[FDT_MAX_DEPTH]; struct device_node *nps[FDT_MAX_DEPTH]; void *base = mem; bool dryrun = !base; @@ -418,7 +388,6 @@ static int unflatten_dt_nodes(const void *blob, depth = initial_depth = 1; root = dad; - fpsizes[depth] = dad ? strlen(of_node_full_name(dad)) : 0; nps[depth] = dad; for (offset = 0; @@ -427,11 +396,12 @@ static int unflatten_dt_nodes(const void *blob, if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH)) continue; - fpsizes[depth+1] = populate_node(blob, offset, &mem, - nps[depth], - fpsizes[depth], - &nps[depth+1], dryrun); - if (!fpsizes[depth+1]) + if (!IS_ENABLED(CONFIG_OF_KOBJ) && + !of_fdt_device_is_available(blob, offset)) + continue; + + if (!populate_node(blob, offset, &mem, nps[depth], + &nps[depth+1], dryrun)) return mem - base; if (!dryrun && nodepp && !*nodepp) @@ -467,6 +437,7 @@ static int unflatten_dt_nodes(const void *blob, * @mynodes: The device_node tree created by the call * @dt_alloc: An allocator that provides a virtual address to memory * for the resulting tree + * @detached: if true set OF_DETACHED on @mynodes * * Returns NULL on failure or the memory chunk containing the unflattened * device tree on success. @@ -652,7 +623,6 @@ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname, int depth, void *data) { static int found; - const char *status; int err; if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) { @@ -672,8 +642,7 @@ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname, return 1; } - status = of_get_flat_dt_prop(node, "status", NULL); - if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0) + if (!of_fdt_device_is_available(initial_boot_params, node)) return 0; err = __reserved_mem_reserve_reg(node, uname); |