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 /drivers/pci/host | |
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 'drivers/pci/host')
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 10 | ||||
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 21 |
2 files changed, 22 insertions, 9 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 0fb0fdb223d5..946935db62b6 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); | |||
626 | static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | 626 | static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) |
627 | { | 627 | { |
628 | struct tegra_pcie *pcie = sys_to_pcie(sys); | 628 | struct tegra_pcie *pcie = sys_to_pcie(sys); |
629 | phys_addr_t io_start = pci_pio_to_address(pcie->io.start); | ||
629 | 630 | ||
630 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 631 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
631 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | 632 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, |
632 | sys->mem_offset); | 633 | sys->mem_offset); |
633 | pci_add_resource(&sys->resources, &pcie->busn); | 634 | pci_add_resource(&sys->resources, &pcie->busn); |
634 | 635 | ||
635 | pci_ioremap_io(nr * SZ_64K, pcie->io.start); | 636 | pci_ioremap_io(nr * SZ_64K, io_start); |
636 | 637 | ||
637 | return 1; | 638 | return 1; |
638 | } | 639 | } |
@@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg) | |||
737 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | 738 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) |
738 | { | 739 | { |
739 | u32 fpci_bar, size, axi_address; | 740 | u32 fpci_bar, size, axi_address; |
741 | phys_addr_t io_start = pci_pio_to_address(pcie->io.start); | ||
740 | 742 | ||
741 | /* Bar 0: type 1 extended configuration space */ | 743 | /* Bar 0: type 1 extended configuration space */ |
742 | fpci_bar = 0xfe100000; | 744 | fpci_bar = 0xfe100000; |
@@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | |||
749 | /* Bar 1: downstream IO bar */ | 751 | /* Bar 1: downstream IO bar */ |
750 | fpci_bar = 0xfdfc0000; | 752 | fpci_bar = 0xfdfc0000; |
751 | size = resource_size(&pcie->io); | 753 | size = resource_size(&pcie->io); |
752 | axi_address = pcie->io.start; | 754 | axi_address = io_start; |
753 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); | 755 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); |
754 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); | 756 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); |
755 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); | 757 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); |
@@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1520 | } | 1522 | } |
1521 | 1523 | ||
1522 | for_each_of_pci_range(&parser, &range) { | 1524 | for_each_of_pci_range(&parser, &range) { |
1523 | of_pci_range_to_resource(&range, np, &res); | 1525 | err = of_pci_range_to_resource(&range, np, &res); |
1526 | if (err < 0) | ||
1527 | return err; | ||
1524 | 1528 | ||
1525 | switch (res.flags & IORESOURCE_TYPE_BITS) { | 1529 | switch (res.flags & IORESOURCE_TYPE_BITS) { |
1526 | case IORESOURCE_IO: | 1530 | case IORESOURCE_IO: |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 4884ee5e07d4..61158e03ab5f 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie) | |||
323 | 323 | ||
324 | /* Setup PCIe address space mappings for each resource */ | 324 | /* Setup PCIe address space mappings for each resource */ |
325 | resource_size_t size; | 325 | resource_size_t size; |
326 | resource_size_t res_start; | ||
326 | u32 mask; | 327 | u32 mask; |
327 | 328 | ||
328 | rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win)); | 329 | rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win)); |
@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie) | |||
335 | mask = (roundup_pow_of_two(size) / SZ_128) - 1; | 336 | mask = (roundup_pow_of_two(size) / SZ_128) - 1; |
336 | rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win)); | 337 | rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win)); |
337 | 338 | ||
338 | rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win)); | 339 | if (res->flags & IORESOURCE_IO) |
339 | rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win)); | 340 | res_start = pci_pio_to_address(res->start); |
341 | else | ||
342 | res_start = res->start; | ||
343 | |||
344 | rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win)); | ||
345 | rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win)); | ||
340 | 346 | ||
341 | /* First resource is for IO */ | 347 | /* First resource is for IO */ |
342 | mask = PAR_ENABLE; | 348 | mask = PAR_ENABLE; |
@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys) | |||
363 | 369 | ||
364 | rcar_pcie_setup_window(i, pcie); | 370 | rcar_pcie_setup_window(i, pcie); |
365 | 371 | ||
366 | if (res->flags & IORESOURCE_IO) | 372 | if (res->flags & IORESOURCE_IO) { |
367 | pci_ioremap_io(nr * SZ_64K, res->start); | 373 | phys_addr_t io_start = pci_pio_to_address(res->start); |
368 | else | 374 | pci_ioremap_io(nr * SZ_64K, io_start); |
375 | } else | ||
369 | pci_add_resource(&sys->resources, res); | 376 | pci_add_resource(&sys->resources, res); |
370 | } | 377 | } |
371 | pci_add_resource(&sys->resources, &pcie->busn); | 378 | pci_add_resource(&sys->resources, &pcie->busn); |
@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
935 | } | 942 | } |
936 | 943 | ||
937 | for_each_of_pci_range(&parser, &range) { | 944 | for_each_of_pci_range(&parser, &range) { |
938 | of_pci_range_to_resource(&range, pdev->dev.of_node, | 945 | err = of_pci_range_to_resource(&range, pdev->dev.of_node, |
939 | &pcie->res[win++]); | 946 | &pcie->res[win++]); |
947 | if (err < 0) | ||
948 | return err; | ||
940 | 949 | ||
941 | if (win > RCAR_PCI_MAX_RESOURCES) | 950 | if (win > RCAR_PCI_MAX_RESOURCES) |
942 | break; | 951 | break; |