diff options
author | Andres Salomon <dilinger@queued.net> | 2010-10-10 23:49:45 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-10-12 23:57:53 -0400 |
commit | f90c34bd658d240cb5ebc5fe0a17796e590c6ec8 (patch) | |
tree | 02e8243910e156d3af4a14bd9be63dd829d07576 /drivers/of | |
parent | 3cfc535c5df8122af1258ae05aaf2770c033425d (diff) |
of/promtree: no longer call prom_ functions directly; use an ops structure
Rather than assuming an architecture defines prom_getchild and friends,
define an ops struct with hooks for the various prom functions that
pdt.c needs. This ops struct is filled in by the
arch-(and sometimes firmware-)specific code, and passed to
of_pdt_build_devicetree.
Update sparc code to define the ops struct as well.
Signed-off-by: Andres Salomon <dilinger@queued.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/pdt.c | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 2fdb1b478d6f..fd02fc1dd891 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c | |||
@@ -23,7 +23,8 @@ | |||
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_pdt.h> | 24 | #include <linux/of_pdt.h> |
25 | #include <asm/prom.h> | 25 | #include <asm/prom.h> |
26 | #include <asm/oplib.h> | 26 | |
27 | static struct of_pdt_ops *of_pdt_prom_ops __initdata; | ||
27 | 28 | ||
28 | void __initdata (*prom_build_more)(struct device_node *dp, | 29 | void __initdata (*prom_build_more)(struct device_node *dp, |
29 | struct device_node ***nextp); | 30 | struct device_node ***nextp); |
@@ -59,7 +60,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, | |||
59 | { | 60 | { |
60 | static struct property *tmp = NULL; | 61 | static struct property *tmp = NULL; |
61 | struct property *p; | 62 | struct property *p; |
62 | const char *name; | 63 | int err; |
63 | 64 | ||
64 | if (tmp) { | 65 | if (tmp) { |
65 | p = tmp; | 66 | p = tmp; |
@@ -77,28 +78,20 @@ static struct property * __init build_one_prop(phandle node, char *prev, | |||
77 | p->value = prom_early_alloc(special_len); | 78 | p->value = prom_early_alloc(special_len); |
78 | memcpy(p->value, special_val, special_len); | 79 | memcpy(p->value, special_val, special_len); |
79 | } else { | 80 | } else { |
80 | if (prev == NULL) { | 81 | err = of_pdt_prom_ops->nextprop(node, prev, p->name); |
81 | name = prom_firstprop(node, p->name); | 82 | if (err) { |
82 | } else { | ||
83 | name = prom_nextprop(node, prev, p->name); | ||
84 | } | ||
85 | |||
86 | if (!name || strlen(name) == 0) { | ||
87 | tmp = p; | 83 | tmp = p; |
88 | return NULL; | 84 | return NULL; |
89 | } | 85 | } |
90 | #ifdef CONFIG_SPARC32 | 86 | p->length = of_pdt_prom_ops->getproplen(node, p->name); |
91 | strcpy(p->name, name); | ||
92 | #endif | ||
93 | p->length = prom_getproplen(node, p->name); | ||
94 | if (p->length <= 0) { | 87 | if (p->length <= 0) { |
95 | p->length = 0; | 88 | p->length = 0; |
96 | } else { | 89 | } else { |
97 | int len; | 90 | int len; |
98 | 91 | ||
99 | p->value = prom_early_alloc(p->length + 1); | 92 | p->value = prom_early_alloc(p->length + 1); |
100 | len = prom_getproperty(node, p->name, p->value, | 93 | len = of_pdt_prom_ops->getproperty(node, p->name, |
101 | p->length); | 94 | p->value, p->length); |
102 | if (len <= 0) | 95 | if (len <= 0) |
103 | p->length = 0; | 96 | p->length = 0; |
104 | ((unsigned char *)p->value)[p->length] = '\0'; | 97 | ((unsigned char *)p->value)[p->length] = '\0'; |
@@ -130,10 +123,10 @@ static char * __init get_one_property(phandle node, const char *name) | |||
130 | char *buf = "<NULL>"; | 123 | char *buf = "<NULL>"; |
131 | int len; | 124 | int len; |
132 | 125 | ||
133 | len = prom_getproplen(node, name); | 126 | len = of_pdt_prom_ops->getproplen(node, name); |
134 | if (len > 0) { | 127 | if (len > 0) { |
135 | buf = prom_early_alloc(len); | 128 | buf = prom_early_alloc(len); |
136 | len = prom_getproperty(node, name, buf, len); | 129 | len = of_pdt_prom_ops->getproperty(node, name, buf, len); |
137 | } | 130 | } |
138 | 131 | ||
139 | return buf; | 132 | return buf; |
@@ -211,21 +204,25 @@ static struct device_node * __init prom_build_tree(struct device_node *parent, | |||
211 | #endif | 204 | #endif |
212 | dp->full_name = build_full_name(dp); | 205 | dp->full_name = build_full_name(dp); |
213 | 206 | ||
214 | dp->child = prom_build_tree(dp, prom_getchild(node), nextp); | 207 | dp->child = prom_build_tree(dp, |
208 | of_pdt_prom_ops->getchild(node), nextp); | ||
215 | 209 | ||
216 | if (prom_build_more) | 210 | if (prom_build_more) |
217 | prom_build_more(dp, nextp); | 211 | prom_build_more(dp, nextp); |
218 | 212 | ||
219 | node = prom_getsibling(node); | 213 | node = of_pdt_prom_ops->getsibling(node); |
220 | } | 214 | } |
221 | 215 | ||
222 | return ret; | 216 | return ret; |
223 | } | 217 | } |
224 | 218 | ||
225 | void __init of_pdt_build_devicetree(phandle root_node) | 219 | void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) |
226 | { | 220 | { |
227 | struct device_node **nextp; | 221 | struct device_node **nextp; |
228 | 222 | ||
223 | BUG_ON(!ops); | ||
224 | of_pdt_prom_ops = ops; | ||
225 | |||
229 | allnodes = prom_create_node(root_node, NULL); | 226 | allnodes = prom_create_node(root_node, NULL); |
230 | #if defined(CONFIG_SPARC) | 227 | #if defined(CONFIG_SPARC) |
231 | allnodes->path_component_name = ""; | 228 | allnodes->path_component_name = ""; |
@@ -234,6 +231,5 @@ void __init of_pdt_build_devicetree(phandle root_node) | |||
234 | 231 | ||
235 | nextp = &allnodes->allnext; | 232 | nextp = &allnodes->allnext; |
236 | allnodes->child = prom_build_tree(allnodes, | 233 | allnodes->child = prom_build_tree(allnodes, |
237 | prom_getchild(allnodes->phandle), | 234 | of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); |
238 | &nextp); | ||
239 | } | 235 | } |