]> git.karo-electronics.de Git - linux-beck.git/commitdiff
powerpc/pci: Use common PHB resource hookup
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 27 Oct 2008 19:48:29 +0000 (19:48 +0000)
committerPaul Mackerras <paulus@samba.org>
Wed, 5 Nov 2008 11:11:53 +0000 (22:11 +1100)
The 32-bit and 64-bit powerpc PCI code used to set up the resource
pointers of the root bus of a given PHB in completely different
places.

This unifies this in large part, by making 32-bit use a routine very
similar to what 64-bit does when initially scanning the PCI busses.

The actual setup of the PHB resources itself is then moved to a
common function in pci-common.c.

This should cause no functional change on 64-bit.  On 32-bit, the
effect is that the PHB resources are going to be setup a bit earlier,
instead of being setup from pcibios_fixup_bus().

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c

index 9047af7baa697afad42e89b19f2cfdd893ad7430..2dfa8a3d8c76db1cc5af1543b4ed71ec513e3a48 100644 (file)
@@ -290,6 +290,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 /* Allocate & free a PCI host bridge structure */
 extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
 extern void pcibios_free_controller(struct pci_controller *phb);
+extern void pcibios_setup_phb_resources(struct pci_controller *hose);
 
 #ifdef CONFIG_PCI
 extern unsigned long pci_address_to_pio(phys_addr_t address);
index 09ac98e2a502ae6ae814cb499eb06007153f0b89..6d46bfabdbe431cdf623a7097bceba3160942c2e 100644 (file)
@@ -1421,3 +1421,61 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 
        return pci_enable_resources(dev, mask);
 }
+
+void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+{
+       struct pci_bus *bus = hose->bus;
+       struct resource *res;
+       int i;
+
+       /* Hookup PHB IO resource */
+       bus->resource[0] = res = &hose->io_resource;
+
+       if (!res->flags) {
+               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 */
+       }
+
+       pr_debug("PCI: PHB IO resource    = %016llx-%016llx [%lx]\n",
+                (unsigned long long)res->start,
+                (unsigned long long)res->end,
+                (unsigned long)res->flags);
+
+       /* 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 */
+               }
+               bus->resource[i+1] = res;
+
+               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);
+       }
+
+       pr_debug("PCI: PHB MEM offset     = %016llx\n",
+                (unsigned long long)hose->pci_mem_offset);
+       pr_debug("PCI: PHB IO  offset     = %08lx\n",
+                (unsigned long)hose->io_base_virt - _IO_BASE);
+
+}
+
index fdcc898e58dbe27b2906141bc0f6fdeb4d36785c..883040358273637d4e96f6eb876f078ecd1b56d8 100644 (file)
@@ -373,10 +373,41 @@ void pcibios_make_OF_bus_map(void)
 }
 #endif /* CONFIG_PPC_OF */
 
+static void __devinit pcibios_scan_phb(struct pci_controller *hose)
+{
+       struct pci_bus *bus;
+       struct device_node *node = hose->dn;
+       unsigned long io_offset;
+       struct resource *res = &hose->io_resource;
+
+       pr_debug("PCI: Scanning PHB %s\n",
+                node ? node->full_name : "<NO NAME>");
+
+       /* Create an empty bus for the toplevel */
+       bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
+       if (bus == NULL) {
+               printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+                      hose->global_number);
+               return;
+       }
+       bus->secondary = hose->first_busno;
+       hose->bus = bus;
+
+       /* Fixup IO space offset */
+       io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+       res->start = (res->start + io_offset) & 0xffffffffu;
+       res->end = (res->end + io_offset) & 0xffffffffu;
+
+       /* Wire up PHB bus resources */
+       pcibios_setup_phb_resources(hose);
+
+       /* Scan children */
+       hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+}
+
 static int __init pcibios_init(void)
 {
        struct pci_controller *hose, *tmp;
-       struct pci_bus *bus;
        int next_busno = 0;
 
        printk(KERN_INFO "PCI: Probing PCI hardware\n");
@@ -389,12 +420,8 @@ static int __init pcibios_init(void)
                if (pci_assign_all_buses)
                        hose->first_busno = next_busno;
                hose->last_busno = 0xff;
-               bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
-                                           hose->ops, hose);
-               if (bus) {
-                       pci_bus_add_devices(bus);
-                       hose->last_busno = bus->subordinate;
-               }
+               pcibios_scan_phb(hose);
+               pci_bus_add_devices(hose->bus);
                if (pci_assign_all_buses || next_busno <= hose->last_busno)
                        next_busno = hose->last_busno + pcibios_assign_bus_offset;
        }
@@ -421,45 +448,8 @@ subsys_initcall(pcibios_init);
 
 void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
 {
-       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
-       unsigned long io_offset;
-       struct resource *res;
-       int i;
        struct pci_dev *dev;
 
-       /* Hookup PHB resources */
-       io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
-       if (bus->parent == NULL) {
-               /* This is a host bridge - fill in its resources */
-               hose->bus = bus;
-
-               bus->resource[0] = res = &hose->io_resource;
-               if (!res->flags) {
-                       if (io_offset)
-                               printk(KERN_ERR "I/O resource not set for host"
-                                      " bridge %d\n", hose->global_number);
-                       res->start = 0;
-                       res->end = IO_SPACE_LIMIT;
-                       res->flags = IORESOURCE_IO;
-               }
-               res->start = (res->start + io_offset) & 0xffffffffu;
-               res->end = (res->end + io_offset) & 0xffffffffu;
-
-               for (i = 0; i < 3; ++i) {
-                       res = &hose->mem_resources[i];
-                       if (!res->flags) {
-                               if (i > 0)
-                                       continue;
-                               printk(KERN_ERR "Memory resource not set for "
-                                      "host bridge %d\n", hose->global_number);
-                               res->start = hose->pci_mem_offset;
-                               res->end = ~0U;
-                               res->flags = IORESOURCE_MEM;
-                       }
-                       bus->resource[i+1] = res;
-               }
-       }
-
        if (ppc_md.pci_dma_bus_setup)
                ppc_md.pci_dma_bus_setup(bus);
 
index ffada88a4484c9edb6e9acd80a49753141b9fc81..f5fc547284bca6eb26059928c49ffd3c48478123 100644 (file)
@@ -322,7 +322,7 @@ void __devinit scan_phb(struct pci_controller *hose)
 {
        struct pci_bus *bus;
        struct device_node *node = hose->dn;
-       int i, mode;
+       int mode;
 
        pr_debug("PCI: Scanning PHB %s\n",
                 node ? node->full_name : "<NO NAME>");
@@ -341,20 +341,7 @@ void __devinit scan_phb(struct pci_controller *hose)
        pcibios_map_io_space(bus);
 
        /* Wire up PHB bus resources */
-       pr_debug("PCI: PHB IO resource    = %016lx-%016lx [%lx]\n",
-                hose->io_resource.start, hose->io_resource.end,
-                hose->io_resource.flags);
-       bus->resource[0] = &hose->io_resource;
-       for (i = 0; i < 3; ++i) {
-               pr_debug("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
-                        hose->mem_resources[i].start,
-                        hose->mem_resources[i].end,
-                        hose->mem_resources[i].flags);
-               bus->resource[i+1] = &hose->mem_resources[i];
-       }
-       pr_debug("PCI: PHB MEM offset     = %016lx\n", hose->pci_mem_offset);
-       pr_debug("PCI: PHB IO  offset     = %08lx\n",
-           (unsigned long)hose->io_base_virt - _IO_BASE);
+       pcibios_setup_phb_resources(hose);
 
        /* Get probe mode and perform scan */
        mode = PCI_PROBE_NORMAL;
@@ -376,7 +363,7 @@ static int __init pcibios_init(void)
 
        printk(KERN_INFO "PCI: Probing PCI hardware\n");
 
-       /* For now, override phys_mem_access_prot. If we need it,
+       /* For now, override phys_mem_access_prot. If we need it,g
         * later, we may move that initialization to each ppc_md
         */
        ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;