diff options
author | Andrew Murray <amurray@embedded-bits.co.uk> | 2013-07-27 15:01:22 -0400 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2013-09-03 05:13:19 -0400 |
commit | 4f7b6de437544cd1e2e210919cb58cbe5cc3c393 (patch) | |
tree | 073477c88a9fafc77ee745ccf4c1e02d8150cdb4 /arch/microblaze | |
parent | 6e4664525b1db28f8c4e1130957f70a94c19213e (diff) |
of/pci: Use of_pci_range_parser
This patch converts the pci_load_of_ranges function to use the new common
of_pci_range_parser.
Signed-off-by: Andrew Murray <amurray@embedded-bits.co.uk>
Signed-off-by: Andrew Murray <Andrew.Murray@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'arch/microblaze')
-rw-r--r-- | arch/microblaze/pci/pci-common.c | 106 |
1 files changed, 38 insertions, 68 deletions
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index bdb8ea100e73..1b93bf0892a0 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -657,67 +657,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
657 | void pci_process_bridge_OF_ranges(struct pci_controller *hose, | 657 | void pci_process_bridge_OF_ranges(struct pci_controller *hose, |
658 | struct device_node *dev, int primary) | 658 | struct device_node *dev, int primary) |
659 | { | 659 | { |
660 | const u32 *ranges; | ||
661 | int rlen; | ||
662 | int pna = of_n_addr_cells(dev); | ||
663 | int np = pna + 5; | ||
664 | int memno = 0, isa_hole = -1; | 660 | int memno = 0, isa_hole = -1; |
665 | u32 pci_space; | ||
666 | unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; | ||
667 | unsigned long long isa_mb = 0; | 661 | unsigned long long isa_mb = 0; |
668 | struct resource *res; | 662 | struct resource *res; |
663 | struct of_pci_range range; | ||
664 | struct of_pci_range_parser parser; | ||
669 | 665 | ||
670 | pr_info("PCI host bridge %s %s ranges:\n", | 666 | pr_info("PCI host bridge %s %s ranges:\n", |
671 | dev->full_name, primary ? "(primary)" : ""); | 667 | dev->full_name, primary ? "(primary)" : ""); |
672 | 668 | ||
673 | /* Get ranges property */ | 669 | /* Check for ranges property */ |
674 | ranges = of_get_property(dev, "ranges", &rlen); | 670 | if (of_pci_range_parser_init(&parser, dev)) |
675 | if (ranges == NULL) | ||
676 | return; | 671 | return; |
677 | 672 | ||
678 | /* Parse it */ | ||
679 | pr_debug("Parsing ranges property...\n"); | 673 | pr_debug("Parsing ranges property...\n"); |
680 | while ((rlen -= np * 4) >= 0) { | 674 | for_each_of_pci_range(&parser, &range) { |
681 | /* Read next ranges element */ | 675 | /* Read next ranges element */ |
682 | pci_space = ranges[0]; | ||
683 | pci_addr = of_read_number(ranges + 1, 2); | ||
684 | cpu_addr = of_translate_address(dev, ranges + 3); | ||
685 | size = of_read_number(ranges + pna + 3, 2); | ||
686 | |||
687 | pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ", | 676 | pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ", |
688 | pci_space, pci_addr); | 677 | range.pci_space, range.pci_addr); |
689 | pr_debug("cpu_addr:0x%016llx size:0x%016llx\n", | 678 | pr_debug("cpu_addr:0x%016llx size:0x%016llx\n", |
690 | cpu_addr, size); | 679 | range.cpu_addr, range.size); |
691 | |||
692 | ranges += np; | ||
693 | 680 | ||
694 | /* If we failed translation or got a zero-sized region | 681 | /* If we failed translation or got a zero-sized region |
695 | * (some FW try to feed us with non sensical zero sized regions | 682 | * (some FW try to feed us with non sensical zero sized regions |
696 | * such as power3 which look like some kind of attempt | 683 | * such as power3 which look like some kind of attempt |
697 | * at exposing the VGA memory hole) | 684 | * at exposing the VGA memory hole) |
698 | */ | 685 | */ |
699 | if (cpu_addr == OF_BAD_ADDR || size == 0) | 686 | if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) |
700 | continue; | 687 | continue; |
701 | 688 | ||
702 | /* Now consume following elements while they are contiguous */ | ||
703 | for (; rlen >= np * sizeof(u32); | ||
704 | ranges += np, rlen -= np * 4) { | ||
705 | if (ranges[0] != pci_space) | ||
706 | break; | ||
707 | pci_next = of_read_number(ranges + 1, 2); | ||
708 | cpu_next = of_translate_address(dev, ranges + 3); | ||
709 | if (pci_next != pci_addr + size || | ||
710 | cpu_next != cpu_addr + size) | ||
711 | break; | ||
712 | size += of_read_number(ranges + pna + 3, 2); | ||
713 | } | ||
714 | |||
715 | /* Act based on address space type */ | 689 | /* Act based on address space type */ |
716 | res = NULL; | 690 | res = NULL; |
717 | switch ((pci_space >> 24) & 0x3) { | 691 | switch (range.flags & IORESOURCE_TYPE_BITS) { |
718 | case 1: /* PCI IO space */ | 692 | case IORESOURCE_IO: |
719 | pr_info(" IO 0x%016llx..0x%016llx -> 0x%016llx\n", | 693 | pr_info(" IO 0x%016llx..0x%016llx -> 0x%016llx\n", |
720 | cpu_addr, cpu_addr + size - 1, pci_addr); | 694 | range.cpu_addr, range.cpu_addr + range.size - 1, |
695 | range.pci_addr); | ||
721 | 696 | ||
722 | /* We support only one IO range */ | 697 | /* We support only one IO range */ |
723 | if (hose->pci_io_size) { | 698 | if (hose->pci_io_size) { |
@@ -725,11 +700,12 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
725 | continue; | 700 | continue; |
726 | } | 701 | } |
727 | /* On 32 bits, limit I/O space to 16MB */ | 702 | /* On 32 bits, limit I/O space to 16MB */ |
728 | if (size > 0x01000000) | 703 | if (range.size > 0x01000000) |
729 | size = 0x01000000; | 704 | range.size = 0x01000000; |
730 | 705 | ||
731 | /* 32 bits needs to map IOs here */ | 706 | /* 32 bits needs to map IOs here */ |
732 | hose->io_base_virt = ioremap(cpu_addr, size); | 707 | hose->io_base_virt = ioremap(range.cpu_addr, |
708 | range.size); | ||
733 | 709 | ||
734 | /* Expect trouble if pci_addr is not 0 */ | 710 | /* Expect trouble if pci_addr is not 0 */ |
735 | if (primary) | 711 | if (primary) |
@@ -738,19 +714,20 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
738 | /* pci_io_size and io_base_phys always represent IO | 714 | /* pci_io_size and io_base_phys always represent IO |
739 | * space starting at 0 so we factor in pci_addr | 715 | * space starting at 0 so we factor in pci_addr |
740 | */ | 716 | */ |
741 | hose->pci_io_size = pci_addr + size; | 717 | hose->pci_io_size = range.pci_addr + range.size; |
742 | hose->io_base_phys = cpu_addr - pci_addr; | 718 | hose->io_base_phys = range.cpu_addr - range.pci_addr; |
743 | 719 | ||
744 | /* Build resource */ | 720 | /* Build resource */ |
745 | res = &hose->io_resource; | 721 | res = &hose->io_resource; |
746 | res->flags = IORESOURCE_IO; | 722 | range.cpu_addr = range.pci_addr; |
747 | res->start = pci_addr; | 723 | |
748 | break; | 724 | break; |
749 | case 2: /* PCI Memory space */ | 725 | case IORESOURCE_MEM: |
750 | case 3: /* PCI 64 bits Memory space */ | ||
751 | pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", | 726 | pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", |
752 | cpu_addr, cpu_addr + size - 1, pci_addr, | 727 | range.cpu_addr, range.cpu_addr + range.size - 1, |
753 | (pci_space & 0x40000000) ? "Prefetch" : ""); | 728 | range.pci_addr, |
729 | (range.pci_space & 0x40000000) ? | ||
730 | "Prefetch" : ""); | ||
754 | 731 | ||
755 | /* We support only 3 memory ranges */ | 732 | /* We support only 3 memory ranges */ |
756 | if (memno >= 3) { | 733 | if (memno >= 3) { |
@@ -758,13 +735,13 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
758 | continue; | 735 | continue; |
759 | } | 736 | } |
760 | /* Handles ISA memory hole space here */ | 737 | /* Handles ISA memory hole space here */ |
761 | if (pci_addr == 0) { | 738 | if (range.pci_addr == 0) { |
762 | isa_mb = cpu_addr; | 739 | isa_mb = range.cpu_addr; |
763 | isa_hole = memno; | 740 | isa_hole = memno; |
764 | if (primary || isa_mem_base == 0) | 741 | if (primary || isa_mem_base == 0) |
765 | isa_mem_base = cpu_addr; | 742 | isa_mem_base = range.cpu_addr; |
766 | hose->isa_mem_phys = cpu_addr; | 743 | hose->isa_mem_phys = range.cpu_addr; |
767 | hose->isa_mem_size = size; | 744 | hose->isa_mem_size = range.size; |
768 | } | 745 | } |
769 | 746 | ||
770 | /* We get the PCI/Mem offset from the first range or | 747 | /* We get the PCI/Mem offset from the first range or |
@@ -772,30 +749,23 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
772 | * hole. If they don't match, bugger. | 749 | * hole. If they don't match, bugger. |
773 | */ | 750 | */ |
774 | if (memno == 0 || | 751 | if (memno == 0 || |
775 | (isa_hole >= 0 && pci_addr != 0 && | 752 | (isa_hole >= 0 && range.pci_addr != 0 && |
776 | hose->pci_mem_offset == isa_mb)) | 753 | hose->pci_mem_offset == isa_mb)) |
777 | hose->pci_mem_offset = cpu_addr - pci_addr; | 754 | hose->pci_mem_offset = range.cpu_addr - |
778 | else if (pci_addr != 0 && | 755 | range.pci_addr; |
779 | hose->pci_mem_offset != cpu_addr - pci_addr) { | 756 | else if (range.pci_addr != 0 && |
757 | hose->pci_mem_offset != range.cpu_addr - | ||
758 | range.pci_addr) { | ||
780 | pr_info(" \\--> Skipped (offset mismatch) !\n"); | 759 | pr_info(" \\--> Skipped (offset mismatch) !\n"); |
781 | continue; | 760 | continue; |
782 | } | 761 | } |
783 | 762 | ||
784 | /* Build resource */ | 763 | /* Build resource */ |
785 | res = &hose->mem_resources[memno++]; | 764 | res = &hose->mem_resources[memno++]; |
786 | res->flags = IORESOURCE_MEM; | ||
787 | if (pci_space & 0x40000000) | ||
788 | res->flags |= IORESOURCE_PREFETCH; | ||
789 | res->start = cpu_addr; | ||
790 | break; | 765 | break; |
791 | } | 766 | } |
792 | if (res != NULL) { | 767 | if (res != NULL) |
793 | res->name = dev->full_name; | 768 | of_pci_range_to_resource(&range, dev, res); |
794 | res->end = res->start + size - 1; | ||
795 | res->parent = NULL; | ||
796 | res->sibling = NULL; | ||
797 | res->child = NULL; | ||
798 | } | ||
799 | } | 769 | } |
800 | 770 | ||
801 | /* If there's an ISA hole and the pci_mem_offset is -not- matching | 771 | /* If there's an ISA hole and the pci_mem_offset is -not- matching |