blob: 7809100034b05ace35ed0a142e9fcb022bf9f073 [file] [log] [blame]
David S. Miller372b07b2006-06-21 15:35:28 -07001/*
2 * Procedures for creating, accessing and interpreting the device tree.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * Adapted for sparc64 by David S. Miller davem@davemloft.net
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/string.h>
21#include <linux/mm.h>
22#include <linux/bootmem.h>
David S. Millerde8d28b2006-06-22 16:18:54 -070023#include <linux/module.h>
David S. Miller372b07b2006-06-21 15:35:28 -070024
25#include <asm/prom.h>
26#include <asm/oplib.h>
27
28static struct device_node *allnodes;
29
30struct device_node *of_get_parent(const struct device_node *node)
31{
32 struct device_node *np;
33
34 if (!node)
35 return NULL;
36
37 np = node->parent;
38
39 return np;
40}
41
42struct device_node *of_get_next_child(const struct device_node *node,
43 struct device_node *prev)
44{
45 struct device_node *next;
46
47 next = prev ? prev->sibling : node->child;
48 for (; next != 0; next = next->sibling) {
49 break;
50 }
51
52 return next;
53}
54
55struct device_node *of_find_node_by_path(const char *path)
56{
57 struct device_node *np = allnodes;
58
59 for (; np != 0; np = np->allnext) {
60 if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
61 break;
62 }
63
64 return np;
65}
David S. Miller690c8fd2006-06-22 19:12:03 -070066EXPORT_SYMBOL(of_find_node_by_path);
David S. Miller372b07b2006-06-21 15:35:28 -070067
David S. Millerde8d28b2006-06-22 16:18:54 -070068struct device_node *of_find_node_by_phandle(phandle handle)
69{
70 struct device_node *np;
71
72 for (np = allnodes; np != 0; np = np->allnext)
73 if (np->node == handle)
74 break;
75
76 return np;
77}
78
David S. Milleraaf7cec2006-06-21 16:33:54 -070079struct device_node *of_find_node_by_name(struct device_node *from,
80 const char *name)
81{
82 struct device_node *np;
83
84 np = from ? from->allnext : allnodes;
85 for (; np != NULL; np = np->allnext)
86 if (np->name != NULL && strcmp(np->name, name) == 0)
87 break;
88
89 return np;
90}
91
92struct device_node *of_find_node_by_type(struct device_node *from,
93 const char *type)
94{
95 struct device_node *np;
96
97 np = from ? from->allnext : allnodes;
98 for (; np != 0; np = np->allnext)
99 if (np->type != 0 && strcmp(np->type, type) == 0)
100 break;
101
102 return np;
103}
104
David S. Miller372b07b2006-06-21 15:35:28 -0700105struct property *of_find_property(struct device_node *np, const char *name,
106 int *lenp)
107{
108 struct property *pp;
109
110 for (pp = np->properties; pp != 0; pp = pp->next) {
111 if (strcmp(pp->name, name) == 0) {
112 if (lenp != 0)
113 *lenp = pp->length;
114 break;
115 }
116 }
117 return pp;
118}
David S. Millerde8d28b2006-06-22 16:18:54 -0700119EXPORT_SYMBOL(of_find_property);
120
121/*
122 * Find a property with a given name for a given node
123 * and return the value.
124 */
125void *of_get_property(struct device_node *np, const char *name, int *lenp)
126{
127 struct property *pp = of_find_property(np,name,lenp);
128 return pp ? pp->value : NULL;
129}
130EXPORT_SYMBOL(of_get_property);
David S. Miller372b07b2006-06-21 15:35:28 -0700131
David S. Miller6d307722006-06-21 23:07:29 -0700132int of_getintprop_default(struct device_node *np, const char *name, int def)
133{
134 struct property *prop;
135 int len;
136
137 prop = of_find_property(np, name, &len);
138 if (!prop || len != 4)
139 return def;
140
141 return *(int *) prop->value;
142}
David S. Millerde8d28b2006-06-22 16:18:54 -0700143EXPORT_SYMBOL(of_getintprop_default);
David S. Miller6d307722006-06-21 23:07:29 -0700144
David S. Miller372b07b2006-06-21 15:35:28 -0700145static unsigned int prom_early_allocated;
146
147static void * __init prom_early_alloc(unsigned long size)
148{
149 void *ret;
150
151 ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
152 if (ret != NULL)
153 memset(ret, 0, size);
154
155 prom_early_allocated += size;
156
157 return ret;
158}
159
160static int is_root_node(const struct device_node *dp)
161{
162 if (!dp)
163 return 0;
164
165 return (dp->parent == NULL);
166}
167
168/* The following routines deal with the black magic of fully naming a
169 * node.
170 *
171 * Certain well known named nodes are just the simple name string.
172 *
173 * Actual devices have an address specifier appended to the base name
174 * string, like this "foo@addr". The "addr" can be in any number of
175 * formats, and the platform plus the type of the node determine the
176 * format and how it is constructed.
177 *
178 * For children of the ROOT node, the naming convention is fixed and
179 * determined by whether this is a sun4u or sun4v system.
180 *
181 * For children of other nodes, it is bus type specific. So
182 * we walk up the tree until we discover a "device_type" property
183 * we recognize and we go from there.
184 *
185 * As an example, the boot device on my workstation has a full path:
186 *
187 * /pci@1e,600000/ide@d/disk@0,0:c
188 */
189static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
190{
191 struct linux_prom64_registers *regs;
192 struct property *rprop;
193 u32 high_bits, low_bits, type;
194
195 rprop = of_find_property(dp, "reg", NULL);
196 if (!rprop)
197 return;
198
199 regs = rprop->value;
200 if (!is_root_node(dp->parent)) {
201 sprintf(tmp_buf, "%s@%x,%x",
202 dp->name,
203 (unsigned int) (regs->phys_addr >> 32UL),
204 (unsigned int) (regs->phys_addr & 0xffffffffUL));
205 return;
206 }
207
208 type = regs->phys_addr >> 60UL;
209 high_bits = (regs->phys_addr >> 32UL) & 0x0fffffffUL;
210 low_bits = (regs->phys_addr & 0xffffffffUL);
211
212 if (type == 0 || type == 8) {
213 const char *prefix = (type == 0) ? "m" : "i";
214
215 if (low_bits)
216 sprintf(tmp_buf, "%s@%s%x,%x",
217 dp->name, prefix,
218 high_bits, low_bits);
219 else
220 sprintf(tmp_buf, "%s@%s%x",
221 dp->name,
222 prefix,
223 high_bits);
224 } else if (type == 12) {
225 sprintf(tmp_buf, "%s@%x",
226 dp->name, high_bits);
227 }
228}
229
230static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
231{
232 struct linux_prom64_registers *regs;
233 struct property *prop;
234
235 prop = of_find_property(dp, "reg", NULL);
236 if (!prop)
237 return;
238
239 regs = prop->value;
240 if (!is_root_node(dp->parent)) {
241 sprintf(tmp_buf, "%s@%x,%x",
242 dp->name,
243 (unsigned int) (regs->phys_addr >> 32UL),
244 (unsigned int) (regs->phys_addr & 0xffffffffUL));
245 return;
246 }
247
248 prop = of_find_property(dp, "upa-portid", NULL);
249 if (!prop)
250 prop = of_find_property(dp, "portid", NULL);
251 if (prop) {
252 unsigned long mask = 0xffffffffUL;
253
254 if (tlb_type >= cheetah)
255 mask = 0x7fffff;
256
257 sprintf(tmp_buf, "%s@%x,%x",
258 dp->name,
259 *(u32 *)prop->value,
260 (unsigned int) (regs->phys_addr & mask));
261 }
262}
263
264/* "name@slot,offset" */
265static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
266{
267 struct linux_prom_registers *regs;
268 struct property *prop;
269
270 prop = of_find_property(dp, "reg", NULL);
271 if (!prop)
272 return;
273
274 regs = prop->value;
275 sprintf(tmp_buf, "%s@%x,%x",
276 dp->name,
277 regs->which_io,
278 regs->phys_addr);
279}
280
281/* "name@devnum[,func]" */
282static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
283{
284 struct linux_prom_pci_registers *regs;
285 struct property *prop;
286 unsigned int devfn;
287
288 prop = of_find_property(dp, "reg", NULL);
289 if (!prop)
290 return;
291
292 regs = prop->value;
293 devfn = (regs->phys_hi >> 8) & 0xff;
294 if (devfn & 0x07) {
295 sprintf(tmp_buf, "%s@%x,%x",
296 dp->name,
297 devfn >> 3,
298 devfn & 0x07);
299 } else {
300 sprintf(tmp_buf, "%s@%x",
301 dp->name,
302 devfn >> 3);
303 }
304}
305
306/* "name@UPA_PORTID,offset" */
307static void __init upa_path_component(struct device_node *dp, char *tmp_buf)
308{
309 struct linux_prom64_registers *regs;
310 struct property *prop;
311
312 prop = of_find_property(dp, "reg", NULL);
313 if (!prop)
314 return;
315
316 regs = prop->value;
317
318 prop = of_find_property(dp, "upa-portid", NULL);
319 if (!prop)
320 return;
321
322 sprintf(tmp_buf, "%s@%x,%x",
323 dp->name,
324 *(u32 *) prop->value,
325 (unsigned int) (regs->phys_addr & 0xffffffffUL));
326}
327
328/* "name@reg" */
329static void __init vdev_path_component(struct device_node *dp, char *tmp_buf)
330{
331 struct property *prop;
332 u32 *regs;
333
334 prop = of_find_property(dp, "reg", NULL);
335 if (!prop)
336 return;
337
338 regs = prop->value;
339
340 sprintf(tmp_buf, "%s@%x", dp->name, *regs);
341}
342
343/* "name@addrhi,addrlo" */
344static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
345{
346 struct linux_prom64_registers *regs;
347 struct property *prop;
348
349 prop = of_find_property(dp, "reg", NULL);
350 if (!prop)
351 return;
352
353 regs = prop->value;
354
355 sprintf(tmp_buf, "%s@%x,%x",
356 dp->name,
357 (unsigned int) (regs->phys_addr >> 32UL),
358 (unsigned int) (regs->phys_addr & 0xffffffffUL));
359}
360
361/* "name@bus,addr" */
362static void __init i2c_path_component(struct device_node *dp, char *tmp_buf)
363{
364 struct property *prop;
365 u32 *regs;
366
367 prop = of_find_property(dp, "reg", NULL);
368 if (!prop)
369 return;
370
371 regs = prop->value;
372
373 /* This actually isn't right... should look at the #address-cells
374 * property of the i2c bus node etc. etc.
375 */
376 sprintf(tmp_buf, "%s@%x,%x",
377 dp->name, regs[0], regs[1]);
378}
379
380/* "name@reg0[,reg1]" */
381static void __init usb_path_component(struct device_node *dp, char *tmp_buf)
382{
383 struct property *prop;
384 u32 *regs;
385
386 prop = of_find_property(dp, "reg", NULL);
387 if (!prop)
388 return;
389
390 regs = prop->value;
391
392 if (prop->length == sizeof(u32) || regs[1] == 1) {
393 sprintf(tmp_buf, "%s@%x",
394 dp->name, regs[0]);
395 } else {
396 sprintf(tmp_buf, "%s@%x,%x",
397 dp->name, regs[0], regs[1]);
398 }
399}
400
401/* "name@reg0reg1[,reg2reg3]" */
402static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf)
403{
404 struct property *prop;
405 u32 *regs;
406
407 prop = of_find_property(dp, "reg", NULL);
408 if (!prop)
409 return;
410
411 regs = prop->value;
412
413 if (regs[2] || regs[3]) {
414 sprintf(tmp_buf, "%s@%08x%08x,%04x%08x",
415 dp->name, regs[0], regs[1], regs[2], regs[3]);
416 } else {
417 sprintf(tmp_buf, "%s@%08x%08x",
418 dp->name, regs[0], regs[1]);
419 }
420}
421
422static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
423{
424 struct device_node *parent = dp->parent;
425
426 if (parent != NULL) {
427 if (!strcmp(parent->type, "pci") ||
428 !strcmp(parent->type, "pciex"))
429 return pci_path_component(dp, tmp_buf);
430 if (!strcmp(parent->type, "sbus"))
431 return sbus_path_component(dp, tmp_buf);
432 if (!strcmp(parent->type, "upa"))
433 return upa_path_component(dp, tmp_buf);
434 if (!strcmp(parent->type, "ebus"))
435 return ebus_path_component(dp, tmp_buf);
436 if (!strcmp(parent->name, "usb") ||
437 !strcmp(parent->name, "hub"))
438 return usb_path_component(dp, tmp_buf);
439 if (!strcmp(parent->type, "i2c"))
440 return i2c_path_component(dp, tmp_buf);
441 if (!strcmp(parent->type, "firewire"))
442 return ieee1394_path_component(dp, tmp_buf);
443 if (!strcmp(parent->type, "virtual-devices"))
444 return vdev_path_component(dp, tmp_buf);
445
446 /* "isa" is handled with platform naming */
447 }
448
449 /* Use platform naming convention. */
450 if (tlb_type == hypervisor)
451 return sun4v_path_component(dp, tmp_buf);
452 else
453 return sun4u_path_component(dp, tmp_buf);
454}
455
456static char * __init build_path_component(struct device_node *dp)
457{
458 char tmp_buf[64], *n;
459
460 tmp_buf[0] = '\0';
461 __build_path_component(dp, tmp_buf);
462 if (tmp_buf[0] == '\0')
463 strcpy(tmp_buf, dp->name);
464
465 n = prom_early_alloc(strlen(tmp_buf) + 1);
466 strcpy(n, tmp_buf);
467
468 return n;
469}
470
471static char * __init build_full_name(struct device_node *dp)
472{
473 int len, ourlen, plen;
474 char *n;
475
476 plen = strlen(dp->parent->full_name);
477 ourlen = strlen(dp->path_component_name);
478 len = ourlen + plen + 2;
479
480 n = prom_early_alloc(len);
481 strcpy(n, dp->parent->full_name);
482 if (!is_root_node(dp->parent)) {
483 strcpy(n + plen, "/");
484 plen++;
485 }
486 strcpy(n + plen, dp->path_component_name);
487
488 return n;
489}
490
491static struct property * __init build_one_prop(phandle node, char *prev)
492{
493 static struct property *tmp = NULL;
494 struct property *p;
495
496 if (tmp) {
497 p = tmp;
498 memset(p, 0, sizeof(*p) + 32);
499 tmp = NULL;
500 } else
501 p = prom_early_alloc(sizeof(struct property) + 32);
502
503 p->name = (char *) (p + 1);
504 if (prev == NULL) {
505 prom_firstprop(node, p->name);
506 } else {
507 prom_nextprop(node, prev, p->name);
508 }
509 if (strlen(p->name) == 0) {
510 tmp = p;
511 return NULL;
512 }
513 p->length = prom_getproplen(node, p->name);
514 if (p->length <= 0) {
515 p->length = 0;
516 } else {
517 p->value = prom_early_alloc(p->length);
518 prom_getproperty(node, p->name, p->value, p->length);
519 }
520 return p;
521}
522
523static struct property * __init build_prop_list(phandle node)
524{
525 struct property *head, *tail;
526
527 head = tail = build_one_prop(node, NULL);
528 while(tail) {
529 tail->next = build_one_prop(node, tail->name);
530 tail = tail->next;
531 }
532
533 return head;
534}
535
536static char * __init get_one_property(phandle node, const char *name)
537{
538 char *buf = "<NULL>";
539 int len;
540
541 len = prom_getproplen(node, name);
542 if (len > 0) {
543 buf = prom_early_alloc(len);
544 prom_getproperty(node, name, buf, len);
545 }
546
547 return buf;
548}
549
550static struct device_node * __init create_node(phandle node)
551{
552 struct device_node *dp;
553
554 if (!node)
555 return NULL;
556
557 dp = prom_early_alloc(sizeof(*dp));
558
559 kref_init(&dp->kref);
560
561 dp->name = get_one_property(node, "name");
562 dp->type = get_one_property(node, "device_type");
563 dp->node = node;
564
565 /* Build interrupts later... */
566
567 dp->properties = build_prop_list(node);
568
569 return dp;
570}
571
572static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
573{
574 struct device_node *dp;
575
576 dp = create_node(node);
577 if (dp) {
578 *(*nextp) = dp;
579 *nextp = &dp->allnext;
580
581 dp->parent = parent;
582 dp->path_component_name = build_path_component(dp);
583 dp->full_name = build_full_name(dp);
584
585 dp->child = build_tree(dp, prom_getchild(node), nextp);
586
587 dp->sibling = build_tree(parent, prom_getsibling(node), nextp);
588 }
589
590 return dp;
591}
592
593void __init prom_build_devicetree(void)
594{
595 struct device_node **nextp;
596
597 allnodes = create_node(prom_root_node);
598 allnodes->path_component_name = "";
599 allnodes->full_name = "/";
600
601 nextp = &allnodes->allnext;
602 allnodes->child = build_tree(allnodes,
603 prom_getchild(allnodes->node),
604 &nextp);
605 printk("PROM: Built device tree with %u bytes of memory.\n",
606 prom_early_allocated);
607}