diff options
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 101 |
1 files changed, 35 insertions, 66 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f325dc923409..f5c5c90799a7 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -786,22 +786,8 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
786 | hose->isa_mem_size = size; | 786 | hose->isa_mem_size = size; |
787 | } | 787 | } |
788 | 788 | ||
789 | /* We get the PCI/Mem offset from the first range or | ||
790 | * the, current one if the offset came from an ISA | ||
791 | * hole. If they don't match, bugger. | ||
792 | */ | ||
793 | if (memno == 0 || | ||
794 | (isa_hole >= 0 && pci_addr != 0 && | ||
795 | hose->pci_mem_offset == isa_mb)) | ||
796 | hose->pci_mem_offset = cpu_addr - pci_addr; | ||
797 | else if (pci_addr != 0 && | ||
798 | hose->pci_mem_offset != cpu_addr - pci_addr) { | ||
799 | printk(KERN_INFO | ||
800 | " \\--> Skipped (offset mismatch) !\n"); | ||
801 | continue; | ||
802 | } | ||
803 | |||
804 | /* Build resource */ | 789 | /* Build resource */ |
790 | hose->mem_offset[memno] = cpu_addr - pci_addr; | ||
805 | res = &hose->mem_resources[memno++]; | 791 | res = &hose->mem_resources[memno++]; |
806 | res->flags = IORESOURCE_MEM; | 792 | res->flags = IORESOURCE_MEM; |
807 | if (pci_space & 0x40000000) | 793 | if (pci_space & 0x40000000) |
@@ -817,20 +803,6 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
817 | res->child = NULL; | 803 | res->child = NULL; |
818 | } | 804 | } |
819 | } | 805 | } |
820 | |||
821 | /* If there's an ISA hole and the pci_mem_offset is -not- matching | ||
822 | * the ISA hole offset, then we need to remove the ISA hole from | ||
823 | * the resource list for that brige | ||
824 | */ | ||
825 | if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) { | ||
826 | unsigned int next = isa_hole + 1; | ||
827 | printk(KERN_INFO " Removing ISA hole at 0x%016llx\n", isa_mb); | ||
828 | if (next < memno) | ||
829 | memmove(&hose->mem_resources[isa_hole], | ||
830 | &hose->mem_resources[next], | ||
831 | sizeof(struct resource) * (memno - next)); | ||
832 | hose->mem_resources[--memno].flags = 0; | ||
833 | } | ||
834 | } | 806 | } |
835 | 807 | ||
836 | /* Decide whether to display the domain number in /proc */ | 808 | /* Decide whether to display the domain number in /proc */ |
@@ -845,6 +817,14 @@ int pci_proc_domain(struct pci_bus *bus) | |||
845 | return 1; | 817 | return 1; |
846 | } | 818 | } |
847 | 819 | ||
820 | int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
821 | { | ||
822 | if (ppc_md.pcibios_root_bridge_prepare) | ||
823 | return ppc_md.pcibios_root_bridge_prepare(bridge); | ||
824 | |||
825 | return 0; | ||
826 | } | ||
827 | |||
848 | /* This header fixup will do the resource fixup for all devices as they are | 828 | /* This header fixup will do the resource fixup for all devices as they are |
849 | * probed, but not for bridge ranges | 829 | * probed, but not for bridge ranges |
850 | */ | 830 | */ |
@@ -908,6 +888,7 @@ static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, | |||
908 | struct pci_controller *hose = pci_bus_to_host(bus); | 888 | struct pci_controller *hose = pci_bus_to_host(bus); |
909 | struct pci_dev *dev = bus->self; | 889 | struct pci_dev *dev = bus->self; |
910 | resource_size_t offset; | 890 | resource_size_t offset; |
891 | struct pci_bus_region region; | ||
911 | u16 command; | 892 | u16 command; |
912 | int i; | 893 | int i; |
913 | 894 | ||
@@ -917,10 +898,10 @@ static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, | |||
917 | 898 | ||
918 | /* Job is a bit different between memory and IO */ | 899 | /* Job is a bit different between memory and IO */ |
919 | if (res->flags & IORESOURCE_MEM) { | 900 | if (res->flags & IORESOURCE_MEM) { |
920 | /* If the BAR is non-0 (res != pci_mem_offset) then it's probably been | 901 | pcibios_resource_to_bus(dev, ®ion, res); |
921 | * initialized by somebody | 902 | |
922 | */ | 903 | /* If the BAR is non-0 then it's probably been initialized */ |
923 | if (res->start != hose->pci_mem_offset) | 904 | if (region.start != 0) |
924 | return 0; | 905 | return 0; |
925 | 906 | ||
926 | /* The BAR is 0, let's check if memory decoding is enabled on | 907 | /* The BAR is 0, let's check if memory decoding is enabled on |
@@ -932,11 +913,11 @@ static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, | |||
932 | 913 | ||
933 | /* Memory decoding is enabled and the BAR is 0. If any of the bridge | 914 | /* Memory decoding is enabled and the BAR is 0. If any of the bridge |
934 | * resources covers that starting address (0 then it's good enough for | 915 | * resources covers that starting address (0 then it's good enough for |
935 | * us for memory | 916 | * us for memory space) |
936 | */ | 917 | */ |
937 | for (i = 0; i < 3; i++) { | 918 | for (i = 0; i < 3; i++) { |
938 | if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && | 919 | if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && |
939 | hose->mem_resources[i].start == hose->pci_mem_offset) | 920 | hose->mem_resources[i].start == hose->mem_offset[i]) |
940 | return 0; | 921 | return 0; |
941 | } | 922 | } |
942 | 923 | ||
@@ -1373,10 +1354,9 @@ static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus) | |||
1373 | 1354 | ||
1374 | no_io: | 1355 | no_io: |
1375 | /* Check for memory */ | 1356 | /* Check for memory */ |
1376 | offset = hose->pci_mem_offset; | ||
1377 | pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset); | ||
1378 | for (i = 0; i < 3; i++) { | 1357 | for (i = 0; i < 3; i++) { |
1379 | pres = &hose->mem_resources[i]; | 1358 | pres = &hose->mem_resources[i]; |
1359 | offset = hose->mem_offset[i]; | ||
1380 | if (!(pres->flags & IORESOURCE_MEM)) | 1360 | if (!(pres->flags & IORESOURCE_MEM)) |
1381 | continue; | 1361 | continue; |
1382 | pr_debug("hose mem res: %pR\n", pres); | 1362 | pr_debug("hose mem res: %pR\n", pres); |
@@ -1516,6 +1496,7 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, | |||
1516 | struct list_head *resources) | 1496 | struct list_head *resources) |
1517 | { | 1497 | { |
1518 | struct resource *res; | 1498 | struct resource *res; |
1499 | resource_size_t offset; | ||
1519 | int i; | 1500 | int i; |
1520 | 1501 | ||
1521 | /* Hookup PHB IO resource */ | 1502 | /* Hookup PHB IO resource */ |
@@ -1525,49 +1506,37 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, | |||
1525 | printk(KERN_WARNING "PCI: I/O resource not set for host" | 1506 | printk(KERN_WARNING "PCI: I/O resource not set for host" |
1526 | " bridge %s (domain %d)\n", | 1507 | " bridge %s (domain %d)\n", |
1527 | hose->dn->full_name, hose->global_number); | 1508 | hose->dn->full_name, hose->global_number); |
1528 | #ifdef CONFIG_PPC32 | 1509 | } else { |
1529 | /* Workaround for lack of IO resource only on 32-bit */ | 1510 | offset = pcibios_io_space_offset(hose); |
1530 | res->start = (unsigned long)hose->io_base_virt - isa_io_base; | ||
1531 | res->end = res->start + IO_SPACE_LIMIT; | ||
1532 | res->flags = IORESOURCE_IO; | ||
1533 | #endif /* CONFIG_PPC32 */ | ||
1534 | } | ||
1535 | 1511 | ||
1536 | pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", | 1512 | pr_debug("PCI: PHB IO resource = %08llx-%08llx [%lx] off 0x%08llx\n", |
1537 | (unsigned long long)res->start, | 1513 | (unsigned long long)res->start, |
1538 | (unsigned long long)res->end, | 1514 | (unsigned long long)res->end, |
1539 | (unsigned long)res->flags); | 1515 | (unsigned long)res->flags, |
1540 | pci_add_resource_offset(resources, res, pcibios_io_space_offset(hose)); | 1516 | (unsigned long long)offset); |
1517 | pci_add_resource_offset(resources, res, offset); | ||
1518 | } | ||
1541 | 1519 | ||
1542 | /* Hookup PHB Memory resources */ | 1520 | /* Hookup PHB Memory resources */ |
1543 | for (i = 0; i < 3; ++i) { | 1521 | for (i = 0; i < 3; ++i) { |
1544 | res = &hose->mem_resources[i]; | 1522 | res = &hose->mem_resources[i]; |
1545 | if (!res->flags) { | 1523 | if (!res->flags) { |
1546 | if (i > 0) | ||
1547 | continue; | ||
1548 | printk(KERN_ERR "PCI: Memory resource 0 not set for " | 1524 | printk(KERN_ERR "PCI: Memory resource 0 not set for " |
1549 | "host bridge %s (domain %d)\n", | 1525 | "host bridge %s (domain %d)\n", |
1550 | hose->dn->full_name, hose->global_number); | 1526 | hose->dn->full_name, hose->global_number); |
1551 | #ifdef CONFIG_PPC32 | 1527 | continue; |
1552 | /* Workaround for lack of MEM resource only on 32-bit */ | ||
1553 | res->start = hose->pci_mem_offset; | ||
1554 | res->end = (resource_size_t)-1LL; | ||
1555 | res->flags = IORESOURCE_MEM; | ||
1556 | #endif /* CONFIG_PPC32 */ | ||
1557 | } | 1528 | } |
1529 | offset = hose->mem_offset[i]; | ||
1558 | 1530 | ||
1559 | pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i, | 1531 | |
1532 | pr_debug("PCI: PHB MEM resource %d = %08llx-%08llx [%lx] off 0x%08llx\n", i, | ||
1560 | (unsigned long long)res->start, | 1533 | (unsigned long long)res->start, |
1561 | (unsigned long long)res->end, | 1534 | (unsigned long long)res->end, |
1562 | (unsigned long)res->flags); | 1535 | (unsigned long)res->flags, |
1563 | pci_add_resource_offset(resources, res, hose->pci_mem_offset); | 1536 | (unsigned long long)offset); |
1564 | } | ||
1565 | |||
1566 | pr_debug("PCI: PHB MEM offset = %016llx\n", | ||
1567 | (unsigned long long)hose->pci_mem_offset); | ||
1568 | pr_debug("PCI: PHB IO offset = %08lx\n", | ||
1569 | (unsigned long)hose->io_base_virt - _IO_BASE); | ||
1570 | 1537 | ||
1538 | pci_add_resource_offset(resources, res, offset); | ||
1539 | } | ||
1571 | } | 1540 | } |
1572 | 1541 | ||
1573 | /* | 1542 | /* |