diff options
author | Liviu Dudau <Liviu.Dudau@arm.com> | 2014-09-29 10:29:25 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-09-30 19:08:40 -0400 |
commit | 0b0b0893d49b34201a6c4416b1a707b580b91e3d (patch) | |
tree | 6705257f35735ce6bc8c85a760d49227905d6b13 /arch/arm/mach-integrator | |
parent | 83bbde1cc0ec9d156b9271e29ffe0dc89c687feb (diff) |
of/pci: Fix the conversion of IO ranges into IO resources
The ranges property for a host bridge controller in DT describes the
mapping between the PCI bus address and the CPU physical address. The
resources framework however expects that the IO resources start at a pseudo
"port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT. The
conversion from PCI ranges to resources failed to take that into account,
returning a CPU physical address instead of a port number.
Also fix all the drivers that depend on the old behaviour by fetching the
CPU physical address based on the port number where it is being needed.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
CC: Grant Likely <grant.likely@linaro.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Thierry Reding <thierry.reding@gmail.com>
CC: Simon Horman <horms@verge.net.au>
CC: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r-- | arch/arm/mach-integrator/pci_v3.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 05e1f73a1e8d..c186a17c2cff 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c | |||
@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void) | |||
660 | { | 660 | { |
661 | unsigned long flags; | 661 | unsigned long flags; |
662 | unsigned int temp; | 662 | unsigned int temp; |
663 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); | ||
663 | 664 | ||
664 | pcibios_min_mem = 0x00100000; | 665 | pcibios_min_mem = 0x00100000; |
665 | 666 | ||
@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void) | |||
701 | /* | 702 | /* |
702 | * Setup window 2 - PCI IO | 703 | * Setup window 2 - PCI IO |
703 | */ | 704 | */ |
704 | v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) | | 705 | v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) | |
705 | V3_LB_BASE_ENABLE); | 706 | V3_LB_BASE_ENABLE); |
706 | v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); | 707 | v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); |
707 | 708 | ||
@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void) | |||
742 | static void __init pci_v3_postinit(void) | 743 | static void __init pci_v3_postinit(void) |
743 | { | 744 | { |
744 | unsigned int pci_cmd; | 745 | unsigned int pci_cmd; |
746 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); | ||
745 | 747 | ||
746 | pci_cmd = PCI_COMMAND_MEMORY | | 748 | pci_cmd = PCI_COMMAND_MEMORY | |
747 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | 749 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; |
@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void) | |||
758 | "interrupt: %d\n", ret); | 760 | "interrupt: %d\n", ret); |
759 | #endif | 761 | #endif |
760 | 762 | ||
761 | register_isa_ports(non_mem.start, io_mem.start, 0); | 763 | register_isa_ports(non_mem.start, io_address, 0); |
762 | } | 764 | } |
763 | 765 | ||
764 | /* | 766 | /* |
@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev) | |||
867 | 869 | ||
868 | for_each_of_pci_range(&parser, &range) { | 870 | for_each_of_pci_range(&parser, &range) { |
869 | if (!range.flags) { | 871 | if (!range.flags) { |
870 | of_pci_range_to_resource(&range, np, &conf_mem); | 872 | ret = of_pci_range_to_resource(&range, np, &conf_mem); |
871 | conf_mem.name = "PCIv3 config"; | 873 | conf_mem.name = "PCIv3 config"; |
872 | } | 874 | } |
873 | if (range.flags & IORESOURCE_IO) { | 875 | if (range.flags & IORESOURCE_IO) { |
874 | of_pci_range_to_resource(&range, np, &io_mem); | 876 | ret = of_pci_range_to_resource(&range, np, &io_mem); |
875 | io_mem.name = "PCIv3 I/O"; | 877 | io_mem.name = "PCIv3 I/O"; |
876 | } | 878 | } |
877 | if ((range.flags & IORESOURCE_MEM) && | 879 | if ((range.flags & IORESOURCE_MEM) && |
878 | !(range.flags & IORESOURCE_PREFETCH)) { | 880 | !(range.flags & IORESOURCE_PREFETCH)) { |
879 | non_mem_pci = range.pci_addr; | 881 | non_mem_pci = range.pci_addr; |
880 | non_mem_pci_sz = range.size; | 882 | non_mem_pci_sz = range.size; |
881 | of_pci_range_to_resource(&range, np, &non_mem); | 883 | ret = of_pci_range_to_resource(&range, np, &non_mem); |
882 | non_mem.name = "PCIv3 non-prefetched mem"; | 884 | non_mem.name = "PCIv3 non-prefetched mem"; |
883 | } | 885 | } |
884 | if ((range.flags & IORESOURCE_MEM) && | 886 | if ((range.flags & IORESOURCE_MEM) && |
885 | (range.flags & IORESOURCE_PREFETCH)) { | 887 | (range.flags & IORESOURCE_PREFETCH)) { |
886 | pre_mem_pci = range.pci_addr; | 888 | pre_mem_pci = range.pci_addr; |
887 | pre_mem_pci_sz = range.size; | 889 | pre_mem_pci_sz = range.size; |
888 | of_pci_range_to_resource(&range, np, &pre_mem); | 890 | ret = of_pci_range_to_resource(&range, np, &pre_mem); |
889 | pre_mem.name = "PCIv3 prefetched mem"; | 891 | pre_mem.name = "PCIv3 prefetched mem"; |
890 | } | 892 | } |
891 | } | ||
892 | 893 | ||
893 | if (!conf_mem.start || !io_mem.start || | 894 | if (ret < 0) { |
894 | !non_mem.start || !pre_mem.start) { | 895 | dev_err(&pdev->dev, "missing ranges in device node\n"); |
895 | dev_err(&pdev->dev, "missing ranges in device node\n"); | 896 | return ret; |
896 | return -EINVAL; | 897 | } |
897 | } | 898 | } |
898 | 899 | ||
899 | pci_v3.map_irq = of_irq_parse_and_map_pci; | 900 | pci_v3.map_irq = of_irq_parse_and_map_pci; |