]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kernel/pci-common.c
powerpc/pci: Support per-aperture memory offset
[karo-tx-linux.git] / arch / powerpc / kernel / pci-common.c
index cf00588b0023ba37ee74c46191f9a726c96465d8..f5c5c90799a763eb2a188316ea95e5d761ffe232 100644 (file)
@@ -786,22 +786,8 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
                                hose->isa_mem_size = size;
                        }
 
-                       /* We get the PCI/Mem offset from the first range or
-                        * the, current one if the offset came from an ISA
-                        * hole. If they don't match, bugger.
-                        */
-                       if (memno == 0 ||
-                           (isa_hole >= 0 && pci_addr != 0 &&
-                            hose->pci_mem_offset == isa_mb))
-                               hose->pci_mem_offset = cpu_addr - pci_addr;
-                       else if (pci_addr != 0 &&
-                                hose->pci_mem_offset != cpu_addr - pci_addr) {
-                               printk(KERN_INFO
-                                      " \\--> Skipped (offset mismatch) !\n");
-                               continue;
-                       }
-
                        /* Build resource */
+                       hose->mem_offset[memno] = cpu_addr - pci_addr;
                        res = &hose->mem_resources[memno++];
                        res->flags = IORESOURCE_MEM;
                        if (pci_space & 0x40000000)
@@ -817,20 +803,6 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
                        res->child = NULL;
                }
        }
-
-       /* If there's an ISA hole and the pci_mem_offset is -not- matching
-        * the ISA hole offset, then we need to remove the ISA hole from
-        * the resource list for that brige
-        */
-       if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) {
-               unsigned int next = isa_hole + 1;
-               printk(KERN_INFO " Removing ISA hole at 0x%016llx\n", isa_mb);
-               if (next < memno)
-                       memmove(&hose->mem_resources[isa_hole],
-                               &hose->mem_resources[next],
-                               sizeof(struct resource) * (memno - next));
-               hose->mem_resources[--memno].flags = 0;
-       }
 }
 
 /* Decide whether to display the domain number in /proc */
@@ -916,6 +888,7 @@ static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
        struct pci_controller *hose = pci_bus_to_host(bus);
        struct pci_dev *dev = bus->self;
        resource_size_t offset;
+       struct pci_bus_region region;
        u16 command;
        int i;
 
@@ -925,10 +898,10 @@ static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
 
        /* Job is a bit different between memory and IO */
        if (res->flags & IORESOURCE_MEM) {
-               /* If the BAR is non-0 (res != pci_mem_offset) then it's probably been
-                * initialized by somebody
-                */
-               if (res->start != hose->pci_mem_offset)
+               pcibios_resource_to_bus(dev, &region, res);
+
+               /* If the BAR is non-0 then it's probably been initialized */
+               if (region.start != 0)
                        return 0;
 
                /* The BAR is 0, let's check if memory decoding is enabled on
@@ -940,11 +913,11 @@ static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
 
                /* Memory decoding is enabled and the BAR is 0. If any of the bridge
                 * resources covers that starting address (0 then it's good enough for
-                * us for memory
+                * us for memory space)
                 */
                for (i = 0; i < 3; i++) {
                        if ((hose->mem_resources[i].flags & IORESOURCE_MEM) &&
-                           hose->mem_resources[i].start == hose->pci_mem_offset)
+                           hose->mem_resources[i].start == hose->mem_offset[i])
                                return 0;
                }
 
@@ -1381,10 +1354,9 @@ static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus)
 
  no_io:
        /* Check for memory */
-       offset = hose->pci_mem_offset;
-       pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset);
        for (i = 0; i < 3; i++) {
                pres = &hose->mem_resources[i];
+               offset = hose->mem_offset[i];
                if (!(pres->flags & IORESOURCE_MEM))
                        continue;
                pr_debug("hose mem res: %pR\n", pres);
@@ -1524,6 +1496,7 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,
                                        struct list_head *resources)
 {
        struct resource *res;
+       resource_size_t offset;
        int i;
 
        /* Hookup PHB IO resource */
@@ -1533,51 +1506,37 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,
                printk(KERN_WARNING "PCI: I/O resource not set for host"
                       " bridge %s (domain %d)\n",
                       hose->dn->full_name, hose->global_number);
-#ifdef CONFIG_PPC32
-               /* Workaround for lack of IO resource only on 32-bit */
-               res->start = (unsigned long)hose->io_base_virt - isa_io_base;
-               res->end = res->start + IO_SPACE_LIMIT;
-               res->flags = IORESOURCE_IO;
-#endif /* CONFIG_PPC32 */
-       }
-       if (res->flags) {
-               pr_debug("PCI: PHB IO resource    = %016llx-%016llx [%lx]\n",
+       } else {
+               offset = pcibios_io_space_offset(hose);
+
+               pr_debug("PCI: PHB IO resource    = %08llx-%08llx [%lx] off 0x%08llx\n",
                         (unsigned long long)res->start,
                         (unsigned long long)res->end,
-                        (unsigned long)res->flags);
-               pci_add_resource_offset(resources, res, pcibios_io_space_offset(hose));
-
-               pr_debug("PCI: PHB IO  offset     = %08lx\n",
-                        (unsigned long)hose->io_base_virt - _IO_BASE);
+                        (unsigned long)res->flags,
+                        (unsigned long long)offset);
+               pci_add_resource_offset(resources, res, offset);
        }
 
        /* Hookup PHB Memory resources */
        for (i = 0; i < 3; ++i) {
                res = &hose->mem_resources[i];
                if (!res->flags) {
-                       if (i > 0)
-                               continue;
                        printk(KERN_ERR "PCI: Memory resource 0 not set for "
                               "host bridge %s (domain %d)\n",
                               hose->dn->full_name, hose->global_number);
-#ifdef CONFIG_PPC32
-                       /* Workaround for lack of MEM resource only on 32-bit */
-                       res->start = hose->pci_mem_offset;
-                       res->end = (resource_size_t)-1LL;
-                       res->flags = IORESOURCE_MEM;
-#endif /* CONFIG_PPC32 */
-               }
-               if (res->flags) {
-                       pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
-                                (unsigned long long)res->start,
-                                (unsigned long long)res->end,
-                                (unsigned long)res->flags);
-                       pci_add_resource_offset(resources, res, hose->pci_mem_offset);
+                       continue;
                }
-       }
+               offset = hose->mem_offset[i];
 
-       pr_debug("PCI: PHB MEM offset     = %016llx\n",
-                (unsigned long long)hose->pci_mem_offset);
+
+               pr_debug("PCI: PHB MEM resource %d = %08llx-%08llx [%lx] off 0x%08llx\n", i,
+                        (unsigned long long)res->start,
+                        (unsigned long long)res->end,
+                        (unsigned long)res->flags,
+                        (unsigned long long)offset);
+
+               pci_add_resource_offset(resources, res, offset);
+       }
 }
 
 /*