diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2017-04-28 10:34:05 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-04-28 10:34:05 -0500 |
commit | 0b0ee66c4f4debaaf2f07662ad20a6e89b568c1e (patch) | |
tree | b7643509c540e0315a18f09262b942d4ebfd0e72 /drivers/pci | |
parent | 27e99676f0f15692d2b70efb8e697d9cf7091362 (diff) | |
parent | bc636ee94501aedef744f96c57bb2e29cf21aa39 (diff) | |
download | lwn-0b0ee66c4f4debaaf2f07662ad20a6e89b568c1e.tar.gz lwn-0b0ee66c4f4debaaf2f07662ad20a6e89b568c1e.zip |
Merge branch 'pci/ioremap' into next
* pci/ioremap:
PCI: versatile: Update PCI config space remap function
PCI: keystone-dw: Update PCI config space remap function
PCI: layerscape: Update PCI config space remap function
PCI: hisi: Update PCI config space remap function
PCI: tegra: Update PCI config space remap function
PCI: xgene: Update PCI config space remap function
PCI: armada8k: Update PCI config space remap function
PCI: designware: Update PCI config space remap function
PCI: iproc-platform: Update PCI config space remap function
PCI: qcom: Update PCI config space remap function
PCI: rockchip: Update PCI config space remap function
PCI: spear13xx: Update PCI config space remap function
PCI: xilinx-nwl: Update PCI config space remap function
PCI: xilinx: Update PCI config space remap function
PCI: ECAM: Map config region with pci_remap_cfgspace()
PCI: Implement devm_pci_remap_cfgspace()
devres: fix devm_ioremap_*() offset parameter kerneldoc description
ARM: Implement pci_remap_cfgspace() interface
ARM64: Implement pci_remap_cfgspace() interface
linux/io.h: Add pci_remap_cfgspace() interface
PCI: Remove __weak tag from pci_remap_iospace()
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/dwc/pci-keystone-dw.c | 2 | ||||
-rw-r--r-- | drivers/pci/dwc/pci-layerscape.c | 2 | ||||
-rw-r--r-- | drivers/pci/dwc/pcie-armada8k.c | 2 | ||||
-rw-r--r-- | drivers/pci/dwc/pcie-designware-host.c | 12 | ||||
-rw-r--r-- | drivers/pci/dwc/pcie-hisi.c | 7 | ||||
-rw-r--r-- | drivers/pci/dwc/pcie-qcom.c | 2 | ||||
-rw-r--r-- | drivers/pci/dwc/pcie-spear13xx.c | 2 | ||||
-rw-r--r-- | drivers/pci/ecam.c | 6 | ||||
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 4 | ||||
-rw-r--r-- | drivers/pci/host/pci-versatile.c | 3 | ||||
-rw-r--r-- | drivers/pci/host/pci-xgene.c | 4 | ||||
-rw-r--r-- | drivers/pci/host/pcie-iproc-platform.c | 3 | ||||
-rw-r--r-- | drivers/pci/host/pcie-rockchip.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pcie-xilinx-nwl.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pcie-xilinx.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci.c | 84 |
16 files changed, 113 insertions, 26 deletions
diff --git a/drivers/pci/dwc/pci-keystone-dw.c b/drivers/pci/dwc/pci-keystone-dw.c index 6b396f6b4615..8bc626e640c8 100644 --- a/drivers/pci/dwc/pci-keystone-dw.c +++ b/drivers/pci/dwc/pci-keystone-dw.c @@ -543,7 +543,7 @@ int __init ks_dw_pcie_host_init(struct keystone_pcie *ks_pcie, /* Index 0 is the config reg. space address */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pci->dbi_base = devm_ioremap_resource(dev, res); + pci->dbi_base = devm_pci_remap_cfg_resource(dev, res); if (IS_ERR(pci->dbi_base)) return PTR_ERR(pci->dbi_base); diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index c32e392a0ae6..8f0ee0d8129c 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c @@ -283,7 +283,7 @@ static int __init ls_pcie_probe(struct platform_device *pdev) pcie->pci = pci; dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); - pci->dbi_base = devm_ioremap_resource(dev, dbi_base); + pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base); if (IS_ERR(pci->dbi_base)) return PTR_ERR(pci->dbi_base); diff --git a/drivers/pci/dwc/pcie-armada8k.c b/drivers/pci/dwc/pcie-armada8k.c index f110e3b24a26..3ff31301323b 100644 --- a/drivers/pci/dwc/pcie-armada8k.c +++ b/drivers/pci/dwc/pcie-armada8k.c @@ -230,7 +230,7 @@ static int armada8k_pcie_probe(struct platform_device *pdev) /* Get the dw-pcie unit configuration/control registers base. */ base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); - pci->dbi_base = devm_ioremap_resource(dev, base); + pci->dbi_base = devm_pci_remap_cfg_resource(dev, base); if (IS_ERR(pci->dbi_base)) { dev_err(dev, "couldn't remap regs base %p\n", base); ret = PTR_ERR(pci->dbi_base); diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c index aece2962defc..28ed32ba4f1b 100644 --- a/drivers/pci/dwc/pcie-designware-host.c +++ b/drivers/pci/dwc/pcie-designware-host.c @@ -339,8 +339,9 @@ int dw_pcie_host_init(struct pcie_port *pp) } if (!pci->dbi_base) { - pci->dbi_base = devm_ioremap(dev, pp->cfg->start, - resource_size(pp->cfg)); + pci->dbi_base = devm_pci_remap_cfgspace(dev, + pp->cfg->start, + resource_size(pp->cfg)); if (!pci->dbi_base) { dev_err(dev, "error with ioremap\n"); ret = -ENOMEM; @@ -351,8 +352,8 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->mem_base = pp->mem->start; if (!pp->va_cfg0_base) { - pp->va_cfg0_base = devm_ioremap(dev, pp->cfg0_base, - pp->cfg0_size); + pp->va_cfg0_base = devm_pci_remap_cfgspace(dev, + pp->cfg0_base, pp->cfg0_size); if (!pp->va_cfg0_base) { dev_err(dev, "error with ioremap in function\n"); ret = -ENOMEM; @@ -361,7 +362,8 @@ int dw_pcie_host_init(struct pcie_port *pp) } if (!pp->va_cfg1_base) { - pp->va_cfg1_base = devm_ioremap(dev, pp->cfg1_base, + pp->va_cfg1_base = devm_pci_remap_cfgspace(dev, + pp->cfg1_base, pp->cfg1_size); if (!pp->va_cfg1_base) { dev_err(dev, "error with ioremap\n"); diff --git a/drivers/pci/dwc/pcie-hisi.c b/drivers/pci/dwc/pcie-hisi.c index fd66a3199db7..1606de5bf757 100644 --- a/drivers/pci/dwc/pcie-hisi.c +++ b/drivers/pci/dwc/pcie-hisi.c @@ -99,7 +99,7 @@ static int hisi_pcie_init(struct pci_config_window *cfg) return -ENOMEM; } - reg_base = devm_ioremap(dev, res->start, resource_size(res)); + reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res)); if (!reg_base) return -ENOMEM; @@ -296,10 +296,9 @@ static int hisi_pcie_probe(struct platform_device *pdev) } reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi"); - pci->dbi_base = devm_ioremap_resource(dev, reg); + pci->dbi_base = devm_pci_remap_cfg_resource(dev, reg); if (IS_ERR(pci->dbi_base)) return PTR_ERR(pci->dbi_base); - platform_set_drvdata(pdev, hisi_pcie); ret = hisi_add_pcie_port(hisi_pcie, pdev); @@ -360,7 +359,7 @@ static int hisi_pcie_platform_init(struct pci_config_window *cfg) return -EINVAL; } - reg_base = devm_ioremap(dev, res->start, resource_size(res)); + reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res)); if (!reg_base) return -ENOMEM; diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c index 67eb7f5926dd..5bf23d432fdb 100644 --- a/drivers/pci/dwc/pcie-qcom.c +++ b/drivers/pci/dwc/pcie-qcom.c @@ -700,7 +700,7 @@ static int qcom_pcie_probe(struct platform_device *pdev) return PTR_ERR(pcie->parf); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); - pci->dbi_base = devm_ioremap_resource(dev, res); + pci->dbi_base = devm_pci_remap_cfg_resource(dev, res); if (IS_ERR(pci->dbi_base)) return PTR_ERR(pci->dbi_base); diff --git a/drivers/pci/dwc/pcie-spear13xx.c b/drivers/pci/dwc/pcie-spear13xx.c index eaa4ea8e2ea4..3ae59de5c043 100644 --- a/drivers/pci/dwc/pcie-spear13xx.c +++ b/drivers/pci/dwc/pcie-spear13xx.c @@ -273,7 +273,7 @@ static int spear13xx_pcie_probe(struct platform_device *pdev) } dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); - pci->dbi_base = devm_ioremap_resource(dev, dbi_base); + pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base); if (IS_ERR(pci->dbi_base)) { dev_err(dev, "couldn't remap dbi base %p\n", dbi_base); ret = PTR_ERR(pci->dbi_base); diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c index 2fee61bb6559..c228a2eb7faa 100644 --- a/drivers/pci/ecam.c +++ b/drivers/pci/ecam.c @@ -84,12 +84,14 @@ struct pci_config_window *pci_ecam_create(struct device *dev, if (!cfg->winp) goto err_exit_malloc; for (i = 0; i < bus_range; i++) { - cfg->winp[i] = ioremap(cfgres->start + i * bsz, bsz); + cfg->winp[i] = + pci_remap_cfgspace(cfgres->start + i * bsz, + bsz); if (!cfg->winp[i]) goto err_exit_iomap; } } else { - cfg->win = ioremap(cfgres->start, bus_range * bsz); + cfg->win = pci_remap_cfgspace(cfgres->start, bus_range * bsz); if (!cfg->win) goto err_exit_iomap; } diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index ed8a93f2bfb5..2618f875a600 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -380,7 +380,7 @@ static struct tegra_pcie_bus *tegra_pcie_bus_alloc(struct tegra_pcie *pcie, unsigned int busnr) { struct device *dev = pcie->dev; - pgprot_t prot = pgprot_device(PAGE_KERNEL); + pgprot_t prot = pgprot_noncached(PAGE_KERNEL); phys_addr_t cs = pcie->cs->start; struct tegra_pcie_bus *bus; unsigned int i; @@ -1962,7 +1962,7 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) rp->pcie = pcie; rp->np = port; - rp->base = devm_ioremap_resource(dev, &rp->regs); + rp->base = devm_pci_remap_cfg_resource(dev, &rp->regs); if (IS_ERR(rp->base)) return PTR_ERR(rp->base); diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c index 5ebee7d37ff5..85e773661bc8 100644 --- a/drivers/pci/host/pci-versatile.c +++ b/drivers/pci/host/pci-versatile.c @@ -138,7 +138,8 @@ static int versatile_pci_probe(struct platform_device *pdev) return PTR_ERR(versatile_cfg_base[0]); res = platform_get_resource(pdev, IORESOURCE_MEM, 2); - versatile_cfg_base[1] = devm_ioremap_resource(&pdev->dev, res); + versatile_cfg_base[1] = devm_pci_remap_cfg_resource(&pdev->dev, + res); if (IS_ERR(versatile_cfg_base[1])) return PTR_ERR(versatile_cfg_base[1]); diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index 1a6108788f6f..de198980432e 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c @@ -248,7 +248,7 @@ static int xgene_pcie_ecam_init(struct pci_config_window *cfg, u32 ipversion) dev_err(dev, "can't get CSR resource\n"); return ret; } - port->csr_base = devm_ioremap_resource(dev, &csr); + port->csr_base = devm_pci_remap_cfg_resource(dev, &csr); if (IS_ERR(port->csr_base)) return PTR_ERR(port->csr_base); @@ -359,7 +359,7 @@ static int xgene_pcie_map_reg(struct xgene_pcie_port *port, struct resource *res; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr"); - port->csr_base = devm_ioremap_resource(dev, res); + port->csr_base = devm_pci_remap_cfg_resource(dev, res); if (IS_ERR(port->csr_base)) return PTR_ERR(port->csr_base); diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c index 8c6a327ca6cd..90d2bdd94e41 100644 --- a/drivers/pci/host/pcie-iproc-platform.c +++ b/drivers/pci/host/pcie-iproc-platform.c @@ -67,7 +67,8 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev) return ret; } - pcie->base = devm_ioremap(dev, reg.start, resource_size(®)); + pcie->base = devm_pci_remap_cfgspace(dev, reg.start, + resource_size(®)); if (!pcie->base) { dev_err(dev, "unable to map controller registers\n"); return -ENOMEM; diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index abc7fd76b181..0e020b6e0943 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c @@ -832,7 +832,7 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "axi-base"); - rockchip->reg_base = devm_ioremap_resource(dev, regs); + rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs); if (IS_ERR(rockchip->reg_base)) return PTR_ERR(rockchip->reg_base); diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c index 4c3e0ab35496..4b16b26ae909 100644 --- a/drivers/pci/host/pcie-xilinx-nwl.c +++ b/drivers/pci/host/pcie-xilinx-nwl.c @@ -761,7 +761,7 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie, pcie->phys_pcie_reg_base = res->start; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); - pcie->ecam_base = devm_ioremap_resource(dev, res); + pcie->ecam_base = devm_pci_remap_cfg_resource(dev, res); if (IS_ERR(pcie->ecam_base)) return PTR_ERR(pcie->ecam_base); pcie->phys_ecam_base = res->start; diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index 7f030f5d750b..2fe2df51f9f8 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c @@ -606,7 +606,7 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port) return err; } - port->reg_base = devm_ioremap_resource(dev, ®s); + port->reg_base = devm_pci_remap_cfg_resource(dev, ®s); if (IS_ERR(port->reg_base)) return PTR_ERR(port->reg_base); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f85774b3da1e..d8b5c37cecd3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3363,7 +3363,7 @@ unsigned long __weak pci_address_to_pio(phys_addr_t address) * Only architectures that have memory mapped IO functions defined * (and the PCI_IOBASE value defined) should call this function. */ -int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) +int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) { #if defined(PCI_IOBASE) && defined(CONFIG_MMU) unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; @@ -3403,6 +3403,88 @@ void pci_unmap_iospace(struct resource *res) } EXPORT_SYMBOL(pci_unmap_iospace); +/** + * devm_pci_remap_cfgspace - Managed pci_remap_cfgspace() + * @dev: Generic device to remap IO address for + * @offset: Resource address to map + * @size: Size of map + * + * Managed pci_remap_cfgspace(). Map is automatically unmapped on driver + * detach. + */ +void __iomem *devm_pci_remap_cfgspace(struct device *dev, + resource_size_t offset, + resource_size_t size) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = pci_remap_cfgspace(offset, size); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_pci_remap_cfgspace); + +/** + * devm_pci_remap_cfg_resource - check, request region and ioremap cfg resource + * @dev: generic device to handle the resource for + * @res: configuration space resource to be handled + * + * Checks that a resource is a valid memory region, requests the memory + * region and ioremaps with pci_remap_cfgspace() API that ensures the + * proper PCI configuration space memory attributes are guaranteed. + * + * All operations are managed and will be undone on driver detach. + * + * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code + * on failure. Usage example: + * + * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + * base = devm_pci_remap_cfg_resource(&pdev->dev, res); + * if (IS_ERR(base)) + * return PTR_ERR(base); + */ +void __iomem *devm_pci_remap_cfg_resource(struct device *dev, + struct resource *res) +{ + resource_size_t size; + const char *name; + void __iomem *dest_ptr; + + BUG_ON(!dev); + + if (!res || resource_type(res) != IORESOURCE_MEM) { + dev_err(dev, "invalid resource\n"); + return IOMEM_ERR_PTR(-EINVAL); + } + + size = resource_size(res); + name = res->name ?: dev_name(dev); + + if (!devm_request_mem_region(dev, res->start, size, name)) { + dev_err(dev, "can't request region for resource %pR\n", res); + return IOMEM_ERR_PTR(-EBUSY); + } + + dest_ptr = devm_pci_remap_cfgspace(dev, res->start, size); + if (!dest_ptr) { + dev_err(dev, "ioremap failed for resource %pR\n", res); + devm_release_mem_region(dev, res->start, size); + dest_ptr = IOMEM_ERR_PTR(-ENOMEM); + } + + return dest_ptr; +} +EXPORT_SYMBOL(devm_pci_remap_cfg_resource); + static void __pci_set_master(struct pci_dev *dev, bool enable) { u16 old_cmd, cmd; |