aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/prom_parse.c')
-rw-r--r--arch/powerpc/kernel/prom_parse.c103
1 files changed, 58 insertions, 45 deletions
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 11052c212ad5..603dff3ad62a 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -27,7 +27,7 @@
27 27
28/* Debug utility */ 28/* Debug utility */
29#ifdef DEBUG 29#ifdef DEBUG
30static void of_dump_addr(const char *s, u32 *addr, int na) 30static void of_dump_addr(const char *s, const u32 *addr, int na)
31{ 31{
32 printk("%s", s); 32 printk("%s", s);
33 while(na--) 33 while(na--)
@@ -35,7 +35,7 @@ static void of_dump_addr(const char *s, u32 *addr, int na)
35 printk("\n"); 35 printk("\n");
36} 36}
37#else 37#else
38static void of_dump_addr(const char *s, u32 *addr, int na) { } 38static void of_dump_addr(const char *s, const u32 *addr, int na) { }
39#endif 39#endif
40 40
41 41
@@ -46,9 +46,10 @@ struct of_bus {
46 int (*match)(struct device_node *parent); 46 int (*match)(struct device_node *parent);
47 void (*count_cells)(struct device_node *child, 47 void (*count_cells)(struct device_node *child,
48 int *addrc, int *sizec); 48 int *addrc, int *sizec);
49 u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); 49 u64 (*map)(u32 *addr, const u32 *range,
50 int na, int ns, int pna);
50 int (*translate)(u32 *addr, u64 offset, int na); 51 int (*translate)(u32 *addr, u64 offset, int na);
51 unsigned int (*get_flags)(u32 *addr); 52 unsigned int (*get_flags)(const u32 *addr);
52}; 53};
53 54
54 55
@@ -65,7 +66,8 @@ static void of_bus_default_count_cells(struct device_node *dev,
65 *sizec = prom_n_size_cells(dev); 66 *sizec = prom_n_size_cells(dev);
66} 67}
67 68
68static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) 69static u64 of_bus_default_map(u32 *addr, const u32 *range,
70 int na, int ns, int pna)
69{ 71{
70 u64 cp, s, da; 72 u64 cp, s, da;
71 73
@@ -93,7 +95,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
93 return 0; 95 return 0;
94} 96}
95 97
96static unsigned int of_bus_default_get_flags(u32 *addr) 98static unsigned int of_bus_default_get_flags(const u32 *addr)
97{ 99{
98 return IORESOURCE_MEM; 100 return IORESOURCE_MEM;
99} 101}
@@ -118,7 +120,7 @@ static void of_bus_pci_count_cells(struct device_node *np,
118 *sizec = 2; 120 *sizec = 2;
119} 121}
120 122
121static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) 123static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
122{ 124{
123 u64 cp, s, da; 125 u64 cp, s, da;
124 126
@@ -143,7 +145,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
143 return of_bus_default_translate(addr + 1, offset, na - 1); 145 return of_bus_default_translate(addr + 1, offset, na - 1);
144} 146}
145 147
146static unsigned int of_bus_pci_get_flags(u32 *addr) 148static unsigned int of_bus_pci_get_flags(const u32 *addr)
147{ 149{
148 unsigned int flags = 0; 150 unsigned int flags = 0;
149 u32 w = addr[0]; 151 u32 w = addr[0];
@@ -178,7 +180,7 @@ static void of_bus_isa_count_cells(struct device_node *child,
178 *sizec = 1; 180 *sizec = 1;
179} 181}
180 182
181static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) 183static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
182{ 184{
183 u64 cp, s, da; 185 u64 cp, s, da;
184 186
@@ -203,7 +205,7 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
203 return of_bus_default_translate(addr + 1, offset, na - 1); 205 return of_bus_default_translate(addr + 1, offset, na - 1);
204} 206}
205 207
206static unsigned int of_bus_isa_get_flags(u32 *addr) 208static unsigned int of_bus_isa_get_flags(const u32 *addr)
207{ 209{
208 unsigned int flags = 0; 210 unsigned int flags = 0;
209 u32 w = addr[0]; 211 u32 w = addr[0];
@@ -268,7 +270,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
268 struct of_bus *pbus, u32 *addr, 270 struct of_bus *pbus, u32 *addr,
269 int na, int ns, int pna) 271 int na, int ns, int pna)
270{ 272{
271 u32 *ranges; 273 const u32 *ranges;
272 unsigned int rlen; 274 unsigned int rlen;
273 int rone; 275 int rone;
274 u64 offset = OF_BAD_ADDR; 276 u64 offset = OF_BAD_ADDR;
@@ -285,7 +287,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
285 * to translate addresses that aren't supposed to be translated in 287 * to translate addresses that aren't supposed to be translated in
286 * the first place. --BenH. 288 * the first place. --BenH.
287 */ 289 */
288 ranges = (u32 *)get_property(parent, "ranges", &rlen); 290 ranges = get_property(parent, "ranges", &rlen);
289 if (ranges == NULL || rlen == 0) { 291 if (ranges == NULL || rlen == 0) {
290 offset = of_read_number(addr, na); 292 offset = of_read_number(addr, na);
291 memset(addr, 0, pna * 4); 293 memset(addr, 0, pna * 4);
@@ -328,7 +330,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
328 * that can be mapped to a cpu physical address). This is not really specified 330 * that can be mapped to a cpu physical address). This is not really specified
329 * that way, but this is traditionally the way IBM at least do things 331 * that way, but this is traditionally the way IBM at least do things
330 */ 332 */
331u64 of_translate_address(struct device_node *dev, u32 *in_addr) 333u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
332{ 334{
333 struct device_node *parent = NULL; 335 struct device_node *parent = NULL;
334 struct of_bus *bus, *pbus; 336 struct of_bus *bus, *pbus;
@@ -405,10 +407,10 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr)
405} 407}
406EXPORT_SYMBOL(of_translate_address); 408EXPORT_SYMBOL(of_translate_address);
407 409
408u32 *of_get_address(struct device_node *dev, int index, u64 *size, 410const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
409 unsigned int *flags) 411 unsigned int *flags)
410{ 412{
411 u32 *prop; 413 const u32 *prop;
412 unsigned int psize; 414 unsigned int psize;
413 struct device_node *parent; 415 struct device_node *parent;
414 struct of_bus *bus; 416 struct of_bus *bus;
@@ -425,7 +427,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
425 return NULL; 427 return NULL;
426 428
427 /* Get "reg" or "assigned-addresses" property */ 429 /* Get "reg" or "assigned-addresses" property */
428 prop = (u32 *)get_property(dev, bus->addresses, &psize); 430 prop = get_property(dev, bus->addresses, &psize);
429 if (prop == NULL) 431 if (prop == NULL)
430 return NULL; 432 return NULL;
431 psize /= 4; 433 psize /= 4;
@@ -443,10 +445,10 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
443} 445}
444EXPORT_SYMBOL(of_get_address); 446EXPORT_SYMBOL(of_get_address);
445 447
446u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, 448const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
447 unsigned int *flags) 449 unsigned int *flags)
448{ 450{
449 u32 *prop; 451 const u32 *prop;
450 unsigned int psize; 452 unsigned int psize;
451 struct device_node *parent; 453 struct device_node *parent;
452 struct of_bus *bus; 454 struct of_bus *bus;
@@ -467,7 +469,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
467 return NULL; 469 return NULL;
468 470
469 /* Get "reg" or "assigned-addresses" property */ 471 /* Get "reg" or "assigned-addresses" property */
470 prop = (u32 *)get_property(dev, bus->addresses, &psize); 472 prop = get_property(dev, bus->addresses, &psize);
471 if (prop == NULL) 473 if (prop == NULL)
472 return NULL; 474 return NULL;
473 psize /= 4; 475 psize /= 4;
@@ -485,7 +487,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
485} 487}
486EXPORT_SYMBOL(of_get_pci_address); 488EXPORT_SYMBOL(of_get_pci_address);
487 489
488static int __of_address_to_resource(struct device_node *dev, u32 *addrp, 490static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
489 u64 size, unsigned int flags, 491 u64 size, unsigned int flags,
490 struct resource *r) 492 struct resource *r)
491{ 493{
@@ -516,7 +518,7 @@ static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
516int of_address_to_resource(struct device_node *dev, int index, 518int of_address_to_resource(struct device_node *dev, int index,
517 struct resource *r) 519 struct resource *r)
518{ 520{
519 u32 *addrp; 521 const u32 *addrp;
520 u64 size; 522 u64 size;
521 unsigned int flags; 523 unsigned int flags;
522 524
@@ -530,7 +532,7 @@ EXPORT_SYMBOL_GPL(of_address_to_resource);
530int of_pci_address_to_resource(struct device_node *dev, int bar, 532int of_pci_address_to_resource(struct device_node *dev, int bar,
531 struct resource *r) 533 struct resource *r)
532{ 534{
533 u32 *addrp; 535 const u32 *addrp;
534 u64 size; 536 u64 size;
535 unsigned int flags; 537 unsigned int flags;
536 538
@@ -541,13 +543,14 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
541} 543}
542EXPORT_SYMBOL_GPL(of_pci_address_to_resource); 544EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
543 545
544void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop, 546void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
545 unsigned long *busno, unsigned long *phys, unsigned long *size) 547 unsigned long *busno, unsigned long *phys, unsigned long *size)
546{ 548{
547 u32 *dma_window, cells; 549 const u32 *dma_window;
548 unsigned char *prop; 550 u32 cells;
551 const unsigned char *prop;
549 552
550 dma_window = (u32 *)dma_window_prop; 553 dma_window = dma_window_prop;
551 554
552 /* busno is always one cell */ 555 /* busno is always one cell */
553 *busno = *(dma_window++); 556 *busno = *(dma_window++);
@@ -576,13 +579,13 @@ static struct device_node *of_irq_dflt_pic;
576static struct device_node *of_irq_find_parent(struct device_node *child) 579static struct device_node *of_irq_find_parent(struct device_node *child)
577{ 580{
578 struct device_node *p; 581 struct device_node *p;
579 phandle *parp; 582 const phandle *parp;
580 583
581 if (!of_node_get(child)) 584 if (!of_node_get(child))
582 return NULL; 585 return NULL;
583 586
584 do { 587 do {
585 parp = (phandle *)get_property(child, "interrupt-parent", NULL); 588 parp = get_property(child, "interrupt-parent", NULL);
586 if (parp == NULL) 589 if (parp == NULL)
587 p = of_get_parent(child); 590 p = of_get_parent(child);
588 else { 591 else {
@@ -639,14 +642,17 @@ void of_irq_map_init(unsigned int flags)
639 642
640} 643}
641 644
642int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr, 645int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
643 struct of_irq *out_irq) 646 const u32 *addr, struct of_irq *out_irq)
644{ 647{
645 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; 648 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
646 u32 *tmp, *imap, *imask; 649 const u32 *tmp, *imap, *imask;
647 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; 650 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
648 int imaplen, match, i; 651 int imaplen, match, i;
649 652
653 DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
654 parent->full_name, intspec[0], intspec[1], ointsize);
655
650 ipar = of_node_get(parent); 656 ipar = of_node_get(parent);
651 657
652 /* First get the #interrupt-cells property of the current cursor 658 /* First get the #interrupt-cells property of the current cursor
@@ -654,7 +660,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr,
654 * is none, we are nice and just walk up the tree 660 * is none, we are nice and just walk up the tree
655 */ 661 */
656 do { 662 do {
657 tmp = (u32 *)get_property(ipar, "#interrupt-cells", NULL); 663 tmp = get_property(ipar, "#interrupt-cells", NULL);
658 if (tmp != NULL) { 664 if (tmp != NULL) {
659 intsize = *tmp; 665 intsize = *tmp;
660 break; 666 break;
@@ -670,12 +676,15 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr,
670 676
671 DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); 677 DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
672 678
679 if (ointsize != intsize)
680 return -EINVAL;
681
673 /* Look for this #address-cells. We have to implement the old linux 682 /* Look for this #address-cells. We have to implement the old linux
674 * trick of looking for the parent here as some device-trees rely on it 683 * trick of looking for the parent here as some device-trees rely on it
675 */ 684 */
676 old = of_node_get(ipar); 685 old = of_node_get(ipar);
677 do { 686 do {
678 tmp = (u32 *)get_property(old, "#address-cells", NULL); 687 tmp = get_property(old, "#address-cells", NULL);
679 tnode = of_get_parent(old); 688 tnode = of_get_parent(old);
680 of_node_put(old); 689 of_node_put(old);
681 old = tnode; 690 old = tnode;
@@ -702,7 +711,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr,
702 } 711 }
703 712
704 /* Now look for an interrupt-map */ 713 /* Now look for an interrupt-map */
705 imap = (u32 *)get_property(ipar, "interrupt-map", &imaplen); 714 imap = get_property(ipar, "interrupt-map", &imaplen);
706 /* No interrupt map, check for an interrupt parent */ 715 /* No interrupt map, check for an interrupt parent */
707 if (imap == NULL) { 716 if (imap == NULL) {
708 DBG(" -> no map, getting parent\n"); 717 DBG(" -> no map, getting parent\n");
@@ -712,7 +721,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr,
712 imaplen /= sizeof(u32); 721 imaplen /= sizeof(u32);
713 722
714 /* Look for a mask */ 723 /* Look for a mask */
715 imask = (u32 *)get_property(ipar, "interrupt-map-mask", NULL); 724 imask = get_property(ipar, "interrupt-map-mask", NULL);
716 725
717 /* If we were passed no "reg" property and we attempt to parse 726 /* If we were passed no "reg" property and we attempt to parse
718 * an interrupt-map, then #address-cells must be 0. 727 * an interrupt-map, then #address-cells must be 0.
@@ -759,14 +768,14 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr,
759 /* Get #interrupt-cells and #address-cells of new 768 /* Get #interrupt-cells and #address-cells of new
760 * parent 769 * parent
761 */ 770 */
762 tmp = (u32 *)get_property(newpar, "#interrupt-cells", 771 tmp = get_property(newpar, "#interrupt-cells",
763 NULL); 772 NULL);
764 if (tmp == NULL) { 773 if (tmp == NULL) {
765 DBG(" -> parent lacks #interrupt-cells !\n"); 774 DBG(" -> parent lacks #interrupt-cells !\n");
766 goto fail; 775 goto fail;
767 } 776 }
768 newintsize = *tmp; 777 newintsize = *tmp;
769 tmp = (u32 *)get_property(newpar, "#address-cells", 778 tmp = get_property(newpar, "#address-cells",
770 NULL); 779 NULL);
771 newaddrsize = (tmp == NULL) ? 0 : *tmp; 780 newaddrsize = (tmp == NULL) ? 0 : *tmp;
772 781
@@ -812,14 +821,14 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
812static int of_irq_map_oldworld(struct device_node *device, int index, 821static int of_irq_map_oldworld(struct device_node *device, int index,
813 struct of_irq *out_irq) 822 struct of_irq *out_irq)
814{ 823{
815 u32 *ints; 824 const u32 *ints;
816 int intlen; 825 int intlen;
817 826
818 /* 827 /*
819 * Old machines just have a list of interrupt numbers 828 * Old machines just have a list of interrupt numbers
820 * and no interrupt-controller nodes. 829 * and no interrupt-controller nodes.
821 */ 830 */
822 ints = (u32 *) get_property(device, "AAPL,interrupts", &intlen); 831 ints = get_property(device, "AAPL,interrupts", &intlen);
823 if (ints == NULL) 832 if (ints == NULL)
824 return -EINVAL; 833 return -EINVAL;
825 intlen /= sizeof(u32); 834 intlen /= sizeof(u32);
@@ -844,7 +853,8 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
844int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) 853int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
845{ 854{
846 struct device_node *p; 855 struct device_node *p;
847 u32 *intspec, *tmp, intsize, intlen, *addr; 856 const u32 *intspec, *tmp, *addr;
857 u32 intsize, intlen;
848 int res; 858 int res;
849 859
850 DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); 860 DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
@@ -854,13 +864,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
854 return of_irq_map_oldworld(device, index, out_irq); 864 return of_irq_map_oldworld(device, index, out_irq);
855 865
856 /* Get the interrupts property */ 866 /* Get the interrupts property */
857 intspec = (u32 *)get_property(device, "interrupts", &intlen); 867 intspec = get_property(device, "interrupts", &intlen);
858 if (intspec == NULL) 868 if (intspec == NULL)
859 return -EINVAL; 869 return -EINVAL;
860 intlen /= sizeof(u32); 870 intlen /= sizeof(u32);
861 871
862 /* Get the reg property (if any) */ 872 /* Get the reg property (if any) */
863 addr = (u32 *)get_property(device, "reg", NULL); 873 addr = get_property(device, "reg", NULL);
864 874
865 /* Look for the interrupt parent. */ 875 /* Look for the interrupt parent. */
866 p = of_irq_find_parent(device); 876 p = of_irq_find_parent(device);
@@ -868,19 +878,22 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
868 return -EINVAL; 878 return -EINVAL;
869 879
870 /* Get size of interrupt specifier */ 880 /* Get size of interrupt specifier */
871 tmp = (u32 *)get_property(p, "#interrupt-cells", NULL); 881 tmp = get_property(p, "#interrupt-cells", NULL);
872 if (tmp == NULL) { 882 if (tmp == NULL) {
873 of_node_put(p); 883 of_node_put(p);
874 return -EINVAL; 884 return -EINVAL;
875 } 885 }
876 intsize = *tmp; 886 intsize = *tmp;
877 887
888 DBG(" intsize=%d intlen=%d\n", intsize, intlen);
889
878 /* Check index */ 890 /* Check index */
879 if ((index + 1) * intsize > intlen) 891 if ((index + 1) * intsize > intlen)
880 return -EINVAL; 892 return -EINVAL;
881 893
882 /* Get new specifier and map it */ 894 /* Get new specifier and map it */
883 res = of_irq_map_raw(p, intspec + index * intsize, addr, out_irq); 895 res = of_irq_map_raw(p, intspec + index * intsize, intsize,
896 addr, out_irq);
884 of_node_put(p); 897 of_node_put(p);
885 return res; 898 return res;
886} 899}
@@ -965,7 +978,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
965 laddr[0] = (pdev->bus->number << 16) 978 laddr[0] = (pdev->bus->number << 16)
966 | (pdev->devfn << 8); 979 | (pdev->devfn << 8);
967 laddr[1] = laddr[2] = 0; 980 laddr[1] = laddr[2] = 0;
968 return of_irq_map_raw(ppnode, &lspec, laddr, out_irq); 981 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
969} 982}
970EXPORT_SYMBOL_GPL(of_irq_map_pci); 983EXPORT_SYMBOL_GPL(of_irq_map_pci);
971#endif /* CONFIG_PCI */ 984#endif /* CONFIG_PCI */