1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#undef DEBUG
19
20#include <stdarg.h>
21#include <linux/config.h>
22#include <linux/kernel.h>
23#include <linux/string.h>
24#include <linux/init.h>
25#include <linux/version.h>
26#include <linux/threads.h>
27#include <linux/spinlock.h>
28#include <linux/types.h>
29#include <linux/pci.h>
30#include <linux/proc_fs.h>
31#include <linux/stringify.h>
32#include <linux/delay.h>
33#include <linux/initrd.h>
34#include <linux/bitops.h>
35#include <asm/prom.h>
36#include <asm/rtas.h>
37#include <asm/lmb.h>
38#include <asm/abs_addr.h>
39#include <asm/page.h>
40#include <asm/processor.h>
41#include <asm/irq.h>
42#include <asm/io.h>
43#include <asm/smp.h>
44#include <asm/system.h>
45#include <asm/mmu.h>
46#include <asm/pgtable.h>
47#include <asm/pci.h>
48#include <asm/iommu.h>
49#include <asm/bootinfo.h>
50#include <asm/ppcdebug.h>
51#include <asm/btext.h>
52#include <asm/sections.h>
53#include <asm/machdep.h>
54
55#ifdef DEBUG
56#define DBG(fmt...) udbg_printf(fmt)
57#else
58#define DBG(fmt...)
59#endif
60
61struct pci_reg_property {
62 struct pci_address addr;
63 u32 size_hi;
64 u32 size_lo;
65};
66
67struct isa_reg_property {
68 u32 space;
69 u32 address;
70 u32 size;
71};
72
73
74typedef unsigned long interpret_func(struct device_node *, unsigned long,
75 int, int, int);
76
77extern struct rtas_t rtas;
78extern struct lmb lmb;
79extern unsigned long klimit;
80
81static int __initdata dt_root_addr_cells;
82static int __initdata dt_root_size_cells;
83static int __initdata iommu_is_off;
84int __initdata iommu_force_on;
85typedef u32 cell_t;
86
87#if 0
88static struct boot_param_header *initial_boot_params __initdata;
89#else
90struct boot_param_header *initial_boot_params;
91#endif
92
93static struct device_node *allnodes = NULL;
94
95
96
97
98static DEFINE_RWLOCK(devtree_lock);
99
100
101struct device_node *of_chosen;
102
103
104
105
106static struct device_node * find_phandle(phandle ph)
107{
108 struct device_node *np;
109
110 for (np = allnodes; np != 0; np = np->allnext)
111 if (np->linux_phandle == ph)
112 return np;
113 return NULL;
114}
115
116
117
118
119static struct device_node * __devinit intr_parent(struct device_node *p)
120{
121 phandle *parp;
122
123 parp = (phandle *) get_property(p, "interrupt-parent", NULL);
124 if (parp == NULL)
125 return p->parent;
126 return find_phandle(*parp);
127}
128
129
130
131
132
133int __devinit prom_n_intr_cells(struct device_node *np)
134{
135 struct device_node *p;
136 unsigned int *icp;
137
138 for (p = np; (p = intr_parent(p)) != NULL; ) {
139 icp = (unsigned int *)
140 get_property(p, "#interrupt-cells", NULL);
141 if (icp != NULL)
142 return *icp;
143 if (get_property(p, "interrupt-controller", NULL) != NULL
144 || get_property(p, "interrupt-map", NULL) != NULL) {
145 printk("oops, node %s doesn't have #interrupt-cells\n",
146 p->full_name);
147 return 1;
148 }
149 }
150#ifdef DEBUG_IRQ
151 printk("prom_n_intr_cells failed for %s\n", np->full_name);
152#endif
153 return 1;
154}
155
156
157
158
159
160static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
161 struct device_node *np, unsigned int *ints,
162 int nintrc)
163{
164 struct device_node *p, *ipar;
165 unsigned int *imap, *imask, *ip;
166 int i, imaplen, match;
167 int newintrc = 0, newaddrc = 0;
168 unsigned int *reg;
169 int naddrc;
170
171 reg = (unsigned int *) get_property(np, "reg", NULL);
172 naddrc = prom_n_addr_cells(np);
173 p = intr_parent(np);
174 while (p != NULL) {
175 if (get_property(p, "interrupt-controller", NULL) != NULL)
176
177 break;
178 imap = (unsigned int *)
179 get_property(p, "interrupt-map", &imaplen);
180 if (imap == NULL) {
181 p = intr_parent(p);
182 continue;
183 }
184 imask = (unsigned int *)
185 get_property(p, "interrupt-map-mask", NULL);
186 if (imask == NULL) {
187 printk("oops, %s has interrupt-map but no mask\n",
188 p->full_name);
189 return 0;
190 }
191 imaplen /= sizeof(unsigned int);
192 match = 0;
193 ipar = NULL;
194 while (imaplen > 0 && !match) {
195
196 match = 1;
197 for (i = 0; i < naddrc && match; ++i)
198 match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
199 for (; i < naddrc + nintrc && match; ++i)
200 match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
201 imap += naddrc + nintrc;
202 imaplen -= naddrc + nintrc;
203
204 ipar = find_phandle((phandle) *imap++);
205 --imaplen;
206 if (ipar == NULL) {
207 printk("oops, no int parent %x in map of %s\n",
208 imap[-1], p->full_name);
209 return 0;
210 }
211
212 ip = (unsigned int *)
213 get_property(ipar, "#interrupt-cells", NULL);
214 if (ip == NULL) {
215 printk("oops, no #interrupt-cells on %s\n",
216 ipar->full_name);
217 return 0;
218 }
219 newintrc = *ip;
220 ip = (unsigned int *)
221 get_property(ipar, "#address-cells", NULL);
222 newaddrc = (ip == NULL)? 0: *ip;
223 imap += newaddrc + newintrc;
224 imaplen -= newaddrc + newintrc;
225 }
226 if (imaplen < 0) {
227 printk("oops, error decoding int-map on %s, len=%d\n",
228 p->full_name, imaplen);
229 return 0;
230 }
231 if (!match) {
232#ifdef DEBUG_IRQ
233 printk("oops, no match in %s int-map for %s\n",
234 p->full_name, np->full_name);
235#endif
236 return 0;
237 }
238 p = ipar;
239 naddrc = newaddrc;
240 nintrc = newintrc;
241 ints = imap - nintrc;
242 reg = ints - naddrc;
243 }
244 if (p == NULL) {
245#ifdef DEBUG_IRQ
246 printk("hmmm, int tree for %s doesn't have ctrler\n",
247 np->full_name);
248#endif
249 return 0;
250 }
251 *irq = ints;
252 *ictrler = p;
253 return nintrc;
254}
255
256static unsigned long __init finish_node_interrupts(struct device_node *np,
257 unsigned long mem_start,
258 int measure_only)
259{
260 unsigned int *ints;
261 int intlen, intrcells, intrcount;
262 int i, j, n;
263 unsigned int *irq, virq;
264 struct device_node *ic;
265
266 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
267 if (ints == NULL)
268 return mem_start;
269 intrcells = prom_n_intr_cells(np);
270 intlen /= intrcells * sizeof(unsigned int);
271 np->intrs = (struct interrupt_info *) mem_start;
272 mem_start += intlen * sizeof(struct interrupt_info);
273
274 if (measure_only)
275 return mem_start;
276
277 intrcount = 0;
278 for (i = 0; i < intlen; ++i, ints += intrcells) {
279 n = map_interrupt(&irq, &ic, np, ints, intrcells);
280 if (n <= 0)
281 continue;
282
283
284 if (ic && device_is_compatible(ic, "chrp,iic")) {
285 np->intrs[intrcount].line = irq[0];
286 } else {
287 virq = virt_irq_create_mapping(irq[0]);
288 if (virq == NO_IRQ) {
289 printk(KERN_CRIT "Could not allocate interrupt"
290 " number for %s\n", np->full_name);
291 continue;
292 }
293 np->intrs[intrcount].line = irq_offset_up(virq);
294 }
295
296
297 if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
298 char *name = get_property(ic->parent, "name", NULL);
299 if (name && !strcmp(name, "u3"))
300 np->intrs[intrcount].line += 128;
301 }
302 np->intrs[intrcount].sense = 1;
303 if (n > 1)
304 np->intrs[intrcount].sense = irq[1];
305 if (n > 2) {
306 printk("hmmm, got %d intr cells for %s:", n,
307 np->full_name);
308 for (j = 0; j < n; ++j)
309 printk(" %d", irq[j]);
310 printk("\n");
311 }
312 ++intrcount;
313 }
314 np->n_intrs = intrcount;
315
316 return mem_start;
317}
318
319static unsigned long __init interpret_pci_props(struct device_node *np,
320 unsigned long mem_start,
321 int naddrc, int nsizec,
322 int measure_only)
323{
324 struct address_range *adr;
325 struct pci_reg_property *pci_addrs;
326 int i, l;
327
328 pci_addrs = (struct pci_reg_property *)
329 get_property(np, "assigned-addresses", &l);
330 if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
331 i = 0;
332 adr = (struct address_range *) mem_start;
333 while ((l -= sizeof(struct pci_reg_property)) >= 0) {
334 if (!measure_only) {
335 adr[i].space = pci_addrs[i].addr.a_hi;
336 adr[i].address = pci_addrs[i].addr.a_lo;
337 adr[i].size = pci_addrs[i].size_lo;
338 }
339 ++i;
340 }
341 np->addrs = adr;
342 np->n_addrs = i;
343 mem_start += i * sizeof(struct address_range);
344 }
345 return mem_start;
346}
347
348static unsigned long __init interpret_dbdma_props(struct device_node *np,
349 unsigned long mem_start,
350 int naddrc, int nsizec,
351 int measure_only)
352{
353 struct reg_property32 *rp;
354 struct address_range *adr;
355 unsigned long base_address;
356 int i, l;
357 struct device_node *db;
358
359 base_address = 0;
360 if (!measure_only) {
361 for (db = np->parent; db != NULL; db = db->parent) {
362 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
363 base_address = db->addrs[0].address;
364 break;
365 }
366 }
367 }
368
369 rp = (struct reg_property32 *) get_property(np, "reg", &l);
370 if (rp != 0 && l >= sizeof(struct reg_property32)) {
371 i = 0;
372 adr = (struct address_range *) mem_start;
373 while ((l -= sizeof(struct reg_property32)) >= 0) {
374 if (!measure_only) {
375 adr[i].space = 2;
376 adr[i].address = rp[i].address + base_address;
377 adr[i].size = rp[i].size;
378 }
379 ++i;
380 }
381 np->addrs = adr;
382 np->n_addrs = i;
383 mem_start += i * sizeof(struct address_range);
384 }
385
386 return mem_start;
387}
388
389static unsigned long __init interpret_macio_props(struct device_node *np,
390 unsigned long mem_start,
391 int naddrc, int nsizec,
392 int measure_only)
393{
394 struct reg_property32 *rp;
395 struct address_range *adr;
396 unsigned long base_address;
397 int i, l;
398 struct device_node *db;
399
400 base_address = 0;
401 if (!measure_only) {
402 for (db = np->parent; db != NULL; db = db->parent) {
403 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
404 base_address = db->addrs[0].address;
405 break;
406 }
407 }
408 }
409
410 rp = (struct reg_property32 *) get_property(np, "reg", &l);
411 if (rp != 0 && l >= sizeof(struct reg_property32)) {
412 i = 0;
413 adr = (struct address_range *) mem_start;
414 while ((l -= sizeof(struct reg_property32)) >= 0) {
415 if (!measure_only) {
416 adr[i].space = 2;
417 adr[i].address = rp[i].address + base_address;
418 adr[i].size = rp[i].size;
419 }
420 ++i;
421 }
422 np->addrs = adr;
423 np->n_addrs = i;
424 mem_start += i * sizeof(struct address_range);
425 }
426
427 return mem_start;
428}
429
430static unsigned long __init interpret_isa_props(struct device_node *np,
431 unsigned long mem_start,
432 int naddrc, int nsizec,
433 int measure_only)
434{
435 struct isa_reg_property *rp;
436 struct address_range *adr;
437 int i, l;
438
439 rp = (struct isa_reg_property *) get_property(np, "reg", &l);
440 if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
441 i = 0;
442 adr = (struct address_range *) mem_start;
443 while ((l -= sizeof(struct isa_reg_property)) >= 0) {
444 if (!measure_only) {
445 adr[i].space = rp[i].space;
446 adr[i].address = rp[i].address;
447 adr[i].size = rp[i].size;
448 }
449 ++i;
450 }
451 np->addrs = adr;
452 np->n_addrs = i;
453 mem_start += i * sizeof(struct address_range);
454 }
455
456 return mem_start;
457}
458
459static unsigned long __init interpret_root_props(struct device_node *np,
460 unsigned long mem_start,
461 int naddrc, int nsizec,
462 int measure_only)
463{
464 struct address_range *adr;
465 int i, l;
466 unsigned int *rp;
467 int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
468
469 rp = (unsigned int *) get_property(np, "reg", &l);
470 if (rp != 0 && l >= rpsize) {
471 i = 0;
472 adr = (struct address_range *) mem_start;
473 while ((l -= rpsize) >= 0) {
474 if (!measure_only) {
475 adr[i].space = 0;
476 adr[i].address = rp[naddrc - 1];
477 adr[i].size = rp[naddrc + nsizec - 1];
478 }
479 ++i;
480 rp += naddrc + nsizec;
481 }
482 np->addrs = adr;
483 np->n_addrs = i;
484 mem_start += i * sizeof(struct address_range);
485 }
486
487 return mem_start;
488}
489
490static unsigned long __init finish_node(struct device_node *np,
491 unsigned long mem_start,
492 interpret_func *ifunc,
493 int naddrc, int nsizec,
494 int measure_only)
495{
496 struct device_node *child;
497 int *ip;
498
499
500 if (ifunc != NULL)
501 mem_start = ifunc(np, mem_start, naddrc, nsizec, measure_only);
502
503 mem_start = finish_node_interrupts(np, mem_start, measure_only);
504
505
506 ip = (int *) get_property(np, "#address-cells", NULL);
507 if (ip != NULL)
508 naddrc = *ip;
509 ip = (int *) get_property(np, "#size-cells", NULL);
510 if (ip != NULL)
511 nsizec = *ip;
512
513
514
515
516 if (!strcmp(np->name, "display"))
517 np->name = get_property(np, "compatible", NULL);
518
519 if (!strcmp(np->name, "device-tree") || np->parent == NULL)
520 ifunc = interpret_root_props;
521 else if (np->type == 0)
522 ifunc = NULL;
523 else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
524 ifunc = interpret_pci_props;
525 else if (!strcmp(np->type, "dbdma"))
526 ifunc = interpret_dbdma_props;
527 else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
528 ifunc = interpret_macio_props;
529 else if (!strcmp(np->type, "isa"))
530 ifunc = interpret_isa_props;
531 else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
532 ifunc = interpret_root_props;
533 else if (!((ifunc == interpret_dbdma_props
534 || ifunc == interpret_macio_props)
535 && (!strcmp(np->type, "escc")
536 || !strcmp(np->type, "media-bay"))))
537 ifunc = NULL;
538
539 for (child = np->child; child != NULL; child = child->sibling)
540 mem_start = finish_node(child, mem_start, ifunc,
541 naddrc, nsizec, measure_only);
542
543 return mem_start;
544}
545
546
547
548
549
550
551
552
553void __init finish_device_tree(void)
554{
555 unsigned long mem, size;
556
557 DBG(" -> finish_device_tree\n");
558
559 if (ppc64_interrupt_controller == IC_INVALID) {
560 DBG("failed to configure interrupt controller type\n");
561 panic("failed to configure interrupt controller type\n");
562 }
563
564
565 virt_irq_init();
566
567
568 size = finish_node(allnodes, 0, NULL, 0, 0, 1);
569 mem = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
570 if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + size)
571 BUG();
572
573 DBG(" <- finish_device_tree\n");
574}
575
576#ifdef DEBUG
577#define printk udbg_printf
578#endif
579
580static inline char *find_flat_dt_string(u32 offset)
581{
582 return ((char *)initial_boot_params) + initial_boot_params->off_dt_strings
583 + offset;
584}
585
586
587
588
589
590
591static int __init scan_flat_dt(int (*it)(unsigned long node,
592 const char *full_path, void *data),
593 void *data)
594{
595 unsigned long p = ((unsigned long)initial_boot_params) +
596 initial_boot_params->off_dt_struct;
597 int rc = 0;
598
599 do {
600 u32 tag = *((u32 *)p);
601 char *pathp;
602
603 p += 4;
604 if (tag == OF_DT_END_NODE)
605 continue;
606 if (tag == OF_DT_END)
607 break;
608 if (tag == OF_DT_PROP) {
609 u32 sz = *((u32 *)p);
610 p += 8;
611 p = _ALIGN(p, sz >= 8 ? 8 : 4);
612 p += sz;
613 p = _ALIGN(p, 4);
614 continue;
615 }
616 if (tag != OF_DT_BEGIN_NODE) {
617 printk(KERN_WARNING "Invalid tag %x scanning flattened"
618 " device tree !\n", tag);
619 return -EINVAL;
620 }
621 pathp = (char *)p;
622 p = _ALIGN(p + strlen(pathp) + 1, 4);
623 rc = it(p, pathp, data);
624 if (rc != 0)
625 break;
626 } while(1);
627
628 return rc;
629}
630
631
632
633
634
635static void* __init get_flat_dt_prop(unsigned long node, const char *name,
636 unsigned long *size)
637{
638 unsigned long p = node;
639
640 do {
641 u32 tag = *((u32 *)p);
642 u32 sz, noff;
643 const char *nstr;
644
645 p += 4;
646 if (tag != OF_DT_PROP)
647 return NULL;
648
649 sz = *((u32 *)p);
650 noff = *((u32 *)(p + 4));
651 p += 8;
652 p = _ALIGN(p, sz >= 8 ? 8 : 4);
653
654 nstr = find_flat_dt_string(noff);
655 if (nstr == NULL) {
656 printk(KERN_WARNING "Can't find property index name !\n");
657 return NULL;
658 }
659 if (strcmp(name, nstr) == 0) {
660 if (size)
661 *size = sz;
662 return (void *)p;
663 }
664 p += sz;
665 p = _ALIGN(p, 4);
666 } while(1);
667}
668
669static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
670 unsigned long align)
671{
672 void *res;
673
674 *mem = _ALIGN(*mem, align);
675 res = (void *)*mem;
676 *mem += size;
677
678 return res;
679}
680
681static unsigned long __init unflatten_dt_node(unsigned long mem,
682 unsigned long *p,
683 struct device_node *dad,
684 struct device_node ***allnextpp)
685{
686 struct device_node *np;
687 struct property *pp, **prev_pp = NULL;
688 char *pathp;
689 u32 tag;
690 unsigned int l;
691
692 tag = *((u32 *)(*p));
693 if (tag != OF_DT_BEGIN_NODE) {
694 printk("Weird tag at start of node: %x\n", tag);
695 return mem;
696 }
697 *p += 4;
698 pathp = (char *)*p;
699 l = strlen(pathp) + 1;
700 *p = _ALIGN(*p + l, 4);
701
702 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + l,
703 __alignof__(struct device_node));
704 if (allnextpp) {
705 memset(np, 0, sizeof(*np));
706 np->full_name = ((char*)np) + sizeof(struct device_node);
707 memcpy(np->full_name, pathp, l);
708 prev_pp = &np->properties;
709 **allnextpp = np;
710 *allnextpp = &np->allnext;
711 if (dad != NULL) {
712 np->parent = dad;
713
714 if (dad->next == 0)
715 dad->child = np;
716 else
717 dad->next->sibling = np;
718 dad->next = np;
719 }
720 kref_init(&np->kref);
721 }
722 while(1) {
723 u32 sz, noff;
724 char *pname;
725
726 tag = *((u32 *)(*p));
727 if (tag != OF_DT_PROP)
728 break;
729 *p += 4;
730 sz = *((u32 *)(*p));
731 noff = *((u32 *)((*p) + 4));
732 *p = _ALIGN((*p) + 8, sz >= 8 ? 8 : 4);
733
734 pname = find_flat_dt_string(noff);
735 if (pname == NULL) {
736 printk("Can't find property name in list !\n");
737 break;
738 }
739 l = strlen(pname) + 1;
740 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
741 __alignof__(struct property));
742 if (allnextpp) {
743 if (strcmp(pname, "linux,phandle") == 0) {
744 np->node = *((u32 *)*p);
745 if (np->linux_phandle == 0)
746 np->linux_phandle = np->node;
747 }
748 if (strcmp(pname, "ibm,phandle") == 0)
749 np->linux_phandle = *((u32 *)*p);
750 pp->name = pname;
751 pp->length = sz;
752 pp->value = (void *)*p;
753 *prev_pp = pp;
754 prev_pp = &pp->next;
755 }
756 *p = _ALIGN((*p) + sz, 4);
757 }
758 if (allnextpp) {
759 *prev_pp = NULL;
760 np->name = get_property(np, "name", NULL);
761 np->type = get_property(np, "device_type", NULL);
762
763 if (!np->name)
764 np->name = "<NULL>";
765 if (!np->type)
766 np->type = "<NULL>";
767 }
768 while (tag == OF_DT_BEGIN_NODE) {
769 mem = unflatten_dt_node(mem, p, np, allnextpp);
770 tag = *((u32 *)(*p));
771 }
772 if (tag != OF_DT_END_NODE) {
773 printk("Weird tag at start of node: %x\n", tag);
774 return mem;
775 }
776 *p += 4;
777 return mem;
778}
779
780
781
782
783
784
785
786
787void __init unflatten_device_tree(void)
788{
789 unsigned long start, mem, size;
790 struct device_node **allnextp = &allnodes;
791 char *p;
792 int l = 0;
793
794 DBG(" -> unflatten_device_tree()\n");
795
796
797 start = ((unsigned long)initial_boot_params) +
798 initial_boot_params->off_dt_struct;
799 size = unflatten_dt_node(0, &start, NULL, NULL);
800
801 DBG(" size is %lx, allocating...\n", size);
802
803
804 mem = (unsigned long)abs_to_virt(lmb_alloc(size,
805 __alignof__(struct device_node)));
806 DBG(" unflattening...\n", mem);
807
808
809 start = ((unsigned long)initial_boot_params) +
810 initial_boot_params->off_dt_struct;
811 unflatten_dt_node(mem, &start, NULL, &allnextp);
812 if (*((u32 *)start) != OF_DT_END)
813 printk(KERN_WARNING "Weird tag at end of tree: %x\n", *((u32 *)start));
814 *allnextp = NULL;
815
816
817 of_chosen = of_find_node_by_path("/chosen");
818
819
820 if (of_chosen != NULL) {
821 p = (char *)get_property(of_chosen, "bootargs", &l);
822 if (p != NULL && l > 0)
823 strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
824 }
825#ifdef CONFIG_CMDLINE
826 if (l == 0 || (l == 1 && (*p) == 0))
827 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
828#endif
829
830 DBG("Command line is: %s\n", cmd_line);
831
832 DBG(" <- unflatten_device_tree()\n");
833}
834
835
836static int __init early_init_dt_scan_cpus(unsigned long node,
837 const char *full_path, void *data)
838{
839 char *type = get_flat_dt_prop(node, "device_type", NULL);
840
841
842 if (type == NULL || strcmp(type, "cpu") != 0)
843 return 0;
844
845
846
847 if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
848 u32 *pft_size;
849 pft_size = (u32 *)get_flat_dt_prop(node, "ibm,pft-size", NULL);
850 if (pft_size != NULL) {
851
852 ppc64_pft_size = pft_size[1];
853 }
854 }
855
856 if (initial_boot_params && initial_boot_params->version >= 2) {
857
858
859
860 boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
861 boot_cpuid = 0;
862 } else {
863
864 if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) {
865 u32 *prop = get_flat_dt_prop(node, "reg", NULL);
866 set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop);
867 boot_cpuid_phys = get_hard_smp_processor_id(0);
868 }
869 }
870
871 return 0;
872}
873
874static int __init early_init_dt_scan_chosen(unsigned long node,
875 const char *full_path, void *data)
876{
877 u32 *prop;
878
879 if (strcmp(full_path, "/chosen") != 0)
880 return 0;
881
882
883 prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL);
884 if (prop == NULL)
885 return 0;
886 systemcfg->platform = *prop;
887
888
889 if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
890 iommu_is_off = 1;
891 if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
892 iommu_force_on = 1;
893
894#ifdef CONFIG_PPC_PSERIES
895
896
897
898 {
899 u64 *basep, *entryp;
900
901 basep = (u64*)get_flat_dt_prop(node, "linux,rtas-base", NULL);
902 entryp = (u64*)get_flat_dt_prop(node, "linux,rtas-entry", NULL);
903 prop = (u32*)get_flat_dt_prop(node, "linux,rtas-size", NULL);
904 if (basep && entryp && prop) {
905 rtas.base = *basep;
906 rtas.entry = *entryp;
907 rtas.size = *prop;
908 }
909 }
910#endif
911
912
913 return 1;
914}
915
916static int __init early_init_dt_scan_root(unsigned long node,
917 const char *full_path, void *data)
918{
919 u32 *prop;
920
921 if (strcmp(full_path, "/") != 0)
922 return 0;
923
924 prop = (u32 *)get_flat_dt_prop(node, "#size-cells", NULL);
925 dt_root_size_cells = (prop == NULL) ? 1 : *prop;
926
927 prop = (u32 *)get_flat_dt_prop(node, "#address-cells", NULL);
928 dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
929
930
931 return 1;
932}
933
934static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
935{
936 cell_t *p = *cellp;
937 unsigned long r = 0;
938
939
940 while (s > 2) {
941 p++;
942 s--;
943 }
944 while (s) {
945 r <<= 32;
946 r |= *(p++);
947 s--;
948 }
949
950 *cellp = p;
951 return r;
952}
953
954
955static int __init early_init_dt_scan_memory(unsigned long node,
956 const char *full_path, void *data)
957{
958 char *type = get_flat_dt_prop(node, "device_type", NULL);
959 cell_t *reg, *endp;
960 unsigned long l;
961
962
963 if (type == NULL || strcmp(type, "memory") != 0)
964 return 0;
965
966 reg = (cell_t *)get_flat_dt_prop(node, "reg", &l);
967 if (reg == NULL)
968 return 0;
969
970 endp = reg + (l / sizeof(cell_t));
971
972 DBG("memory scan node %s ...\n", full_path);
973 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
974 unsigned long base, size;
975
976 base = dt_mem_next_cell(dt_root_addr_cells, ®);
977 size = dt_mem_next_cell(dt_root_size_cells, ®);
978
979 if (size == 0)
980 continue;
981 DBG(" - %lx , %lx\n", base, size);
982 if (iommu_is_off) {
983 if (base >= 0x80000000ul)
984 continue;
985 if ((base + size) > 0x80000000ul)
986 size = 0x80000000ul - base;
987 }
988 lmb_add(base, size);
989 }
990 return 0;
991}
992
993static void __init early_reserve_mem(void)
994{
995 u64 base, size;
996 u64 *reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
997 initial_boot_params->off_mem_rsvmap);
998 while (1) {
999 base = *(reserve_map++);
1000 size = *(reserve_map++);
1001 if (size == 0)
1002 break;
1003 DBG("reserving: %lx -> %lx\n", base, size);
1004 lmb_reserve(base, size);
1005 }
1006
1007#if 0
1008 DBG("memory reserved, lmbs :\n");
1009 lmb_dump_all();
1010#endif
1011}
1012
1013void __init early_init_devtree(void *params)
1014{
1015 DBG(" -> early_init_devtree()\n");
1016
1017
1018 initial_boot_params = params;
1019
1020
1021 ppc64_pft_size = 0;
1022
1023
1024
1025
1026
1027 scan_flat_dt(early_init_dt_scan_chosen, NULL);
1028
1029
1030 lmb_init();
1031 scan_flat_dt(early_init_dt_scan_root, NULL);
1032 scan_flat_dt(early_init_dt_scan_memory, NULL);
1033 lmb_analyze();
1034 systemcfg->physicalMemorySize = lmb_phys_mem_size();
1035 lmb_reserve(0, __pa(klimit));
1036
1037 DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize);
1038
1039
1040 early_reserve_mem();
1041
1042 DBG("Scanning CPUs ...\n");
1043
1044
1045 scan_flat_dt(early_init_dt_scan_cpus, NULL);
1046
1047
1048
1049
1050 if (ppc64_pft_size == 0) {
1051 unsigned long rnd_mem_size, pteg_count;
1052
1053
1054 rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize);
1055 if (rnd_mem_size < systemcfg->physicalMemorySize)
1056 rnd_mem_size <<= 1;
1057
1058
1059 pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
1060
1061 ppc64_pft_size = __ilog2(pteg_count << 7);
1062 }
1063
1064 DBG("Hash pftSize: %x\n", (int)ppc64_pft_size);
1065 DBG(" <- early_init_devtree()\n");
1066}
1067
1068#undef printk
1069
1070int
1071prom_n_addr_cells(struct device_node* np)
1072{
1073 int* ip;
1074 do {
1075 if (np->parent)
1076 np = np->parent;
1077 ip = (int *) get_property(np, "#address-cells", NULL);
1078 if (ip != NULL)
1079 return *ip;
1080 } while (np->parent);
1081
1082 return 1;
1083}
1084
1085int
1086prom_n_size_cells(struct device_node* np)
1087{
1088 int* ip;
1089 do {
1090 if (np->parent)
1091 np = np->parent;
1092 ip = (int *) get_property(np, "#size-cells", NULL);
1093 if (ip != NULL)
1094 return *ip;
1095 } while (np->parent);
1096
1097 return 1;
1098}
1099
1100
1101
1102
1103
1104void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
1105{
1106 struct device_node *np;
1107 int i, j;
1108
1109
1110 memset(senses, 1, max - off);
1111
1112 for (np = allnodes; np != 0; np = np->allnext) {
1113 for (j = 0; j < np->n_intrs; j++) {
1114 i = np->intrs[j].line;
1115 if (i >= off && i < max)
1116 senses[i-off] = np->intrs[j].sense ?
1117 IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE :
1118 IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE;
1119 }
1120 }
1121}
1122
1123
1124
1125
1126struct device_node *
1127find_devices(const char *name)
1128{
1129 struct device_node *head, **prevp, *np;
1130
1131 prevp = &head;
1132 for (np = allnodes; np != 0; np = np->allnext) {
1133 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
1134 *prevp = np;
1135 prevp = &np->next;
1136 }
1137 }
1138 *prevp = NULL;
1139 return head;
1140}
1141
1142
1143
1144
1145struct device_node *
1146find_type_devices(const char *type)
1147{
1148 struct device_node *head, **prevp, *np;
1149
1150 prevp = &head;
1151 for (np = allnodes; np != 0; np = np->allnext) {
1152 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
1153 *prevp = np;
1154 prevp = &np->next;
1155 }
1156 }
1157 *prevp = NULL;
1158 return head;
1159}
1160
1161
1162
1163
1164struct device_node *
1165find_all_nodes(void)
1166{
1167 struct device_node *head, **prevp, *np;
1168
1169 prevp = &head;
1170 for (np = allnodes; np != 0; np = np->allnext) {
1171 *prevp = np;
1172 prevp = &np->next;
1173 }
1174 *prevp = NULL;
1175 return head;
1176}
1177
1178
1179
1180
1181int
1182device_is_compatible(struct device_node *device, const char *compat)
1183{
1184 const char* cp;
1185 int cplen, l;
1186
1187 cp = (char *) get_property(device, "compatible", &cplen);
1188 if (cp == NULL)
1189 return 0;
1190 while (cplen > 0) {
1191 if (strncasecmp(cp, compat, strlen(compat)) == 0)
1192 return 1;
1193 l = strlen(cp) + 1;
1194 cp += l;
1195 cplen -= l;
1196 }
1197
1198 return 0;
1199}
1200
1201
1202
1203
1204
1205
1206int
1207machine_is_compatible(const char *compat)
1208{
1209 struct device_node *root;
1210 int rc = 0;
1211
1212 root = of_find_node_by_path("/");
1213 if (root) {
1214 rc = device_is_compatible(root, compat);
1215 of_node_put(root);
1216 }
1217 return rc;
1218}
1219
1220
1221
1222
1223
1224struct device_node *
1225find_compatible_devices(const char *type, const char *compat)
1226{
1227 struct device_node *head, **prevp, *np;
1228
1229 prevp = &head;
1230 for (np = allnodes; np != 0; np = np->allnext) {
1231 if (type != NULL
1232 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1233 continue;
1234 if (device_is_compatible(np, compat)) {
1235 *prevp = np;
1236 prevp = &np->next;
1237 }
1238 }
1239 *prevp = NULL;
1240 return head;
1241}
1242
1243
1244
1245
1246struct device_node *
1247find_path_device(const char *path)
1248{
1249 struct device_node *np;
1250
1251 for (np = allnodes; np != 0; np = np->allnext)
1252 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
1253 return np;
1254 return NULL;
1255}
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279struct device_node *of_find_node_by_name(struct device_node *from,
1280 const char *name)
1281{
1282 struct device_node *np;
1283
1284 read_lock(&devtree_lock);
1285 np = from ? from->allnext : allnodes;
1286 for (; np != 0; np = np->allnext)
1287 if (np->name != 0 && strcasecmp(np->name, name) == 0
1288 && of_node_get(np))
1289 break;
1290 if (from)
1291 of_node_put(from);
1292 read_unlock(&devtree_lock);
1293 return np;
1294}
1295EXPORT_SYMBOL(of_find_node_by_name);
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308struct device_node *of_find_node_by_type(struct device_node *from,
1309 const char *type)
1310{
1311 struct device_node *np;
1312
1313 read_lock(&devtree_lock);
1314 np = from ? from->allnext : allnodes;
1315 for (; np != 0; np = np->allnext)
1316 if (np->type != 0 && strcasecmp(np->type, type) == 0
1317 && of_node_get(np))
1318 break;
1319 if (from)
1320 of_node_put(from);
1321 read_unlock(&devtree_lock);
1322 return np;
1323}
1324EXPORT_SYMBOL(of_find_node_by_type);
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340struct device_node *of_find_compatible_node(struct device_node *from,
1341 const char *type, const char *compatible)
1342{
1343 struct device_node *np;
1344
1345 read_lock(&devtree_lock);
1346 np = from ? from->allnext : allnodes;
1347 for (; np != 0; np = np->allnext) {
1348 if (type != NULL
1349 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1350 continue;
1351 if (device_is_compatible(np, compatible) && of_node_get(np))
1352 break;
1353 }
1354 if (from)
1355 of_node_put(from);
1356 read_unlock(&devtree_lock);
1357 return np;
1358}
1359EXPORT_SYMBOL(of_find_compatible_node);
1360
1361
1362
1363
1364
1365
1366
1367
1368struct device_node *of_find_node_by_path(const char *path)
1369{
1370 struct device_node *np = allnodes;
1371
1372 read_lock(&devtree_lock);
1373 for (; np != 0; np = np->allnext)
1374 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
1375 && of_node_get(np))
1376 break;
1377 read_unlock(&devtree_lock);
1378 return np;
1379}
1380EXPORT_SYMBOL(of_find_node_by_path);
1381
1382
1383
1384
1385
1386
1387
1388
1389struct device_node *of_find_node_by_phandle(phandle handle)
1390{
1391 struct device_node *np;
1392
1393 read_lock(&devtree_lock);
1394 for (np = allnodes; np != 0; np = np->allnext)
1395 if (np->linux_phandle == handle)
1396 break;
1397 if (np)
1398 of_node_get(np);
1399 read_unlock(&devtree_lock);
1400 return np;
1401}
1402EXPORT_SYMBOL(of_find_node_by_phandle);
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412struct device_node *of_find_all_nodes(struct device_node *prev)
1413{
1414 struct device_node *np;
1415
1416 read_lock(&devtree_lock);
1417 np = prev ? prev->allnext : allnodes;
1418 for (; np != 0; np = np->allnext)
1419 if (of_node_get(np))
1420 break;
1421 if (prev)
1422 of_node_put(prev);
1423 read_unlock(&devtree_lock);
1424 return np;
1425}
1426EXPORT_SYMBOL(of_find_all_nodes);
1427
1428
1429
1430
1431
1432
1433
1434
1435struct device_node *of_get_parent(const struct device_node *node)
1436{
1437 struct device_node *np;
1438
1439 if (!node)
1440 return NULL;
1441
1442 read_lock(&devtree_lock);
1443 np = of_node_get(node->parent);
1444 read_unlock(&devtree_lock);
1445 return np;
1446}
1447EXPORT_SYMBOL(of_get_parent);
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457struct device_node *of_get_next_child(const struct device_node *node,
1458 struct device_node *prev)
1459{
1460 struct device_node *next;
1461
1462 read_lock(&devtree_lock);
1463 next = prev ? prev->sibling : node->child;
1464 for (; next != 0; next = next->sibling)
1465 if (of_node_get(next))
1466 break;
1467 if (prev)
1468 of_node_put(prev);
1469 read_unlock(&devtree_lock);
1470 return next;
1471}
1472EXPORT_SYMBOL(of_get_next_child);
1473
1474
1475
1476
1477
1478
1479
1480
1481struct device_node *of_node_get(struct device_node *node)
1482{
1483 if (node)
1484 kref_get(&node->kref);
1485 return node;
1486}
1487EXPORT_SYMBOL(of_node_get);
1488
1489static inline struct device_node * kref_to_device_node(struct kref *kref)
1490{
1491 return container_of(kref, struct device_node, kref);
1492}
1493
1494
1495
1496
1497
1498
1499
1500
1501static void of_node_release(struct kref *kref)
1502{
1503 struct device_node *node = kref_to_device_node(kref);
1504 struct property *prop = node->properties;
1505
1506 if (!OF_IS_DYNAMIC(node))
1507 return;
1508 while (prop) {
1509 struct property *next = prop->next;
1510 kfree(prop->name);
1511 kfree(prop->value);
1512 kfree(prop);
1513 prop = next;
1514 }
1515 kfree(node->intrs);
1516 kfree(node->addrs);
1517 kfree(node->full_name);
1518 kfree(node);
1519}
1520
1521
1522
1523
1524
1525
1526
1527void of_node_put(struct device_node *node)
1528{
1529 if (node)
1530 kref_put(&node->kref, of_node_release);
1531}
1532EXPORT_SYMBOL(of_node_put);
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542static struct device_node *derive_parent(const char *path)
1543{
1544 struct device_node *parent = NULL;
1545 char *parent_path = "/";
1546 size_t parent_path_len = strrchr(path, '/') - path + 1;
1547
1548
1549 if (!strcmp(path, "/"))
1550 return NULL;
1551
1552 if (strrchr(path, '/') != path) {
1553 parent_path = kmalloc(parent_path_len, GFP_KERNEL);
1554 if (!parent_path)
1555 return NULL;
1556 strlcpy(parent_path, path, parent_path_len);
1557 }
1558 parent = of_find_node_by_path(parent_path);
1559 if (strcmp(parent_path, "/"))
1560 kfree(parent_path);
1561 return parent;
1562}
1563
1564
1565
1566
1567#ifdef CONFIG_PROC_DEVICETREE
1568
1569
1570
1571static void add_node_proc_entries(struct device_node *np)
1572{
1573 struct proc_dir_entry *ent;
1574
1575 ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
1576 if (ent)
1577 proc_device_tree_add_node(np, ent);
1578}
1579
1580static void remove_node_proc_entries(struct device_node *np)
1581{
1582 struct property *pp = np->properties;
1583 struct device_node *parent = np->parent;
1584
1585 while (pp) {
1586 remove_proc_entry(pp->name, np->pde);
1587 pp = pp->next;
1588 }
1589
1590
1591
1592
1593 if (np->name_link)
1594 remove_proc_entry(np->name_link->name, parent->pde);
1595 if (np->addr_link)
1596 remove_proc_entry(np->addr_link->name, parent->pde);
1597 if (np->pde)
1598 remove_proc_entry(np->pde->name, parent->pde);
1599}
1600#else
1601static void add_node_proc_entries(struct device_node *np)
1602{
1603 return;
1604}
1605
1606static void remove_node_proc_entries(struct device_node *np)
1607{
1608 return;
1609}
1610#endif
1611
1612
1613
1614
1615
1616static int of_finish_dynamic_node_interrupts(struct device_node *node)
1617{
1618 int intrcells, intlen, i;
1619 unsigned *irq, *ints, virq;
1620 struct device_node *ic;
1621
1622 ints = (unsigned int *)get_property(node, "interrupts", &intlen);
1623 intrcells = prom_n_intr_cells(node);
1624 intlen /= intrcells * sizeof(unsigned int);
1625 node->n_intrs = intlen;
1626 node->intrs = kmalloc(sizeof(struct interrupt_info) * intlen,
1627 GFP_KERNEL);
1628 if (!node->intrs)
1629 return -ENOMEM;
1630
1631 for (i = 0; i < intlen; ++i) {
1632 int n, j;
1633 node->intrs[i].line = 0;
1634 node->intrs[i].sense = 1;
1635 n = map_interrupt(&irq, &ic, node, ints, intrcells);
1636 if (n <= 0)
1637 continue;
1638 virq = virt_irq_create_mapping(irq[0]);
1639 if (virq == NO_IRQ) {
1640 printk(KERN_CRIT "Could not allocate interrupt "
1641 "number for %s\n", node->full_name);
1642 return -ENOMEM;
1643 }
1644 node->intrs[i].line = irq_offset_up(virq);
1645 if (n > 1)
1646 node->intrs[i].sense = irq[1];
1647 if (n > 2) {
1648 printk(KERN_DEBUG "hmmm, got %d intr cells for %s:", n,
1649 node->full_name);
1650 for (j = 0; j < n; ++j)
1651 printk(" %d", irq[j]);
1652 printk("\n");
1653 }
1654 ints += intrcells;
1655 }
1656 return 0;
1657}
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671static int of_finish_dynamic_node(struct device_node *node)
1672{
1673 struct device_node *parent = of_get_parent(node);
1674 u32 *regs;
1675 int err = 0;
1676 phandle *ibm_phandle;
1677
1678 node->name = get_property(node, "name", NULL);
1679 node->type = get_property(node, "device_type", NULL);
1680
1681 if (!parent) {
1682 err = -ENODEV;
1683 goto out;
1684 }
1685
1686
1687
1688
1689 if (systemcfg->platform == PLATFORM_POWERMAC)
1690 return -ENODEV;
1691
1692
1693 if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
1694 node->linux_phandle = *ibm_phandle;
1695
1696
1697 if (parent->type && !strcmp(parent->type, "pci")) {
1698 struct address_range *adr;
1699 struct pci_reg_property *pci_addrs;
1700 int i, l;
1701
1702 pci_addrs = (struct pci_reg_property *)
1703 get_property(node, "assigned-addresses", &l);
1704 if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
1705 i = 0;
1706 adr = kmalloc(sizeof(struct address_range) *
1707 (l / sizeof(struct pci_reg_property)),
1708 GFP_KERNEL);
1709 if (!adr) {
1710 err = -ENOMEM;
1711 goto out;
1712 }
1713 while ((l -= sizeof(struct pci_reg_property)) >= 0) {
1714 adr[i].space = pci_addrs[i].addr.a_hi;
1715 adr[i].address = pci_addrs[i].addr.a_lo;
1716 adr[i].size = pci_addrs[i].size_lo;
1717 ++i;
1718 }
1719 node->addrs = adr;
1720 node->n_addrs = i;
1721 }
1722 }
1723
1724
1725 if (get_property(node, "interrupts", NULL)) {
1726 err = of_finish_dynamic_node_interrupts(node);
1727 if (err) goto out;
1728 }
1729
1730
1731
1732
1733
1734
1735 node->phb = parent->phb;
1736
1737 regs = (u32 *)get_property(node, "reg", NULL);
1738 if (regs) {
1739 node->busno = (regs[0] >> 16) & 0xff;
1740 node->devfn = (regs[0] >> 8) & 0xff;
1741 }
1742
1743out:
1744 of_node_put(parent);
1745 return err;
1746}
1747
1748
1749
1750
1751
1752
1753int of_add_node(const char *path, struct property *proplist)
1754{
1755 struct device_node *np;
1756 int err = 0;
1757
1758 np = kmalloc(sizeof(struct device_node), GFP_KERNEL);
1759 if (!np)
1760 return -ENOMEM;
1761
1762 memset(np, 0, sizeof(*np));
1763
1764 np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
1765 if (!np->full_name) {
1766 kfree(np);
1767 return -ENOMEM;
1768 }
1769 strcpy(np->full_name, path);
1770
1771 np->properties = proplist;
1772 OF_MARK_DYNAMIC(np);
1773 kref_init(&np->kref);
1774 of_node_get(np);
1775 np->parent = derive_parent(path);
1776 if (!np->parent) {
1777 kfree(np);
1778 return -EINVAL;
1779 }
1780
1781 if (0 != (err = of_finish_dynamic_node(np))) {
1782 kfree(np);
1783 return err;
1784 }
1785
1786 write_lock(&devtree_lock);
1787 np->sibling = np->parent->child;
1788 np->allnext = allnodes;
1789 np->parent->child = np;
1790 allnodes = np;
1791 write_unlock(&devtree_lock);
1792
1793 add_node_proc_entries(np);
1794
1795 of_node_put(np->parent);
1796 of_node_put(np);
1797 return 0;
1798}
1799
1800
1801
1802
1803static void of_cleanup_node(struct device_node *np)
1804{
1805 if (np->iommu_table && get_property(np, "ibm,dma-window", NULL))
1806 iommu_free_table(np);
1807}
1808
1809
1810
1811
1812
1813
1814int of_remove_node(struct device_node *np)
1815{
1816 struct device_node *parent, *child;
1817
1818 parent = of_get_parent(np);
1819 if (!parent)
1820 return -EINVAL;
1821
1822 if ((child = of_get_next_child(np, NULL))) {
1823 of_node_put(child);
1824 return -EBUSY;
1825 }
1826
1827 of_cleanup_node(np);
1828
1829 write_lock(&devtree_lock);
1830 remove_node_proc_entries(np);
1831 if (allnodes == np)
1832 allnodes = np->allnext;
1833 else {
1834 struct device_node *prev;
1835 for (prev = allnodes;
1836 prev->allnext != np;
1837 prev = prev->allnext)
1838 ;
1839 prev->allnext = np->allnext;
1840 }
1841
1842 if (parent->child == np)
1843 parent->child = np->sibling;
1844 else {
1845 struct device_node *prevsib;
1846 for (prevsib = np->parent->child;
1847 prevsib->sibling != np;
1848 prevsib = prevsib->sibling)
1849 ;
1850 prevsib->sibling = np->sibling;
1851 }
1852 write_unlock(&devtree_lock);
1853 of_node_put(parent);
1854 of_node_put(np);
1855 return 0;
1856}
1857
1858
1859
1860
1861
1862unsigned char *
1863get_property(struct device_node *np, const char *name, int *lenp)
1864{
1865 struct property *pp;
1866
1867 for (pp = np->properties; pp != 0; pp = pp->next)
1868 if (strcmp(pp->name, name) == 0) {
1869 if (lenp != 0)
1870 *lenp = pp->length;
1871 return pp->value;
1872 }
1873 return NULL;
1874}
1875
1876
1877
1878
1879void
1880prom_add_property(struct device_node* np, struct property* prop)
1881{
1882 struct property **next = &np->properties;
1883
1884 prop->next = NULL;
1885 while (*next)
1886 next = &(*next)->next;
1887 *next = prop;
1888}
1889
1890#if 0
1891void
1892print_properties(struct device_node *np)
1893{
1894 struct property *pp;
1895 char *cp;
1896 int i, n;
1897
1898 for (pp = np->properties; pp != 0; pp = pp->next) {
1899 printk(KERN_INFO "%s", pp->name);
1900 for (i = strlen(pp->name); i < 16; ++i)
1901 printk(" ");
1902 cp = (char *) pp->value;
1903 for (i = pp->length; i > 0; --i, ++cp)
1904 if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
1905 || (i == 1 && *cp != 0))
1906 break;
1907 if (i == 0 && pp->length > 1) {
1908
1909 printk(" %s\n", (char *) pp->value);
1910 } else {
1911
1912 n = pp->length;
1913 if (n > 64)
1914 n = 64;
1915 if (pp->length % 4 == 0) {
1916 unsigned int *p = (unsigned int *) pp->value;
1917
1918 n /= 4;
1919 for (i = 0; i < n; ++i) {
1920 if (i != 0 && (i % 4) == 0)
1921 printk("\n ");
1922 printk(" %08x", *p++);
1923 }
1924 } else {
1925 unsigned char *bp = pp->value;
1926
1927 for (i = 0; i < n; ++i) {
1928 if (i != 0 && (i % 16) == 0)
1929 printk("\n ");
1930 printk(" %02x", *bp++);
1931 }
1932 }
1933 printk("\n");
1934 if (pp->length > 64)
1935 printk(" ... (length = %d)\n",
1936 pp->length);
1937 }
1938 }
1939}
1940#endif
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951