aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2009-11-23 22:07:00 -0500
committerGrant Likely <grant.likely@secretlab.ca>2009-11-23 22:07:00 -0500
commitbbd33931a08362f78266a4016211a35947b91041 (patch)
tree6cc38aa6f43c8db7737915ee854e42e1e4f71533 /arch/powerpc/kernel
parent00e38efd90f27518ec96b37b1c7773e3ac529966 (diff)
of/flattree: Merge unflatten_dt_node
Merge common code between PowerPC and MicroBlaze Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Reviewed-by: Wolfram Sang <w.sang@pengutronix.de> Tested-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/prom.c194
1 files changed, 0 insertions, 194 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 413e608863dd..a102a0a33ed1 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -80,200 +80,6 @@ extern rwlock_t devtree_lock; /* temporary while merging */
80/* export that to outside world */ 80/* export that to outside world */
81struct device_node *of_chosen; 81struct device_node *of_chosen;
82 82
83static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
84 unsigned long align)
85{
86 void *res;
87
88 *mem = _ALIGN(*mem, align);
89 res = (void *)*mem;
90 *mem += size;
91
92 return res;
93}
94
95static unsigned long __init unflatten_dt_node(unsigned long mem,
96 unsigned long *p,
97 struct device_node *dad,
98 struct device_node ***allnextpp,
99 unsigned long fpsize)
100{
101 struct device_node *np;
102 struct property *pp, **prev_pp = NULL;
103 char *pathp;
104 u32 tag;
105 unsigned int l, allocl;
106 int has_name = 0;
107 int new_format = 0;
108
109 tag = *((u32 *)(*p));
110 if (tag != OF_DT_BEGIN_NODE) {
111 printk("Weird tag at start of node: %x\n", tag);
112 return mem;
113 }
114 *p += 4;
115 pathp = (char *)*p;
116 l = allocl = strlen(pathp) + 1;
117 *p = _ALIGN(*p + l, 4);
118
119 /* version 0x10 has a more compact unit name here instead of the full
120 * path. we accumulate the full path size using "fpsize", we'll rebuild
121 * it later. We detect this because the first character of the name is
122 * not '/'.
123 */
124 if ((*pathp) != '/') {
125 new_format = 1;
126 if (fpsize == 0) {
127 /* root node: special case. fpsize accounts for path
128 * plus terminating zero. root node only has '/', so
129 * fpsize should be 2, but we want to avoid the first
130 * level nodes to have two '/' so we use fpsize 1 here
131 */
132 fpsize = 1;
133 allocl = 2;
134 } else {
135 /* account for '/' and path size minus terminal 0
136 * already in 'l'
137 */
138 fpsize += l;
139 allocl = fpsize;
140 }
141 }
142
143
144 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
145 __alignof__(struct device_node));
146 if (allnextpp) {
147 memset(np, 0, sizeof(*np));
148 np->full_name = ((char*)np) + sizeof(struct device_node);
149 if (new_format) {
150 char *p = np->full_name;
151 /* rebuild full path for new format */
152 if (dad && dad->parent) {
153 strcpy(p, dad->full_name);
154#ifdef DEBUG
155 if ((strlen(p) + l + 1) != allocl) {
156 DBG("%s: p: %d, l: %d, a: %d\n",
157 pathp, (int)strlen(p), l, allocl);
158 }
159#endif
160 p += strlen(p);
161 }
162 *(p++) = '/';
163 memcpy(p, pathp, l);
164 } else
165 memcpy(np->full_name, pathp, l);
166 prev_pp = &np->properties;
167 **allnextpp = np;
168 *allnextpp = &np->allnext;
169 if (dad != NULL) {
170 np->parent = dad;
171 /* we temporarily use the next field as `last_child'*/
172 if (dad->next == 0)
173 dad->child = np;
174 else
175 dad->next->sibling = np;
176 dad->next = np;
177 }
178 kref_init(&np->kref);
179 }
180 while(1) {
181 u32 sz, noff;
182 char *pname;
183
184 tag = *((u32 *)(*p));
185 if (tag == OF_DT_NOP) {
186 *p += 4;
187 continue;
188 }
189 if (tag != OF_DT_PROP)
190 break;
191 *p += 4;
192 sz = *((u32 *)(*p));
193 noff = *((u32 *)((*p) + 4));
194 *p += 8;
195 if (initial_boot_params->version < 0x10)
196 *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
197
198 pname = find_flat_dt_string(noff);
199 if (pname == NULL) {
200 printk("Can't find property name in list !\n");
201 break;
202 }
203 if (strcmp(pname, "name") == 0)
204 has_name = 1;
205 l = strlen(pname) + 1;
206 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
207 __alignof__(struct property));
208 if (allnextpp) {
209 if (strcmp(pname, "linux,phandle") == 0) {
210 np->node = *((u32 *)*p);
211 if (np->linux_phandle == 0)
212 np->linux_phandle = np->node;
213 }
214 if (strcmp(pname, "ibm,phandle") == 0)
215 np->linux_phandle = *((u32 *)*p);
216 pp->name = pname;
217 pp->length = sz;
218 pp->value = (void *)*p;
219 *prev_pp = pp;
220 prev_pp = &pp->next;
221 }
222 *p = _ALIGN((*p) + sz, 4);
223 }
224 /* with version 0x10 we may not have the name property, recreate
225 * it here from the unit name if absent
226 */
227 if (!has_name) {
228 char *p = pathp, *ps = pathp, *pa = NULL;
229 int sz;
230
231 while (*p) {
232 if ((*p) == '@')
233 pa = p;
234 if ((*p) == '/')
235 ps = p + 1;
236 p++;
237 }
238 if (pa < ps)
239 pa = p;
240 sz = (pa - ps) + 1;
241 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
242 __alignof__(struct property));
243 if (allnextpp) {
244 pp->name = "name";
245 pp->length = sz;
246 pp->value = pp + 1;
247 *prev_pp = pp;
248 prev_pp = &pp->next;
249 memcpy(pp->value, ps, sz - 1);
250 ((char *)pp->value)[sz - 1] = 0;
251 DBG("fixed up name for %s -> %s\n", pathp,
252 (char *)pp->value);
253 }
254 }
255 if (allnextpp) {
256 *prev_pp = NULL;
257 np->name = of_get_property(np, "name", NULL);
258 np->type = of_get_property(np, "device_type", NULL);
259
260 if (!np->name)
261 np->name = "<NULL>";
262 if (!np->type)
263 np->type = "<NULL>";
264 }
265 while (tag == OF_DT_BEGIN_NODE) {
266 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
267 tag = *((u32 *)(*p));
268 }
269 if (tag != OF_DT_END_NODE) {
270 printk("Weird tag at end of node: %x\n", tag);
271 return mem;
272 }
273 *p += 4;
274 return mem;
275}
276
277static int __init early_parse_mem(char *p) 83static int __init early_parse_mem(char *p)
278{ 84{
279 if (!p) 85 if (!p)