diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-10-01 14:31:23 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-10-01 14:31:23 -0400 |
commit | 07a7cbd3b815ea77b44d4d5bb4260b37d03a358d (patch) | |
tree | 7b205e495fff1e1548cac893264cfdfe18ac34dd /drivers/pci | |
parent | cc0cb67adb97793e76bf6f1f6e05694f6311cebd (diff) | |
parent | d1e6dc91b532d3d3dbbd0fa356b775ca320dc2c2 (diff) |
Merge branch 'pci/host-generic' into next
* pci/host-generic:
arm64: Add architectural support for PCI
PCI: Add pci_remap_iospace() to map bus I/O resources
of/pci: Add support for parsing PCI host bridge resources from DT
of/pci: Add pci_get_new_domain_nr() and of_get_pci_domain_nr()
PCI: Add generic domain handling
of/pci: Fix the conversion of IO ranges into IO resources
of/pci: Move of_pci_range_to_resource() to of/address.c
ARM: Define PCI_IOBASE as the base of virtual PCI IO space
of/pci: Add pci_register_io_range() and pci_pio_to_address()
asm-generic/io.h: Fix ioport_map() for !CONFIG_GENERIC_IOMAP
Conflicts:
drivers/pci/host/pci-tegra.c
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 12 | ||||
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 21 | ||||
-rw-r--r-- | drivers/pci/pci.c | 40 | ||||
-rw-r--r-- | drivers/pci/probe.c | 11 |
4 files changed, 72 insertions, 12 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 79a30476036c..3d43874319be 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -658,6 +658,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
658 | { | 658 | { |
659 | struct tegra_pcie *pcie = sys_to_pcie(sys); | 659 | struct tegra_pcie *pcie = sys_to_pcie(sys); |
660 | int err; | 660 | int err; |
661 | phys_addr_t io_start; | ||
661 | 662 | ||
662 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); | 663 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); |
663 | if (err < 0) | 664 | if (err < 0) |
@@ -667,12 +668,14 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
667 | if (err) | 668 | if (err) |
668 | return err; | 669 | return err; |
669 | 670 | ||
671 | io_start = pci_pio_to_address(pcie->io.start); | ||
672 | |||
670 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 673 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
671 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | 674 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, |
672 | sys->mem_offset); | 675 | sys->mem_offset); |
673 | pci_add_resource(&sys->resources, &pcie->busn); | 676 | pci_add_resource(&sys->resources, &pcie->busn); |
674 | 677 | ||
675 | pci_ioremap_io(nr * SZ_64K, pcie->io.start); | 678 | pci_ioremap_io(nr * SZ_64K, io_start); |
676 | 679 | ||
677 | return 1; | 680 | return 1; |
678 | } | 681 | } |
@@ -783,6 +786,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg) | |||
783 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | 786 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) |
784 | { | 787 | { |
785 | u32 fpci_bar, size, axi_address; | 788 | u32 fpci_bar, size, axi_address; |
789 | phys_addr_t io_start = pci_pio_to_address(pcie->io.start); | ||
786 | 790 | ||
787 | /* Bar 0: type 1 extended configuration space */ | 791 | /* Bar 0: type 1 extended configuration space */ |
788 | fpci_bar = 0xfe100000; | 792 | fpci_bar = 0xfe100000; |
@@ -795,7 +799,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | |||
795 | /* Bar 1: downstream IO bar */ | 799 | /* Bar 1: downstream IO bar */ |
796 | fpci_bar = 0xfdfc0000; | 800 | fpci_bar = 0xfdfc0000; |
797 | size = resource_size(&pcie->io); | 801 | size = resource_size(&pcie->io); |
798 | axi_address = pcie->io.start; | 802 | axi_address = io_start; |
799 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); | 803 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); |
800 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); | 804 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); |
801 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); | 805 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); |
@@ -1680,7 +1684,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1680 | } | 1684 | } |
1681 | 1685 | ||
1682 | for_each_of_pci_range(&parser, &range) { | 1686 | for_each_of_pci_range(&parser, &range) { |
1683 | of_pci_range_to_resource(&range, np, &res); | 1687 | err = of_pci_range_to_resource(&range, np, &res); |
1688 | if (err < 0) | ||
1689 | return err; | ||
1684 | 1690 | ||
1685 | switch (res.flags & IORESOURCE_TYPE_BITS) { | 1691 | switch (res.flags & IORESOURCE_TYPE_BITS) { |
1686 | case IORESOURCE_IO: | 1692 | 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; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b7678be7b106..625a4ace10b4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -2707,6 +2707,37 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | |||
2707 | } | 2707 | } |
2708 | EXPORT_SYMBOL(pci_request_regions_exclusive); | 2708 | EXPORT_SYMBOL(pci_request_regions_exclusive); |
2709 | 2709 | ||
2710 | /** | ||
2711 | * pci_remap_iospace - Remap the memory mapped I/O space | ||
2712 | * @res: Resource describing the I/O space | ||
2713 | * @phys_addr: physical address of range to be mapped | ||
2714 | * | ||
2715 | * Remap the memory mapped I/O space described by the @res | ||
2716 | * and the CPU physical address @phys_addr into virtual address space. | ||
2717 | * Only architectures that have memory mapped IO functions defined | ||
2718 | * (and the PCI_IOBASE value defined) should call this function. | ||
2719 | */ | ||
2720 | int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) | ||
2721 | { | ||
2722 | #if defined(PCI_IOBASE) && defined(CONFIG_MMU) | ||
2723 | unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; | ||
2724 | |||
2725 | if (!(res->flags & IORESOURCE_IO)) | ||
2726 | return -EINVAL; | ||
2727 | |||
2728 | if (res->end > IO_SPACE_LIMIT) | ||
2729 | return -EINVAL; | ||
2730 | |||
2731 | return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr, | ||
2732 | pgprot_device(PAGE_KERNEL)); | ||
2733 | #else | ||
2734 | /* this architecture does not have memory mapped I/O space, | ||
2735 | so this function should never be called */ | ||
2736 | WARN_ONCE(1, "This architecture does not support memory mapped I/O\n"); | ||
2737 | return -ENODEV; | ||
2738 | #endif | ||
2739 | } | ||
2740 | |||
2710 | static void __pci_set_master(struct pci_dev *dev, bool enable) | 2741 | static void __pci_set_master(struct pci_dev *dev, bool enable) |
2711 | { | 2742 | { |
2712 | u16 old_cmd, cmd; | 2743 | u16 old_cmd, cmd; |
@@ -4409,6 +4440,15 @@ static void pci_no_domains(void) | |||
4409 | #endif | 4440 | #endif |
4410 | } | 4441 | } |
4411 | 4442 | ||
4443 | #ifdef CONFIG_PCI_DOMAINS | ||
4444 | static atomic_t __domain_nr = ATOMIC_INIT(-1); | ||
4445 | |||
4446 | int pci_get_new_domain_nr(void) | ||
4447 | { | ||
4448 | return atomic_inc_return(&__domain_nr); | ||
4449 | } | ||
4450 | #endif | ||
4451 | |||
4412 | /** | 4452 | /** |
4413 | * pci_ext_cfg_avail - can we access extended PCI config space? | 4453 | * pci_ext_cfg_avail - can we access extended PCI config space? |
4414 | * | 4454 | * |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c99c4d65461b..efa48dc0de3b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -486,7 +486,7 @@ void pci_read_bridge_bases(struct pci_bus *child) | |||
486 | } | 486 | } |
487 | } | 487 | } |
488 | 488 | ||
489 | static struct pci_bus *pci_alloc_bus(void) | 489 | static struct pci_bus *pci_alloc_bus(struct pci_bus *parent) |
490 | { | 490 | { |
491 | struct pci_bus *b; | 491 | struct pci_bus *b; |
492 | 492 | ||
@@ -501,6 +501,10 @@ static struct pci_bus *pci_alloc_bus(void) | |||
501 | INIT_LIST_HEAD(&b->resources); | 501 | INIT_LIST_HEAD(&b->resources); |
502 | b->max_bus_speed = PCI_SPEED_UNKNOWN; | 502 | b->max_bus_speed = PCI_SPEED_UNKNOWN; |
503 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; | 503 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; |
504 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
505 | if (parent) | ||
506 | b->domain_nr = parent->domain_nr; | ||
507 | #endif | ||
504 | return b; | 508 | return b; |
505 | } | 509 | } |
506 | 510 | ||
@@ -672,7 +676,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
672 | /* | 676 | /* |
673 | * Allocate a new bus, and inherit stuff from the parent.. | 677 | * Allocate a new bus, and inherit stuff from the parent.. |
674 | */ | 678 | */ |
675 | child = pci_alloc_bus(); | 679 | child = pci_alloc_bus(parent); |
676 | if (!child) | 680 | if (!child) |
677 | return NULL; | 681 | return NULL; |
678 | 682 | ||
@@ -1913,13 +1917,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1913 | char bus_addr[64]; | 1917 | char bus_addr[64]; |
1914 | char *fmt; | 1918 | char *fmt; |
1915 | 1919 | ||
1916 | b = pci_alloc_bus(); | 1920 | b = pci_alloc_bus(NULL); |
1917 | if (!b) | 1921 | if (!b) |
1918 | return NULL; | 1922 | return NULL; |
1919 | 1923 | ||
1920 | b->sysdata = sysdata; | 1924 | b->sysdata = sysdata; |
1921 | b->ops = ops; | 1925 | b->ops = ops; |
1922 | b->number = b->busn_res.start = bus; | 1926 | b->number = b->busn_res.start = bus; |
1927 | pci_bus_assign_domain_nr(b, parent); | ||
1923 | b2 = pci_find_bus(pci_domain_nr(b), bus); | 1928 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
1924 | if (b2) { | 1929 | if (b2) { |
1925 | /* If we already got to this bus through a different bridge, ignore it */ | 1930 | /* If we already got to this bus through a different bridge, ignore it */ |