aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/pci.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-10-22 01:03:21 -0400
committerPaul Mackerras <paulus@samba.org>2005-10-22 01:03:21 -0400
commitf7abbc190b0edec34627d5348ba1d5fa5577da77 (patch)
treedc6a97aaef1cf9174af7e09329db85be0af13c16 /arch/ppc64/kernel/pci.c
parenta5b518ed314bfd25ea5e433ce09f8b27080023db (diff)
ppc64: Add a `primary' argument to pci_process_bridge_OF_ranges
... for consistency with ppc32 and to make the powermac merge easier. Also make it use just a single resource in the host bridge for multiple consecutive elements of the ranges property. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/ppc64/kernel/pci.c')
-rw-r--r--arch/ppc64/kernel/pci.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index feec06bbafc3..b2fb6746f00b 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -880,9 +880,9 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
880} 880}
881 881
882void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, 882void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
883 struct device_node *dev) 883 struct device_node *dev, int prim)
884{ 884{
885 unsigned int *ranges; 885 unsigned int *ranges, pci_space;
886 unsigned long size; 886 unsigned long size;
887 int rlen = 0; 887 int rlen = 0;
888 int memno = 0; 888 int memno = 0;
@@ -905,16 +905,39 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
905 ranges = (unsigned int *) get_property(dev, "ranges", &rlen); 905 ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
906 while ((rlen -= np * sizeof(unsigned int)) >= 0) { 906 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
907 res = NULL; 907 res = NULL;
908 pci_addr = (unsigned long)ranges[1] << 32 | ranges[2]; 908 pci_space = ranges[0];
909 pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
909 910
910 cpu_phys_addr = ranges[3]; 911 cpu_phys_addr = ranges[3];
911 if (na == 2) 912 if (na >= 2)
912 cpu_phys_addr = cpu_phys_addr << 32 | ranges[4]; 913 cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
913 914
914 size = (unsigned long)ranges[na+3] << 32 | ranges[na+4]; 915 size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
916 ranges += np;
915 if (size == 0) 917 if (size == 0)
916 continue; 918 continue;
917 switch ((ranges[0] >> 24) & 0x3) { 919
920 /* Now consume following elements while they are contiguous */
921 while (rlen >= np * sizeof(unsigned int)) {
922 unsigned long addr, phys;
923
924 if (ranges[0] != pci_space)
925 break;
926 addr = ((unsigned long)ranges[1] << 32) | ranges[2];
927 phys = ranges[3];
928 if (na >= 2)
929 phys = (phys << 32) | ranges[4];
930 if (addr != pci_addr + size ||
931 phys != cpu_phys_addr + size)
932 break;
933
934 size += ((unsigned long)ranges[na+3] << 32)
935 | ranges[na+4];
936 ranges += np;
937 rlen -= np * sizeof(unsigned int);
938 }
939
940 switch ((pci_space >> 24) & 0x3) {
918 case 1: /* I/O space */ 941 case 1: /* I/O space */
919 hose->io_base_phys = cpu_phys_addr; 942 hose->io_base_phys = cpu_phys_addr;
920 hose->pci_io_size = size; 943 hose->pci_io_size = size;
@@ -948,7 +971,6 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
948 res->sibling = NULL; 971 res->sibling = NULL;
949 res->child = NULL; 972 res->child = NULL;
950 } 973 }
951 ranges += np;
952 } 974 }
953} 975}
954 976