aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2015-10-20 12:36:53 -0400
committerBjorn Helgaas <bhelgaas@google.com>2015-10-29 18:35:46 -0400
commitaf86fa4001ca5644ae20cc2c52cdf67bb7db9752 (patch)
tree54e20db34eb04b1561900c8b4325408f24a02b62 /arch/sparc
parent597becb4adb7d57b8e9d857a68f764ce96a141b8 (diff)
sparc/PCI: Add mem64 resource parsing for root bus
David reported that a T5-8 sparc system failed to boot with: pci_sun4v f02dbcfc: PCI host bridge to bus 0000:00 pci_bus 0000:00: root bus resource [io 0x804000000000-0x80400fffffff] (bus address [0x0000-0xfffffff]) pci_bus 0000:00: root bus resource [mem 0x800000000000-0x80007effffff] (bus address [0x00000000-0x7effffff]) pci 0000:00:01.0: can't claim BAR 15 [mem 0x100000000-0x4afffffff pref]: no compatible bridge window Note that we don't know about a host bridge aperture that contains BAR 15. OF does report a MEM64 aperture, but before this patch, pci_determine_mem_io_space() ignored it. Add support for host bridge apertures with 64-bit PCI addresses. Also set IORESOURCE_MEM_64 for PCI device and bridge resources in PCI 64-bit memory space. Sparc doesn't actually print the device and bridge resources, but after this patch, we should have the equivalent of this: pci_sun4v f02dbcfc: PCI host bridge to bus 0000:00 pci_bus 0000:00: root bus resource [io 0x804000000000-0x80400fffffff] (bus address [0x0000-0xfffffff]) pci_bus 0000:00: root bus resource [mem 0x800000000000-0x80007effffff] (bus address [0x00000000-0x7effffff]) pci_bus 0000:00: root bus resource [mem 0x800100000000-0x8007ffffffff] (bus address [0x100000000-0x7ffffffff]) pci 0000:00:01.0: bridge window [mem 0x800100000000-0x8004afffffff 64bit pref] [bhelgaas: changelog, URL to David's report] Fixes: d63e2e1f3df9 ("sparc/PCI: Clip bridge windows to fit in upstream windows") Link: http://lkml.kernel.org/r/5514391F.2030300@oracle.com Reported-by: David Ahern <david.ahern@oracle.com> Tested-by: David Ahern <david.ahern@oracle.com> Tested-by: Khalid Aziz <khalid.aziz@oracle.com> Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/pci.c7
-rw-r--r--arch/sparc/kernel/pci_common.c17
-rw-r--r--arch/sparc/kernel/pci_impl.h1
3 files changed, 22 insertions, 3 deletions
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b91d7f146175..badf0951d73c 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -185,8 +185,10 @@ static unsigned long pci_parse_of_flags(u32 addr0)
185 185
186 if (addr0 & 0x02000000) { 186 if (addr0 & 0x02000000) {
187 flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; 187 flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
188 flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
189 flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; 188 flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
189 if (addr0 & 0x01000000)
190 flags |= IORESOURCE_MEM_64
191 | PCI_BASE_ADDRESS_MEM_TYPE_64;
190 if (addr0 & 0x40000000) 192 if (addr0 & 0x40000000)
191 flags |= IORESOURCE_PREFETCH 193 flags |= IORESOURCE_PREFETCH
192 | PCI_BASE_ADDRESS_MEM_PREFETCH; 194 | PCI_BASE_ADDRESS_MEM_PREFETCH;
@@ -655,6 +657,9 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
655 pbm->io_space.start); 657 pbm->io_space.start);
656 pci_add_resource_offset(&resources, &pbm->mem_space, 658 pci_add_resource_offset(&resources, &pbm->mem_space,
657 pbm->mem_space.start); 659 pbm->mem_space.start);
660 if (pbm->mem64_space.flags)
661 pci_add_resource_offset(&resources, &pbm->mem64_space,
662 pbm->mem_space.start);
658 pbm->busn.start = pbm->pci_first_busno; 663 pbm->busn.start = pbm->pci_first_busno;
659 pbm->busn.end = pbm->pci_last_busno; 664 pbm->busn.end = pbm->pci_last_busno;
660 pbm->busn.flags = IORESOURCE_BUS; 665 pbm->busn.flags = IORESOURCE_BUS;
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 944a06536ecc..33524c1d5328 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -406,6 +406,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
406 } 406 }
407 407
408 num_pbm_ranges = i / sizeof(*pbm_ranges); 408 num_pbm_ranges = i / sizeof(*pbm_ranges);
409 memset(&pbm->mem64_space, 0, sizeof(struct resource));
409 410
410 for (i = 0; i < num_pbm_ranges; i++) { 411 for (i = 0; i < num_pbm_ranges; i++) {
411 const struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; 412 const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
@@ -451,7 +452,12 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
451 break; 452 break;
452 453
453 case 3: 454 case 3:
454 /* XXX 64-bit MEM handling XXX */ 455 /* 64-bit MEM handling */
456 pbm->mem64_space.start = a;
457 pbm->mem64_space.end = a + size - 1UL;
458 pbm->mem64_space.flags = IORESOURCE_MEM;
459 saw_mem = 1;
460 break;
455 461
456 default: 462 default:
457 break; 463 break;
@@ -465,15 +471,22 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
465 prom_halt(); 471 prom_halt();
466 } 472 }
467 473
468 printk("%s: PCI IO[%llx] MEM[%llx]\n", 474 printk("%s: PCI IO[%llx] MEM[%llx]",
469 pbm->name, 475 pbm->name,
470 pbm->io_space.start, 476 pbm->io_space.start,
471 pbm->mem_space.start); 477 pbm->mem_space.start);
478 if (pbm->mem64_space.flags)
479 printk(" MEM64[%llx]",
480 pbm->mem64_space.start);
481 printk("\n");
472 482
473 pbm->io_space.name = pbm->mem_space.name = pbm->name; 483 pbm->io_space.name = pbm->mem_space.name = pbm->name;
484 pbm->mem64_space.name = pbm->name;
474 485
475 request_resource(&ioport_resource, &pbm->io_space); 486 request_resource(&ioport_resource, &pbm->io_space);
476 request_resource(&iomem_resource, &pbm->mem_space); 487 request_resource(&iomem_resource, &pbm->mem_space);
488 if (pbm->mem64_space.flags)
489 request_resource(&iomem_resource, &pbm->mem64_space);
477 490
478 pci_register_legacy_regions(&pbm->io_space, 491 pci_register_legacy_regions(&pbm->io_space,
479 &pbm->mem_space); 492 &pbm->mem_space);
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 75803c780af3..37222ca849df 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -97,6 +97,7 @@ struct pci_pbm_info {
97 /* PBM I/O and Memory space resources. */ 97 /* PBM I/O and Memory space resources. */
98 struct resource io_space; 98 struct resource io_space;
99 struct resource mem_space; 99 struct resource mem_space;
100 struct resource mem64_space;
100 struct resource busn; 101 struct resource busn;
101 102
102 /* Base of PCI Config space, can be per-PBM or shared. */ 103 /* Base of PCI Config space, can be per-PBM or shared. */