aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci_32.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-27 15:48:29 -0400
committerPaul Mackerras <paulus@samba.org>2008-11-05 06:11:53 -0500
commit53280323350621985b3f2f8ffe649215304bcc5f (patch)
treeec4c126dd620ecb1b36f67fc4201e24fcca6ab18 /arch/powerpc/kernel/pci_32.c
parentb0494bc8ee449f0534afa92a51e2e3bb27bab69b (diff)
powerpc/pci: Use common PHB resource hookup
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>
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r--arch/powerpc/kernel/pci_32.c78
1 files changed, 34 insertions, 44 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index fdcc898e58db..883040358273 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -373,10 +373,41 @@ void pcibios_make_OF_bus_map(void)
373} 373}
374#endif /* CONFIG_PPC_OF */ 374#endif /* CONFIG_PPC_OF */
375 375
376static void __devinit pcibios_scan_phb(struct pci_controller *hose)
377{
378 struct pci_bus *bus;
379 struct device_node *node = hose->dn;
380 unsigned long io_offset;
381 struct resource *res = &hose->io_resource;
382
383 pr_debug("PCI: Scanning PHB %s\n",
384 node ? node->full_name : "<NO NAME>");
385
386 /* Create an empty bus for the toplevel */
387 bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
388 if (bus == NULL) {
389 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
390 hose->global_number);
391 return;
392 }
393 bus->secondary = hose->first_busno;
394 hose->bus = bus;
395
396 /* Fixup IO space offset */
397 io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
398 res->start = (res->start + io_offset) & 0xffffffffu;
399 res->end = (res->end + io_offset) & 0xffffffffu;
400
401 /* Wire up PHB bus resources */
402 pcibios_setup_phb_resources(hose);
403
404 /* Scan children */
405 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
406}
407
376static int __init pcibios_init(void) 408static int __init pcibios_init(void)
377{ 409{
378 struct pci_controller *hose, *tmp; 410 struct pci_controller *hose, *tmp;
379 struct pci_bus *bus;
380 int next_busno = 0; 411 int next_busno = 0;
381 412
382 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 413 printk(KERN_INFO "PCI: Probing PCI hardware\n");
@@ -389,12 +420,8 @@ static int __init pcibios_init(void)
389 if (pci_assign_all_buses) 420 if (pci_assign_all_buses)
390 hose->first_busno = next_busno; 421 hose->first_busno = next_busno;
391 hose->last_busno = 0xff; 422 hose->last_busno = 0xff;
392 bus = pci_scan_bus_parented(hose->parent, hose->first_busno, 423 pcibios_scan_phb(hose);
393 hose->ops, hose); 424 pci_bus_add_devices(hose->bus);
394 if (bus) {
395 pci_bus_add_devices(bus);
396 hose->last_busno = bus->subordinate;
397 }
398 if (pci_assign_all_buses || next_busno <= hose->last_busno) 425 if (pci_assign_all_buses || next_busno <= hose->last_busno)
399 next_busno = hose->last_busno + pcibios_assign_bus_offset; 426 next_busno = hose->last_busno + pcibios_assign_bus_offset;
400 } 427 }
@@ -421,45 +448,8 @@ subsys_initcall(pcibios_init);
421 448
422void __devinit pcibios_do_bus_setup(struct pci_bus *bus) 449void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
423{ 450{
424 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
425 unsigned long io_offset;
426 struct resource *res;
427 int i;
428 struct pci_dev *dev; 451 struct pci_dev *dev;
429 452
430 /* Hookup PHB resources */
431 io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
432 if (bus->parent == NULL) {
433 /* This is a host bridge - fill in its resources */
434 hose->bus = bus;
435
436 bus->resource[0] = res = &hose->io_resource;
437 if (!res->flags) {
438 if (io_offset)
439 printk(KERN_ERR "I/O resource not set for host"
440 " bridge %d\n", hose->global_number);
441 res->start = 0;
442 res->end = IO_SPACE_LIMIT;
443 res->flags = IORESOURCE_IO;
444 }
445 res->start = (res->start + io_offset) & 0xffffffffu;
446 res->end = (res->end + io_offset) & 0xffffffffu;
447
448 for (i = 0; i < 3; ++i) {
449 res = &hose->mem_resources[i];
450 if (!res->flags) {
451 if (i > 0)
452 continue;
453 printk(KERN_ERR "Memory resource not set for "
454 "host bridge %d\n", hose->global_number);
455 res->start = hose->pci_mem_offset;
456 res->end = ~0U;
457 res->flags = IORESOURCE_MEM;
458 }
459 bus->resource[i+1] = res;
460 }
461 }
462
463 if (ppc_md.pci_dma_bus_setup) 453 if (ppc_md.pci_dma_bus_setup)
464 ppc_md.pci_dma_bus_setup(bus); 454 ppc_md.pci_dma_bus_setup(bus);
465 455