diff options
Diffstat (limited to 'drivers/of/pdt.c')
| -rw-r--r-- | drivers/of/pdt.c | 89 |
1 files changed, 24 insertions, 65 deletions
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 4ec19cbee57f..cb0cb374b21f 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* pdt.c: OF PROM device tree support code. * * Paul Mackerras August 1996. @@ -8,11 +9,6 @@ * * Adapted for sparc by David S. Miller davem@davemloft.net * Adapted for multiple architectures by Andres Salomon <dilinger@queued.net> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #include <linux/kernel.h> @@ -22,12 +18,10 @@ #include <linux/slab.h> #include <linux/of.h> #include <linux/of_pdt.h> -#include <asm/prom.h> -static struct of_pdt_ops *of_pdt_prom_ops __initdata; +#include "of_private.h" -void __initdata (*of_pdt_build_more)(struct device_node *dp, - struct device_node ***nextp); +static struct of_pdt_ops *of_pdt_prom_ops __initdata; #if defined(CONFIG_SPARC) unsigned int of_pdt_unique_id __initdata; @@ -38,24 +32,7 @@ unsigned int of_pdt_unique_id __initdata; static char * __init of_pdt_build_full_name(struct device_node *dp) { - int len, ourlen, plen; - char *n; - - dp->path_component_name = build_path_component(dp); - - plen = strlen(dp->parent->full_name); - ourlen = strlen(dp->path_component_name); - len = ourlen + plen + 2; - - n = prom_early_alloc(len); - strcpy(n, dp->parent->full_name); - if (!of_node_is_root(dp->parent)) { - strcpy(n + plen, "/"); - plen++; - } - strcpy(n + plen, dp->path_component_name); - - return n; + return build_path_component(dp); } #else /* CONFIG_SPARC */ @@ -66,23 +43,21 @@ static inline void irq_trans_init(struct device_node *dp) { } static char * __init of_pdt_build_full_name(struct device_node *dp) { static int failsafe_id = 0; /* for generating unique names on failure */ + const char *name; + char path[256]; char *buf; int len; - if (of_pdt_prom_ops->pkg2path(dp->phandle, NULL, 0, &len)) - goto failsafe; - - buf = prom_early_alloc(len + 1); - if (of_pdt_prom_ops->pkg2path(dp->phandle, buf, len, &len)) - goto failsafe; - return buf; + if (!of_pdt_prom_ops->pkg2path(dp->phandle, path, sizeof(path), &len)) { + name = kbasename(path); + buf = prom_early_alloc(strlen(name) + 1); + strcpy(buf, name); + return buf; + } - failsafe: - buf = prom_early_alloc(strlen(dp->parent->full_name) + - strlen(dp->name) + 16); - sprintf(buf, "%s/%s@unknown%i", - of_node_is_root(dp->parent) ? "" : dp->parent->full_name, - dp->name, failsafe_id++); + name = of_get_property(dp, "name", &len); + buf = prom_early_alloc(len + 16); + sprintf(buf, "%s@unknown%i", name, failsafe_id++); pr_err("%s: pkg2path failed; assigning %s\n", __func__, buf); return buf; } @@ -177,25 +152,24 @@ static struct device_node * __init of_pdt_create_node(phandle node, return NULL; dp = prom_early_alloc(sizeof(*dp)); + of_node_init(dp); of_pdt_incr_unique_id(dp); dp->parent = parent; - kref_init(&dp->kref); - dp->name = of_pdt_get_one_property(node, "name"); - dp->type = of_pdt_get_one_property(node, "device_type"); dp->phandle = node; dp->properties = of_pdt_build_prop_list(node); + dp->full_name = of_pdt_build_full_name(dp); + irq_trans_init(dp); return dp; } static struct device_node * __init of_pdt_build_tree(struct device_node *parent, - phandle node, - struct device_node ***nextp) + phandle node) { struct device_node *ret = NULL, *prev_sibling = NULL; struct device_node *dp; @@ -212,16 +186,7 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent, ret = dp; prev_sibling = dp; - *(*nextp) = dp; - *nextp = &dp->allnext; - - dp->full_name = of_pdt_build_full_name(dp); - - dp->child = of_pdt_build_tree(dp, - of_pdt_prom_ops->getchild(node), nextp); - - if (of_pdt_build_more) - of_pdt_build_more(dp, nextp); + dp->child = of_pdt_build_tree(dp, of_pdt_prom_ops->getchild(node)); node = of_pdt_prom_ops->getsibling(node); } @@ -236,20 +201,14 @@ static void * __init kernel_tree_alloc(u64 size, u64 align) void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) { - struct device_node **nextp; - BUG_ON(!ops); of_pdt_prom_ops = ops; - of_allnodes = of_pdt_create_node(root_node, NULL); -#if defined(CONFIG_SPARC) - of_allnodes->path_component_name = ""; -#endif - of_allnodes->full_name = "/"; + of_root = of_pdt_create_node(root_node, NULL); + of_root->full_name = "/"; - nextp = &of_allnodes->allnext; - of_allnodes->child = of_pdt_build_tree(of_allnodes, - of_pdt_prom_ops->getchild(of_allnodes->phandle), &nextp); + of_root->child = of_pdt_build_tree(of_root, + of_pdt_prom_ops->getchild(of_root->phandle)); /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */ of_alias_scan(kernel_tree_alloc); |
