aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/pdt.c
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@queued.net>2010-10-10 23:49:45 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-10-12 23:57:53 -0400
commitf90c34bd658d240cb5ebc5fe0a17796e590c6ec8 (patch)
tree02e8243910e156d3af4a14bd9be63dd829d07576 /drivers/of/pdt.c
parent3cfc535c5df8122af1258ae05aaf2770c033425d (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/pdt.c')
-rw-r--r--drivers/of/pdt.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c
index 2fdb1b478d6..fd02fc1dd89 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
27static struct of_pdt_ops *of_pdt_prom_ops __initdata;
27 28
28void __initdata (*prom_build_more)(struct device_node *dp, 29void __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
225void __init of_pdt_build_devicetree(phandle root_node) 219void __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}