diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-27 15:48:29 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-11-05 06:11:53 -0500 |
commit | 53280323350621985b3f2f8ffe649215304bcc5f (patch) | |
tree | ec4c126dd620ecb1b36f67fc4201e24fcca6ab18 /arch/powerpc/kernel/pci_32.c | |
parent | b0494bc8ee449f0534afa92a51e2e3bb27bab69b (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.c | 78 |
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 | ||
376 | static 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 | |||
376 | static int __init pcibios_init(void) | 408 | static 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 | ||
422 | void __devinit pcibios_do_bus_setup(struct pci_bus *bus) | 449 | void __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 | ||