diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-08 21:15:23 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-08 21:15:23 -0400 |
| commit | 7ac7834765e1c888ab06f677d906179858627f26 (patch) | |
| tree | b08e3a4c652fac9e300dcfa3b6fbe094c6c9a77a | |
| parent | 5b65c09e9966cae543d4727984f098b699aa1653 (diff) | |
| parent | 8c2786cfa6d15c474ec7030e8161c88e9b5c597d (diff) | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC64]: Handle PCI bridges without 'ranges' property.
[SPARC64]: Include <linux/rwsem.h> instead of <asm/rwsem.h>.
| -rw-r--r-- | arch/sparc64/kernel/of_device.c | 19 | ||||
| -rw-r--r-- | arch/sparc64/kernel/pci.c | 97 | ||||
| -rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 2 |
3 files changed, 104 insertions, 14 deletions
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 16cc46a71872..6676b93219dc 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
| @@ -343,6 +343,15 @@ static int of_bus_simba_match(struct device_node *np) | |||
| 343 | 343 | ||
| 344 | if (model && !strcmp(model, "SUNW,simba")) | 344 | if (model && !strcmp(model, "SUNW,simba")) |
| 345 | return 1; | 345 | return 1; |
| 346 | |||
| 347 | /* Treat PCI busses lacking ranges property just like | ||
| 348 | * simba. | ||
| 349 | */ | ||
| 350 | if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { | ||
| 351 | if (!of_find_property(np, "ranges", NULL)) | ||
| 352 | return 1; | ||
| 353 | } | ||
| 354 | |||
| 346 | return 0; | 355 | return 0; |
| 347 | } | 356 | } |
| 348 | 357 | ||
| @@ -549,8 +558,6 @@ static int __init build_one_resource(struct device_node *parent, | |||
| 549 | 558 | ||
| 550 | static int __init use_1to1_mapping(struct device_node *pp) | 559 | static int __init use_1to1_mapping(struct device_node *pp) |
| 551 | { | 560 | { |
| 552 | const char *model; | ||
| 553 | |||
| 554 | /* If this is on the PMU bus, don't try to translate it even | 561 | /* If this is on the PMU bus, don't try to translate it even |
| 555 | * if a ranges property exists. | 562 | * if a ranges property exists. |
| 556 | */ | 563 | */ |
| @@ -567,9 +574,11 @@ static int __init use_1to1_mapping(struct device_node *pp) | |||
| 567 | if (!strcmp(pp->name, "dma")) | 574 | if (!strcmp(pp->name, "dma")) |
| 568 | return 0; | 575 | return 0; |
| 569 | 576 | ||
| 570 | /* Similarly for Simba PCI bridges. */ | 577 | /* Similarly for all PCI bridges, if we get this far |
| 571 | model = of_get_property(pp, "model", NULL); | 578 | * it lacks a ranges property, and this will include |
| 572 | if (model && !strcmp(model, "SUNW,simba")) | 579 | * cases like Simba. |
| 580 | */ | ||
| 581 | if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex")) | ||
| 573 | return 0; | 582 | return 0; |
| 574 | 583 | ||
| 575 | return 1; | 584 | return 1; |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 38a32bc95d22..81f4a5ea05f7 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
| @@ -522,6 +522,89 @@ static void pci_resource_adjust(struct resource *res, | |||
| 522 | res->end += root->start; | 522 | res->end += root->start; |
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | /* For PCI bus devices which lack a 'ranges' property we interrogate | ||
| 526 | * the config space values to set the resources, just like the generic | ||
| 527 | * Linux PCI probing code does. | ||
| 528 | */ | ||
| 529 | static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | ||
| 530 | struct pci_bus *bus, | ||
| 531 | struct pci_pbm_info *pbm) | ||
| 532 | { | ||
| 533 | struct resource *res; | ||
| 534 | u8 io_base_lo, io_limit_lo; | ||
| 535 | u16 mem_base_lo, mem_limit_lo; | ||
| 536 | unsigned long base, limit; | ||
| 537 | |||
| 538 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | ||
| 539 | pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); | ||
| 540 | base = (io_base_lo & PCI_IO_RANGE_MASK) << 8; | ||
| 541 | limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8; | ||
| 542 | |||
| 543 | if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { | ||
| 544 | u16 io_base_hi, io_limit_hi; | ||
| 545 | |||
| 546 | pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi); | ||
| 547 | pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi); | ||
| 548 | base |= (io_base_hi << 16); | ||
| 549 | limit |= (io_limit_hi << 16); | ||
| 550 | } | ||
| 551 | |||
| 552 | res = bus->resource[0]; | ||
| 553 | if (base <= limit) { | ||
| 554 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | ||
| 555 | if (!res->start) | ||
| 556 | res->start = base; | ||
| 557 | if (!res->end) | ||
| 558 | res->end = limit + 0xfff; | ||
| 559 | pci_resource_adjust(res, &pbm->io_space); | ||
| 560 | } | ||
| 561 | |||
| 562 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | ||
| 563 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); | ||
| 564 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
| 565 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
| 566 | |||
| 567 | res = bus->resource[1]; | ||
| 568 | if (base <= limit) { | ||
| 569 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
| 570 | IORESOURCE_MEM); | ||
| 571 | res->start = base; | ||
| 572 | res->end = limit + 0xfffff; | ||
| 573 | pci_resource_adjust(res, &pbm->mem_space); | ||
| 574 | } | ||
| 575 | |||
| 576 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | ||
| 577 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); | ||
| 578 | base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | ||
| 579 | limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | ||
| 580 | |||
| 581 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { | ||
| 582 | u32 mem_base_hi, mem_limit_hi; | ||
| 583 | |||
| 584 | pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); | ||
| 585 | pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); | ||
| 586 | |||
| 587 | /* | ||
| 588 | * Some bridges set the base > limit by default, and some | ||
| 589 | * (broken) BIOSes do not initialize them. If we find | ||
| 590 | * this, just assume they are not being used. | ||
| 591 | */ | ||
| 592 | if (mem_base_hi <= mem_limit_hi) { | ||
| 593 | base |= ((long) mem_base_hi) << 32; | ||
| 594 | limit |= ((long) mem_limit_hi) << 32; | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | res = bus->resource[2]; | ||
| 599 | if (base <= limit) { | ||
| 600 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
| 601 | IORESOURCE_MEM | IORESOURCE_PREFETCH); | ||
| 602 | res->start = base; | ||
| 603 | res->end = limit + 0xfffff; | ||
| 604 | pci_resource_adjust(res, &pbm->mem_space); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 525 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack | 608 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack |
| 526 | * a proper 'ranges' property. | 609 | * a proper 'ranges' property. |
| 527 | */ | 610 | */ |
| @@ -581,13 +664,8 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
| 581 | simba = 0; | 664 | simba = 0; |
| 582 | if (ranges == NULL) { | 665 | if (ranges == NULL) { |
| 583 | const char *model = of_get_property(node, "model", NULL); | 666 | const char *model = of_get_property(node, "model", NULL); |
| 584 | if (model && !strcmp(model, "SUNW,simba")) { | 667 | if (model && !strcmp(model, "SUNW,simba")) |
| 585 | simba = 1; | 668 | simba = 1; |
| 586 | } else { | ||
| 587 | printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", | ||
| 588 | node->full_name); | ||
| 589 | return; | ||
| 590 | } | ||
| 591 | } | 669 | } |
| 592 | 670 | ||
| 593 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); | 671 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); |
| @@ -611,7 +689,10 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
| 611 | } | 689 | } |
| 612 | if (simba) { | 690 | if (simba) { |
| 613 | apb_fake_ranges(dev, bus, pbm); | 691 | apb_fake_ranges(dev, bus, pbm); |
| 614 | goto simba_cont; | 692 | goto after_ranges; |
| 693 | } else if (ranges == NULL) { | ||
| 694 | pci_cfg_fake_ranges(dev, bus, pbm); | ||
| 695 | goto after_ranges; | ||
| 615 | } | 696 | } |
| 616 | i = 1; | 697 | i = 1; |
| 617 | for (; len >= 32; len -= 32, ranges += 8) { | 698 | for (; len >= 32; len -= 32, ranges += 8) { |
| @@ -650,7 +731,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
| 650 | */ | 731 | */ |
| 651 | pci_resource_adjust(res, root); | 732 | pci_resource_adjust(res, root); |
| 652 | } | 733 | } |
| 653 | simba_cont: | 734 | after_ranges: |
| 654 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | 735 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), |
| 655 | bus->number); | 736 | bus->number); |
| 656 | if (ofpci_verbose) | 737 | if (ofpci_verbose) |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index d00f51a5683f..6fa761612899 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
| 25 | #include <linux/percpu.h> | 25 | #include <linux/percpu.h> |
| 26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 27 | #include <linux/rwsem.h> | ||
| 27 | #include <net/compat.h> | 28 | #include <net/compat.h> |
| 28 | 29 | ||
| 29 | #include <asm/oplib.h> | 30 | #include <asm/oplib.h> |
| @@ -58,7 +59,6 @@ | |||
| 58 | #include <asm/ns87303.h> | 59 | #include <asm/ns87303.h> |
| 59 | #include <asm/timer.h> | 60 | #include <asm/timer.h> |
| 60 | #include <asm/cpudata.h> | 61 | #include <asm/cpudata.h> |
| 61 | #include <asm/rwsem.h> | ||
| 62 | 62 | ||
| 63 | struct poll { | 63 | struct poll { |
| 64 | int fd; | 64 | int fd; |
