aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
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
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')
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h1
-rw-r--r--arch/powerpc/kernel/pci-common.c58
-rw-r--r--arch/powerpc/kernel/pci_32.c78
-rw-r--r--arch/powerpc/kernel/pci_64.c19
4 files changed, 96 insertions, 60 deletions
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 9047af7baa69..2dfa8a3d8c76 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -290,6 +290,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
290/* Allocate & free a PCI host bridge structure */ 290/* Allocate & free a PCI host bridge structure */
291extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); 291extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
292extern void pcibios_free_controller(struct pci_controller *phb); 292extern void pcibios_free_controller(struct pci_controller *phb);
293extern void pcibios_setup_phb_resources(struct pci_controller *hose);
293 294
294#ifdef CONFIG_PCI 295#ifdef CONFIG_PCI
295extern unsigned long pci_address_to_pio(phys_addr_t address); 296extern unsigned long pci_address_to_pio(phys_addr_t address);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 09ac98e2a502..6d46bfabdbe4 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1421,3 +1421,61 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
1421 1421
1422 return pci_enable_resources(dev, mask); 1422 return pci_enable_resources(dev, mask);
1423} 1423}
1424
1425void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
1426{
1427 struct pci_bus *bus = hose->bus;
1428 struct resource *res;
1429 int i;
1430
1431 /* Hookup PHB IO resource */
1432 bus->resource[0] = res = &hose->io_resource;
1433
1434 if (!res->flags) {
1435 printk(KERN_WARNING "PCI: I/O resource not set for host"
1436 " bridge %s (domain %d)\n",
1437 hose->dn->full_name, hose->global_number);
1438#ifdef CONFIG_PPC32
1439 /* Workaround for lack of IO resource only on 32-bit */
1440 res->start = (unsigned long)hose->io_base_virt - isa_io_base;
1441 res->end = res->start + IO_SPACE_LIMIT;
1442 res->flags = IORESOURCE_IO;
1443#endif /* CONFIG_PPC32 */
1444 }
1445
1446 pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n",
1447 (unsigned long long)res->start,
1448 (unsigned long long)res->end,
1449 (unsigned long)res->flags);
1450
1451 /* Hookup PHB Memory resources */
1452 for (i = 0; i < 3; ++i) {
1453 res = &hose->mem_resources[i];
1454 if (!res->flags) {
1455 if (i > 0)
1456 continue;
1457 printk(KERN_ERR "PCI: Memory resource 0 not set for "
1458 "host bridge %s (domain %d)\n",
1459 hose->dn->full_name, hose->global_number);
1460#ifdef CONFIG_PPC32
1461 /* Workaround for lack of MEM resource only on 32-bit */
1462 res->start = hose->pci_mem_offset;
1463 res->end = (resource_size_t)-1LL;
1464 res->flags = IORESOURCE_MEM;
1465#endif /* CONFIG_PPC32 */
1466 }
1467 bus->resource[i+1] = res;
1468
1469 pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
1470 (unsigned long long)res->start,
1471 (unsigned long long)res->end,
1472 (unsigned long)res->flags);
1473 }
1474
1475 pr_debug("PCI: PHB MEM offset = %016llx\n",
1476 (unsigned long long)hose->pci_mem_offset);
1477 pr_debug("PCI: PHB IO offset = %08lx\n",
1478 (unsigned long)hose->io_base_virt - _IO_BASE);
1479
1480}
1481
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
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ffada88a4484..f5fc547284bc 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -322,7 +322,7 @@ void __devinit scan_phb(struct pci_controller *hose)
322{ 322{
323 struct pci_bus *bus; 323 struct pci_bus *bus;
324 struct device_node *node = hose->dn; 324 struct device_node *node = hose->dn;
325 int i, mode; 325 int mode;
326 326
327 pr_debug("PCI: Scanning PHB %s\n", 327 pr_debug("PCI: Scanning PHB %s\n",
328 node ? node->full_name : "<NO NAME>"); 328 node ? node->full_name : "<NO NAME>");
@@ -341,20 +341,7 @@ void __devinit scan_phb(struct pci_controller *hose)
341 pcibios_map_io_space(bus); 341 pcibios_map_io_space(bus);
342 342
343 /* Wire up PHB bus resources */ 343 /* Wire up PHB bus resources */
344 pr_debug("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", 344 pcibios_setup_phb_resources(hose);
345 hose->io_resource.start, hose->io_resource.end,
346 hose->io_resource.flags);
347 bus->resource[0] = &hose->io_resource;
348 for (i = 0; i < 3; ++i) {
349 pr_debug("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
350 hose->mem_resources[i].start,
351 hose->mem_resources[i].end,
352 hose->mem_resources[i].flags);
353 bus->resource[i+1] = &hose->mem_resources[i];
354 }
355 pr_debug("PCI: PHB MEM offset = %016lx\n", hose->pci_mem_offset);
356 pr_debug("PCI: PHB IO offset = %08lx\n",
357 (unsigned long)hose->io_base_virt - _IO_BASE);
358 345
359 /* Get probe mode and perform scan */ 346 /* Get probe mode and perform scan */
360 mode = PCI_PROBE_NORMAL; 347 mode = PCI_PROBE_NORMAL;
@@ -376,7 +363,7 @@ static int __init pcibios_init(void)
376 363
377 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 364 printk(KERN_INFO "PCI: Probing PCI hardware\n");
378 365
379 /* For now, override phys_mem_access_prot. If we need it, 366 /* For now, override phys_mem_access_prot. If we need it,g
380 * later, we may move that initialization to each ppc_md 367 * later, we may move that initialization to each ppc_md
381 */ 368 */
382 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; 369 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;