aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/pci/controller/cadence/pcie-cadence-host.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2020-08-05 18:24:21 -0500
committerBjorn Helgaas <bhelgaas@google.com>2020-08-05 18:24:21 -0500
commit49e427e6bdd19aa41c725819f53f381eaea1bf06 (patch)
treed0c35b74e1fc9dcaa544c21883d8dbc8a5724e1e /drivers/pci/controller/cadence/pcie-cadence-host.c
parentMerge branch 'pci/xilinx-cpm' (diff)
parentPCI: Set bridge map_irq and swizzle_irq to default functions (diff)
downloadwireguard-linux-49e427e6bdd19aa41c725819f53f381eaea1bf06.tar.xz
wireguard-linux-49e427e6bdd19aa41c725819f53f381eaea1bf06.zip
Merge branch 'pci/host-probe-refactor'
- Use pci_host_bridge.windows list directly instead of splicing in a temporary list for cadence, mvebu, host-common (Rob Herring) - Use pci_host_probe() instead of open-coding all the pieces for altera, brcmstb, iproc, mobiveil, rcar, rockchip, tegra, v3, versatile, xgene, xilinx, xilinx-nwl (Rob Herring) - Convert to devm_platform_ioremap_resource_byname() instead of open-coding platform_get_resource_byname() and devm_ioremap_resource() for altera, cadence, mediatek, rockchip, tegra, xgene (Dejin Zheng) - Convert to devm_platform_ioremap_resource() instead of open-coding platform_get_resource() and devm_ioremap_resource() for aardvark, brcmstb, exynos, ftpci100, versatile (Dejin Zheng) - Remove redundant error messages from devm_pci_remap_cfg_resource() callers (Dejin Zheng) - Drop useless PCI_ENABLE_PROC_DOMAINS from versatile driver (Rob Herring) - Default host bridge parent device to the platform device (Rob Herring) - Drop unnecessary zeroing of host bridge fields (Rob Herring) - Use pci_is_root_bus() instead of tracking root bus number separately in aardvark, designware (imx6, keystone, designware-host), mobiveil, xilinx-nwl, xilinx, rockchip, rcar (Rob Herring) - Set host bridge bus number in pci_scan_root_bus_bridge() instead of each driver for aardvark, designware-host, host-common, mediatek, rcar, tegra, v3-semi (Rob Herring) - Use bridge resources instead of parsing DT 'ranges' again for cadence (Rob Herring) - Remove private bus number and range from cadence (Rob Herring) - Use devm_pci_alloc_host_bridge() to simplify rcar (Rob Herring) - Use struct pci_host_bridge.windows list directly rather than a temporary (Rob Herring) - Reduce OF "missing non-prefetchable window" from error to warning message (Rob Herring) - Convert rcar-gen2 from old Arm-specific pci_common_init_dev() to new arch-independent interfaces (Rob Herring) - Move DT resource setup into devm_pci_alloc_host_bridge() (Rob Herring) - Set bridge map_irq and swizzle_irq to default functions; drivers that don't support legacy IRQs (iproc) need to undo this (Rob Herring) * pci/host-probe-refactor: PCI: Set bridge map_irq and swizzle_irq to default functions PCI: Move DT resource setup into devm_pci_alloc_host_bridge() PCI: rcar-gen2: Convert to use modern host bridge probe functions PCI: of: Reduce missing non-prefetchable memory region to a warning PCI: rcar: Use struct pci_host_bridge.windows list directly PCI: rcar: Use devm_pci_alloc_host_bridge() PCI: cadence: Remove private bus number and range storage PCI: cadence: Use bridge resources for outbound window setup PCI: Move setting pci_host_bridge.busnr out of host drivers PCI: rcar: Use pci_is_root_bus() to check if bus is root bus PCI: rockchip: Use pci_is_root_bus() to check if bus is root bus PCI: xilinx: Use pci_is_root_bus() to check if bus is root bus PCI: xilinx-nwl: Use pci_is_root_bus() to check if bus is root bus PCI: mobiveil: Use pci_is_root_bus() to check if bus is root bus PCI: designware: Use pci_is_root_bus() to check if bus is root bus PCI: aardvark: Use pci_is_root_bus() to check if bus is root bus PCI: Drop unnecessary zeroing of bridge fields PCI: Set default bridge parent device PCI: versatile: Drop flag PCI_ENABLE_PROC_DOMAINS PCI: controller: Remove duplicate error message PCI: controller: Convert to devm_platform_ioremap_resource() PCI: controller: Convert to devm_platform_ioremap_resource_byname() PCI: xilinx: Use pci_host_probe() to register host PCI: xilinx-nwl: Use pci_host_probe() to register host PCI: rockchip: Use pci_host_probe() to register host PCI: rcar: Use pci_host_probe() to register host PCI: iproc: Use pci_host_probe() to register host PCI: altera: Use pci_host_probe() to register host PCI: xgene: Use pci_host_probe() to register host PCI: versatile: Use pci_host_probe() to register host PCI: v3: Use pci_host_probe() to register host PCI: tegra: Use pci_host_probe() to register host PCI: mobiveil: Use pci_host_probe() to register host PCI: brcmstb: Use pci_host_probe() to register host PCI: host-common: Use struct pci_host_bridge.windows list directly PCI: mvebu: Use struct pci_host_bridge.windows list directly PCI: cadence: Use struct pci_host_bridge.windows list directly # Conflicts: # drivers/pci/controller/cadence/pcie-cadence-host.c
Diffstat (limited to 'drivers/pci/controller/cadence/pcie-cadence-host.c')
-rw-r--r--drivers/pci/controller/cadence/pcie-cadence-host.c104
1 files changed, 35 insertions, 69 deletions
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 8d86560196aa..4550e0d469ca 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -32,7 +32,7 @@ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
unsigned int busn = bus->number;
u32 addr0, desc0;
- if (busn == rc->bus_range->start) {
+ if (pci_is_root_bus(bus)) {
/*
* Only the root port (devfn == 0) is connected to this bus.
* All other PCI devices are behind some bridge hence on another
@@ -62,7 +62,7 @@ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
* The bus number was already set once for all in desc1 by
* cdns_pcie_host_init_address_translation().
*/
- if (busn == rc->bus_range->start + 1)
+ if (busn == bridge->busnr + 1)
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0;
else
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1;
@@ -321,10 +321,9 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc)
resource_list_for_each_entry(entry, &bridge->dma_ranges) {
err = cdns_pcie_host_bar_config(rc, entry);
- if (err) {
+ if (err)
dev_err(dev, "Fail to configure IB using dma-ranges\n");
- return err;
- }
+ return err;
}
return 0;
@@ -333,15 +332,16 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc)
static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
{
struct cdns_pcie *pcie = &rc->pcie;
- struct resource *bus_range = rc->bus_range;
+ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
struct resource *cfg_res = rc->cfg_res;
- struct device *dev = pcie->dev;
- struct device_node *np = dev->of_node;
- struct of_pci_range_parser parser;
+ struct resource_entry *entry;
u64 cpu_addr = cfg_res->start;
- struct of_pci_range range;
u32 addr0, addr1, desc1;
- int r, err;
+ int r, err, busnr = 0;
+
+ entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
+ if (entry)
+ busnr = entry->res->start;
/*
* Reserve region 0 for PCI configure space accesses:
@@ -349,7 +349,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
* cdns_pci_map_bus(), other region registers are set here once for all.
*/
addr1 = 0; /* Should be programmed to zero. */
- desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus_range->start);
+ desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr);
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1);
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
@@ -362,25 +362,24 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(0), addr0);
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1);
- err = of_pci_range_parser_init(&parser, np);
- if (err)
- return err;
-
r = 1;
- for_each_of_pci_range(&parser, &range) {
- bool is_io;
-
- if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
- is_io = false;
- else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
- is_io = true;
+ resource_list_for_each_entry(entry, &bridge->windows) {
+ struct resource *res = entry->res;
+ u64 pci_addr = res->start - entry->offset;
+
+ if (resource_type(res) == IORESOURCE_IO)
+ cdns_pcie_set_outbound_region(pcie, busnr, 0, r,
+ true,
+ pci_pio_to_address(res->start),
+ pci_addr,
+ resource_size(res));
else
- continue;
+ cdns_pcie_set_outbound_region(pcie, busnr, 0, r,
+ false,
+ res->start,
+ pci_addr,
+ resource_size(res));
- cdns_pcie_set_outbound_region(pcie, 0, r, is_io,
- range.cpu_addr,
- range.pci_addr,
- range.size);
r++;
}
@@ -392,39 +391,15 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
}
static int cdns_pcie_host_init(struct device *dev,
- struct list_head *resources,
struct cdns_pcie_rc *rc)
{
- struct resource *bus_range = NULL;
- struct pci_host_bridge *bridge;
int err;
- bridge = pci_host_bridge_from_priv(rc);
- if (!bridge)
- return -ENOMEM;
-
- /* Parse our PCI ranges and request their resources */
- err = pci_parse_request_of_pci_ranges(dev, resources,
- &bridge->dma_ranges, &bus_range);
- if (err)
- return err;
-
- rc->bus_range = bus_range;
- rc->pcie.bus = bus_range->start;
-
err = cdns_pcie_host_init_root_port(rc);
if (err)
- goto err_out;
-
- err = cdns_pcie_host_init_address_translation(rc);
- if (err)
- goto err_out;
-
- return 0;
+ return err;
- err_out:
- pci_free_resource_list(resources);
- return err;
+ return cdns_pcie_host_init_address_translation(rc);
}
static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
@@ -450,7 +425,6 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
struct platform_device *pdev = to_platform_device(dev);
struct device_node *np = dev->of_node;
struct pci_host_bridge *bridge;
- struct list_head resources;
enum cdns_pcie_rp_bar bar;
struct cdns_pcie *pcie;
struct resource *res;
@@ -469,8 +443,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
rc->device_id = 0xffff;
of_property_read_u32(np, "device-id", &rc->device_id);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
- pcie->reg_base = devm_ioremap_resource(dev, res);
+ pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg");
if (IS_ERR(pcie->reg_base)) {
dev_err(dev, "missing \"reg\"\n");
return PTR_ERR(pcie->reg_base);
@@ -478,10 +451,8 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
rc->cfg_base = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(rc->cfg_base)) {
- dev_err(dev, "missing \"cfg\"\n");
+ if (IS_ERR(rc->cfg_base))
return PTR_ERR(rc->cfg_base);
- }
rc->cfg_res = res;
ret = cdns_pcie_start_link(pcie);
@@ -497,26 +468,21 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
rc->avail_ib_bar[bar] = true;
- ret = cdns_pcie_host_init(dev, &resources, rc);
+ ret = cdns_pcie_host_init(dev, rc);
if (ret)
return ret;
- list_splice_init(&resources, &bridge->windows);
- bridge->dev.parent = dev;
- bridge->busnr = pcie->bus;
if (!bridge->ops)
bridge->ops = &cdns_pcie_host_ops;
- bridge->map_irq = of_irq_parse_and_map_pci;
- bridge->swizzle_irq = pci_common_swizzle;
ret = pci_host_probe(bridge);
if (ret < 0)
- goto err_host_probe;
+ goto err_init;
return 0;
- err_host_probe:
- pci_free_resource_list(&resources);
+ err_init:
+ pm_runtime_put_sync(dev);
return ret;
}