aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-03-16 19:48:24 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-03-20 13:42:01 -0400
commita031589bc04086250d0a4d89dd277a70d74ed8fa (patch)
tree8e5be9945ffc950952d86b970c92af8738a9fe45 /arch/sparc
parentc0f209468e8b6c81b28f6417e7d88c99171d20b6 (diff)
sparc/PCI: convert devtree and arch-probed bus addresses to resource
Normal PCI enumeration via PCI config space uses __pci_read_base(), where the PCI core applies any bus-to-resource offset. But sparc sometimes reads PCI config space itself, and sometimes it gets addresses from the device tree. In ac1edcc579b6, I converted sparc to use the PCI core bus-to-resource conversion, but I missed these sparc-specific paths. I don't have a way to test it, but I think sparc is broken between that commit and this one. This patch replaces the sparc-specific pci_resource_adjust() with the generic pcibios_bus_to_resource() in the following paths: pci_cfg_fake_ranges() (addresses read from PCI config) apb_fake_ranges() (addresses computed based on PCI config) of_scan_pci_bridge() (addresses from OF "ranges" property) N.B.: Resources of non-P2P bridge devices are set in pci_parse_of_addrs() and, as far as I can see, never converted to CPU addresses. I do not understand why these would be treated differently than bridge windows. CC: "David S. Miller" <davem@davemloft.net> CC: sparclinux@vger.kernel.org Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/pci.c60
1 files changed, 25 insertions, 35 deletions
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 253e8ac2783f..fdaf21811670 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -375,13 +375,6 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p)
375 *last_p = last; 375 *last_p = last;
376} 376}
377 377
378static void pci_resource_adjust(struct resource *res,
379 struct resource *root)
380{
381 res->start += root->start;
382 res->end += root->start;
383}
384
385/* For PCI bus devices which lack a 'ranges' property we interrogate 378/* For PCI bus devices which lack a 'ranges' property we interrogate
386 * the config space values to set the resources, just like the generic 379 * the config space values to set the resources, just like the generic
387 * Linux PCI probing code does. 380 * Linux PCI probing code does.
@@ -390,7 +383,8 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
390 struct pci_bus *bus, 383 struct pci_bus *bus,
391 struct pci_pbm_info *pbm) 384 struct pci_pbm_info *pbm)
392{ 385{
393 struct resource *res; 386 struct pci_bus_region region;
387 struct resource *res, res2;
394 u8 io_base_lo, io_limit_lo; 388 u8 io_base_lo, io_limit_lo;
395 u16 mem_base_lo, mem_limit_lo; 389 u16 mem_base_lo, mem_limit_lo;
396 unsigned long base, limit; 390 unsigned long base, limit;
@@ -412,11 +406,14 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
412 res = bus->resource[0]; 406 res = bus->resource[0];
413 if (base <= limit) { 407 if (base <= limit) {
414 res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; 408 res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
409 res2.flags = res->flags;
410 region.start = base;
411 region.end = limit + 0xfff;
412 pcibios_bus_to_resource(dev, &res2, &region);
415 if (!res->start) 413 if (!res->start)
416 res->start = base; 414 res->start = res2.start;
417 if (!res->end) 415 if (!res->end)
418 res->end = limit + 0xfff; 416 res->end = res2.end;
419 pci_resource_adjust(res, &pbm->io_space);
420 } 417 }
421 418
422 pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); 419 pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
@@ -428,9 +425,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
428 if (base <= limit) { 425 if (base <= limit) {
429 res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | 426 res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) |
430 IORESOURCE_MEM); 427 IORESOURCE_MEM);
431 res->start = base; 428 region.start = base;
432 res->end = limit + 0xfffff; 429 region.end = limit + 0xfffff;
433 pci_resource_adjust(res, &pbm->mem_space); 430 pcibios_bus_to_resource(dev, res, &region);
434 } 431 }
435 432
436 pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); 433 pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
@@ -459,9 +456,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev,
459 if (base <= limit) { 456 if (base <= limit) {
460 res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | 457 res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) |
461 IORESOURCE_MEM | IORESOURCE_PREFETCH); 458 IORESOURCE_MEM | IORESOURCE_PREFETCH);
462 res->start = base; 459 region.start = base;
463 res->end = limit + 0xfffff; 460 region.end = limit + 0xfffff;
464 pci_resource_adjust(res, &pbm->mem_space); 461 pcibios_bus_to_resource(dev, res, &region);
465 } 462 }
466} 463}
467 464
@@ -472,6 +469,7 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev,
472 struct pci_bus *bus, 469 struct pci_bus *bus,
473 struct pci_pbm_info *pbm) 470 struct pci_pbm_info *pbm)
474{ 471{
472 struct pci_bus_region region;
475 struct resource *res; 473 struct resource *res;
476 u32 first, last; 474 u32 first, last;
477 u8 map; 475 u8 map;
@@ -479,18 +477,18 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev,
479 pci_read_config_byte(dev, APB_IO_ADDRESS_MAP, &map); 477 pci_read_config_byte(dev, APB_IO_ADDRESS_MAP, &map);
480 apb_calc_first_last(map, &first, &last); 478 apb_calc_first_last(map, &first, &last);
481 res = bus->resource[0]; 479 res = bus->resource[0];
482 res->start = (first << 21);
483 res->end = (last << 21) + ((1 << 21) - 1);
484 res->flags = IORESOURCE_IO; 480 res->flags = IORESOURCE_IO;
485 pci_resource_adjust(res, &pbm->io_space); 481 region.start = (first << 21);
482 region.end = (last << 21) + ((1 << 21) - 1);
483 pcibios_bus_to_resource(dev, res, &region);
486 484
487 pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map); 485 pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map);
488 apb_calc_first_last(map, &first, &last); 486 apb_calc_first_last(map, &first, &last);
489 res = bus->resource[1]; 487 res = bus->resource[1];
490 res->start = (first << 21);
491 res->end = (last << 21) + ((1 << 21) - 1);
492 res->flags = IORESOURCE_MEM; 488 res->flags = IORESOURCE_MEM;
493 pci_resource_adjust(res, &pbm->mem_space); 489 region.start = (first << 21);
490 region.end = (last << 21) + ((1 << 21) - 1);
491 pcibios_bus_to_resource(dev, res, &region);
494} 492}
495 493
496static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, 494static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
@@ -506,6 +504,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
506 struct pci_bus *bus; 504 struct pci_bus *bus;
507 const u32 *busrange, *ranges; 505 const u32 *busrange, *ranges;
508 int len, i, simba; 506 int len, i, simba;
507 struct pci_bus_region region;
509 struct resource *res; 508 struct resource *res;
510 unsigned int flags; 509 unsigned int flags;
511 u64 size; 510 u64 size;
@@ -556,8 +555,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
556 } 555 }
557 i = 1; 556 i = 1;
558 for (; len >= 32; len -= 32, ranges += 8) { 557 for (; len >= 32; len -= 32, ranges += 8) {
559 struct resource *root;
560
561 flags = pci_parse_of_flags(ranges[0]); 558 flags = pci_parse_of_flags(ranges[0]);
562 size = GET_64BIT(ranges, 6); 559 size = GET_64BIT(ranges, 6);
563 if (flags == 0 || size == 0) 560 if (flags == 0 || size == 0)
@@ -569,7 +566,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
569 " for bridge %s\n", node->full_name); 566 " for bridge %s\n", node->full_name);
570 continue; 567 continue;
571 } 568 }
572 root = &pbm->io_space;
573 } else { 569 } else {
574 if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { 570 if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
575 printk(KERN_ERR "PCI: too many memory ranges" 571 printk(KERN_ERR "PCI: too many memory ranges"
@@ -578,18 +574,12 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
578 } 574 }
579 res = bus->resource[i]; 575 res = bus->resource[i];
580 ++i; 576 ++i;
581 root = &pbm->mem_space;
582 } 577 }
583 578
584 res->start = GET_64BIT(ranges, 1);
585 res->end = res->start + size - 1;
586 res->flags = flags; 579 res->flags = flags;
587 580 region.start = GET_64BIT(ranges, 1);
588 /* Another way to implement this would be to add an of_device 581 region.end = region.start + size - 1;
589 * layer routine that can calculate a resource for a given 582 pcibios_bus_to_resource(dev, res, &region);
590 * range property value in a PCI device.
591 */
592 pci_resource_adjust(res, root);
593 } 583 }
594after_ranges: 584after_ranges:
595 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), 585 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),