diff options
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index d8ef2e100505..f022862de344 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -637,7 +637,7 @@ make_one_node_map(struct device_node* node, u8 pci_bus) | |||
637 | 637 | ||
638 | if (pci_bus >= pci_bus_count) | 638 | if (pci_bus >= pci_bus_count) |
639 | return; | 639 | return; |
640 | bus_range = get_property(node, "bus-range", &len); | 640 | bus_range = of_get_property(node, "bus-range", &len); |
641 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 641 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
642 | printk(KERN_WARNING "Can't get bus-range for %s, " | 642 | printk(KERN_WARNING "Can't get bus-range for %s, " |
643 | "assuming it starts at 0\n", node->full_name); | 643 | "assuming it starts at 0\n", node->full_name); |
@@ -649,17 +649,20 @@ make_one_node_map(struct device_node* node, u8 pci_bus) | |||
649 | struct pci_dev* dev; | 649 | struct pci_dev* dev; |
650 | const unsigned int *class_code, *reg; | 650 | const unsigned int *class_code, *reg; |
651 | 651 | ||
652 | class_code = get_property(node, "class-code", NULL); | 652 | class_code = of_get_property(node, "class-code", NULL); |
653 | if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | 653 | if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && |
654 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) | 654 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) |
655 | continue; | 655 | continue; |
656 | reg = get_property(node, "reg", NULL); | 656 | reg = of_get_property(node, "reg", NULL); |
657 | if (!reg) | 657 | if (!reg) |
658 | continue; | 658 | continue; |
659 | dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); | 659 | dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff)); |
660 | if (!dev || !dev->subordinate) | 660 | if (!dev || !dev->subordinate) { |
661 | pci_dev_put(dev); | ||
661 | continue; | 662 | continue; |
663 | } | ||
662 | make_one_node_map(node, dev->subordinate->number); | 664 | make_one_node_map(node, dev->subordinate->number); |
665 | pci_dev_put(dev); | ||
663 | } | 666 | } |
664 | } | 667 | } |
665 | 668 | ||
@@ -669,6 +672,7 @@ pcibios_make_OF_bus_map(void) | |||
669 | int i; | 672 | int i; |
670 | struct pci_controller* hose; | 673 | struct pci_controller* hose; |
671 | struct property *map_prop; | 674 | struct property *map_prop; |
675 | struct device_node *dn; | ||
672 | 676 | ||
673 | pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL); | 677 | pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL); |
674 | if (!pci_to_OF_bus_map) { | 678 | if (!pci_to_OF_bus_map) { |
@@ -690,12 +694,13 @@ pcibios_make_OF_bus_map(void) | |||
690 | continue; | 694 | continue; |
691 | make_one_node_map(node, hose->first_busno); | 695 | make_one_node_map(node, hose->first_busno); |
692 | } | 696 | } |
693 | map_prop = of_find_property(find_path_device("/"), | 697 | dn = of_find_node_by_path("/"); |
694 | "pci-OF-bus-map", NULL); | 698 | map_prop = of_find_property(dn, "pci-OF-bus-map", NULL); |
695 | if (map_prop) { | 699 | if (map_prop) { |
696 | BUG_ON(pci_bus_count > map_prop->length); | 700 | BUG_ON(pci_bus_count > map_prop->length); |
697 | memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count); | 701 | memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count); |
698 | } | 702 | } |
703 | of_node_put(dn); | ||
699 | #ifdef DEBUG | 704 | #ifdef DEBUG |
700 | printk("PCI->OF bus map:\n"); | 705 | printk("PCI->OF bus map:\n"); |
701 | for (i=0; i<pci_bus_count; i++) { | 706 | for (i=0; i<pci_bus_count; i++) { |
@@ -724,7 +729,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* | |||
724 | * a fake root for all functions of a multi-function device, | 729 | * a fake root for all functions of a multi-function device, |
725 | * we go down them as well. | 730 | * we go down them as well. |
726 | */ | 731 | */ |
727 | class_code = get_property(node, "class-code", NULL); | 732 | class_code = of_get_property(node, "class-code", NULL); |
728 | if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && | 733 | if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && |
729 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && | 734 | (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && |
730 | strcmp(node->name, "multifunc-device")) | 735 | strcmp(node->name, "multifunc-device")) |
@@ -744,7 +749,7 @@ static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, | |||
744 | unsigned int psize; | 749 | unsigned int psize; |
745 | 750 | ||
746 | while ((np = of_get_next_child(parent, np)) != NULL) { | 751 | while ((np = of_get_next_child(parent, np)) != NULL) { |
747 | reg = get_property(np, "reg", &psize); | 752 | reg = of_get_property(np, "reg", &psize); |
748 | if (reg == NULL || psize < 4) | 753 | if (reg == NULL || psize < 4) |
749 | continue; | 754 | continue; |
750 | if (((reg[0] >> 8) & 0xff) == devfn) | 755 | if (((reg[0] >> 8) & 0xff) == devfn) |
@@ -859,7 +864,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) | |||
859 | if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, | 864 | if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, |
860 | find_OF_pci_device_filter, (void *)node)) | 865 | find_OF_pci_device_filter, (void *)node)) |
861 | return -ENODEV; | 866 | return -ENODEV; |
862 | reg = get_property(node, "reg", NULL); | 867 | reg = of_get_property(node, "reg", NULL); |
863 | if (!reg) | 868 | if (!reg) |
864 | return -ENODEV; | 869 | return -ENODEV; |
865 | *bus = (reg[0] >> 16) & 0xff; | 870 | *bus = (reg[0] >> 16) & 0xff; |
@@ -895,14 +900,14 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
895 | int rlen = 0, orig_rlen; | 900 | int rlen = 0, orig_rlen; |
896 | int memno = 0; | 901 | int memno = 0; |
897 | struct resource *res; | 902 | struct resource *res; |
898 | int np, na = prom_n_addr_cells(dev); | 903 | int np, na = of_n_addr_cells(dev); |
899 | np = na + 5; | 904 | np = na + 5; |
900 | 905 | ||
901 | /* First we try to merge ranges to fix a problem with some pmacs | 906 | /* First we try to merge ranges to fix a problem with some pmacs |
902 | * that can have more than 3 ranges, fortunately using contiguous | 907 | * that can have more than 3 ranges, fortunately using contiguous |
903 | * addresses -- BenH | 908 | * addresses -- BenH |
904 | */ | 909 | */ |
905 | dt_ranges = get_property(dev, "ranges", &rlen); | 910 | dt_ranges = of_get_property(dev, "ranges", &rlen); |
906 | if (!dt_ranges) | 911 | if (!dt_ranges) |
907 | return; | 912 | return; |
908 | /* Sanity check, though hopefully that never happens */ | 913 | /* Sanity check, though hopefully that never happens */ |
@@ -1006,14 +1011,19 @@ void __init | |||
1006 | pci_create_OF_bus_map(void) | 1011 | pci_create_OF_bus_map(void) |
1007 | { | 1012 | { |
1008 | struct property* of_prop; | 1013 | struct property* of_prop; |
1009 | 1014 | struct device_node *dn; | |
1015 | |||
1010 | of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); | 1016 | of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); |
1011 | if (of_prop && find_path_device("/")) { | 1017 | if (!of_prop) |
1018 | return; | ||
1019 | dn = of_find_node_by_path("/"); | ||
1020 | if (dn) { | ||
1012 | memset(of_prop, -1, sizeof(struct property) + 256); | 1021 | memset(of_prop, -1, sizeof(struct property) + 256); |
1013 | of_prop->name = "pci-OF-bus-map"; | 1022 | of_prop->name = "pci-OF-bus-map"; |
1014 | of_prop->length = 256; | 1023 | of_prop->length = 256; |
1015 | of_prop->value = (unsigned char *)&of_prop[1]; | 1024 | of_prop->value = &of_prop[1]; |
1016 | prom_add_property(find_path_device("/"), of_prop); | 1025 | prom_add_property(dn, of_prop); |
1026 | of_node_put(dn); | ||
1017 | } | 1027 | } |
1018 | } | 1028 | } |
1019 | 1029 | ||