diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2020-08-05 18:24:21 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2020-08-05 18:24:21 -0500 |
commit | 49e427e6bdd19aa41c725819f53f381eaea1bf06 (patch) | |
tree | d0c35b74e1fc9dcaa544c21883d8dbc8a5724e1e /drivers/pci | |
parent | f8917db9566703bab02778b1836c5ae0c4aa46ec (diff) | |
parent | b64aa11eb2ddb0600361178286d7b7ed5a069fd8 (diff) |
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')
42 files changed, 240 insertions, 805 deletions
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 23ad8fa699c4..586b9d69fa5e 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -245,11 +245,7 @@ static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie) static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { - struct pci_host_bridge *bridge = pci_find_host_bridge(bus); - struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge); - unsigned int busn = bus->number; - - if (busn == rc->bus_range->start) + if (pci_is_root_bus(bus)) return pci_generic_config_read32(bus, devfn, where, size, value); @@ -259,11 +255,7 @@ static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn, static int cdns_ti_pcie_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { - struct pci_host_bridge *bridge = pci_find_host_bridge(bus); - struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge); - unsigned int busn = bus->number; - - if (busn == rc->bus_range->start) + if (pci_is_root_bus(bus)) return pci_generic_config_write32(bus, devfn, where, size, value); diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index ec1306da301f..254a3e1eff50 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -161,7 +161,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr, return -EINVAL; } - cdns_pcie_set_outbound_region(pcie, fn, r, false, addr, pci_addr, size); + cdns_pcie_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size); set_bit(r, &ep->ob_region_map); ep->ob_addr[r] = addr; @@ -289,7 +289,7 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY || ep->irq_pci_fn != fn)) { /* First region was reserved for IRQ writes. */ - cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, 0, + cdns_pcie_set_outbound_region_for_normal_msg(pcie, 0, fn, 0, ep->irq_phys_addr); ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY; ep->irq_pci_fn = fn; @@ -370,7 +370,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) || ep->irq_pci_fn != fn)) { /* First region was reserved for IRQ writes. */ - cdns_pcie_set_outbound_region(pcie, fn, 0, + cdns_pcie_set_outbound_region(pcie, 0, fn, 0, false, ep->irq_phys_addr, pci_addr & ~pci_addr_mask, @@ -415,7 +415,7 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) || ep->irq_pci_fn != fn) { /* First region was reserved for IRQ writes. */ - cdns_pcie_set_outbound_region(pcie, fn, 0, + cdns_pcie_set_outbound_region(pcie, 0, fn, 0, false, ep->irq_phys_addr, msg_addr & ~pci_addr_mask, @@ -518,8 +518,7 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) pcie->is_rc = false; - 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); 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; } diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c index 8a02981fd456..3c3646502d05 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.c +++ b/drivers/pci/controller/cadence/pcie-cadence.c @@ -7,7 +7,7 @@ #include "pcie-cadence.h" -void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn, +void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn, u32 r, bool is_io, u64 cpu_addr, u64 pci_addr, size_t size) { @@ -60,7 +60,7 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn, /* The device and function numbers are always 0. */ desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID | CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0); - desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus); + desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr); } else { /* * Use captured values for bus and device numbers but still @@ -84,7 +84,8 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn, cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1); } -void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn, +void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, + u8 busnr, u8 fn, u32 r, u64 cpu_addr) { u32 addr0, addr1, desc0, desc1; @@ -96,7 +97,7 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn, if (pcie->is_rc) { desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID | CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0); - desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus); + desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr); } else { desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn); } diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h index 00e44256c3e8..feed1e3038f4 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.h +++ b/drivers/pci/controller/cadence/pcie-cadence.h @@ -272,7 +272,6 @@ struct cdns_pcie { struct resource *mem_res; struct device *dev; bool is_rc; - u8 bus; int phy_count; struct phy **phy; struct device_link **link; @@ -285,7 +284,6 @@ struct cdns_pcie { * @dev: pointer to PCIe device * @cfg_res: start/end offsets in the physical system memory to map PCI * configuration space accesses - * @bus_range: first/last buses behind the PCIe host controller * @cfg_base: IO mapped window to access the PCI configuration space of a * single function at a time * @vendor_id: PCI vendor ID @@ -296,7 +294,6 @@ struct cdns_pcie { struct cdns_pcie_rc { struct cdns_pcie pcie; struct resource *cfg_res; - struct resource *bus_range; void __iomem *cfg_base; u32 vendor_id; u32 device_id; @@ -498,11 +495,12 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) return 0; } #endif -void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn, +void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn, u32 r, bool is_io, u64 cpu_addr, u64 pci_addr, size_t size); -void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn, +void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, + u8 busnr, u8 fn, u32 r, u64 cpu_addr); void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r); diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c index a075eba45abb..5b136a59938d 100644 --- a/drivers/pci/controller/dwc/pci-exynos.c +++ b/drivers/pci/controller/dwc/pci-exynos.c @@ -84,14 +84,12 @@ static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev, { struct dw_pcie *pci = ep->pci; struct device *dev = pci->dev; - struct resource *res; ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL); if (!ep->mem_res) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ep->mem_res->elbi_base = devm_ioremap_resource(dev, res); + ep->mem_res->elbi_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ep->mem_res->elbi_base)) return PTR_ERR(ep->mem_res->elbi_base); diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 4e5c379ae418..12ac47178c91 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1269,7 +1269,7 @@ static void imx6_pcie_quirk(struct pci_dev *dev) if (bus->dev.parent->parent->driver != &imx6_pcie_driver.driver) return; - if (bus->number == pp->root_bus_nr) { + if (pci_is_root_bus(bus)) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci); diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 0b7ed21cf8d0..d274c64d6799 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -440,7 +440,7 @@ static int ks_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) | CFG_FUNC(PCI_FUNC(devfn)); - if (bus->parent->number != pp->root_bus_nr) + if (!pci_is_root_bus(bus->parent)) reg |= CFG_TYPE1; ks_pcie_app_writel(ks_pcie, CFG_SETUP, reg); @@ -457,7 +457,7 @@ static int ks_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) | CFG_FUNC(PCI_FUNC(devfn)); - if (bus->parent->number != pp->root_bus_nr) + if (!pci_is_root_bus(bus->parent)) reg |= CFG_TYPE1; ks_pcie_app_writel(ks_pcie, CFG_SETUP, reg); diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c index 270868f3859a..d57d4ee15848 100644 --- a/drivers/pci/controller/dwc/pcie-al.c +++ b/drivers/pci/controller/dwc/pcie-al.c @@ -67,13 +67,8 @@ static int al_pcie_init(struct pci_config_window *cfg) dev_dbg(dev, "Root port dbi res: %pR\n", res); al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res); - if (IS_ERR(al_pcie->dbi_base)) { - long err = PTR_ERR(al_pcie->dbi_base); - - dev_err(dev, "couldn't remap dbi base %pR (err:%ld)\n", - res, err); - return err; - } + if (IS_ERR(al_pcie->dbi_base)) + return PTR_ERR(al_pcie->dbi_base); cfg->priv = al_pcie; @@ -408,10 +403,8 @@ static int al_pcie_probe(struct platform_device *pdev) dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res); - if (IS_ERR(pci->dbi_base)) { - dev_err(dev, "couldn't remap dbi base %pR\n", dbi_res); + if (IS_ERR(pci->dbi_base)) return PTR_ERR(pci->dbi_base); - } ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); if (!ecam_res) { diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c index 49596547e8c2..896b95d6917c 100644 --- a/drivers/pci/controller/dwc/pcie-armada8k.c +++ b/drivers/pci/controller/dwc/pcie-armada8k.c @@ -317,7 +317,6 @@ static int armada8k_pcie_probe(struct platform_device *pdev) base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); 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); goto fail_clkreg; } diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 2cb286a49293..9dafecba347f 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -346,11 +346,6 @@ int dw_pcie_host_init(struct pcie_port *pp) if (!bridge) return -ENOMEM; - ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (ret) - return ret; - /* Get the I/O and memory ranges from DT */ resource_list_for_each_entry(win, &bridge->windows) { switch (resource_type(win->res)) { @@ -473,14 +468,8 @@ int dw_pcie_host_init(struct pcie_port *pp) goto err_free_msi; } - pp->root_bus_nr = pp->busn->start; - - bridge->dev.parent = dev; bridge->sysdata = pp; - bridge->busnr = pp->root_bus_nr; bridge->ops = &dw_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; ret = pci_scan_root_bus_bridge(bridge); if (ret) @@ -529,7 +518,7 @@ static int dw_pcie_access_other_conf(struct pcie_port *pp, struct pci_bus *bus, busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | PCIE_ATU_FUNC(PCI_FUNC(devfn)); - if (bus->parent->number == pp->root_bus_nr) { + if (pci_is_root_bus(bus->parent)) { type = PCIE_ATU_TYPE_CFG0; cpu_addr = pp->cfg0_base; cfg_size = pp->cfg0_size; @@ -585,13 +574,11 @@ static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, struct dw_pcie *pci = to_dw_pcie_from_pp(pp); /* If there is no link, then there is no device */ - if (bus->number != pp->root_bus_nr) { + if (!pci_is_root_bus(bus)) { if (!dw_pcie_link_up(pci)) return 0; - } - - /* Access only one slot on each root port */ - if (bus->number == pp->root_bus_nr && dev > 0) + } else if (dev > 0) + /* Access only one slot on each root port */ return 0; return 1; @@ -607,7 +594,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, return PCIBIOS_DEVICE_NOT_FOUND; } - if (bus->number == pp->root_bus_nr) + if (pci_is_root_bus(bus)) return dw_pcie_rd_own_conf(pp, where, size, val); return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val); @@ -621,7 +608,7 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn))) return PCIBIOS_DEVICE_NOT_FOUND; - if (bus->number == pp->root_bus_nr) + if (pci_is_root_bus(bus)) return dw_pcie_wr_own_conf(pp, where, size, val); return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 90915dc89e08..f911760dcc69 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -173,7 +173,6 @@ struct dw_pcie_host_ops { }; struct pcie_port { - u8 root_bus_nr; u64 cfg0_base; void __iomem *va_cfg0_base; u32 cfg0_size; diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c index 7d0cdfd8138b..cdfde1bd7d8e 100644 --- a/drivers/pci/controller/dwc/pcie-spear13xx.c +++ b/drivers/pci/controller/dwc/pcie-spear13xx.c @@ -273,7 +273,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev) dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); 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); goto fail_clk; } diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c index 5907baa9b1f2..33ab36d73906 100644 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c @@ -29,18 +29,15 @@ static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) { - struct mobiveil_pcie *pcie = bus->sysdata; - struct mobiveil_root_port *rp = &pcie->rp; - /* Only one device down on each root port */ - if ((bus->number == rp->root_bus_nr) && (devfn > 0)) + if (pci_is_root_bus(bus) && (devfn > 0)) return false; /* * Do not read more than one device on the bus directly * attached to RC */ - if ((bus->primary == rp->root_bus_nr) && (PCI_SLOT(devfn) > 0)) + if ((bus->primary == to_pci_host_bridge(bus->bridge)->busnr) && (PCI_SLOT(devfn) > 0)) return false; return true; @@ -61,7 +58,7 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus, return NULL; /* RC config access */ - if (bus->number == rp->root_bus_nr) + if (pci_is_root_bus(bus)) return pcie->csr_axi_slave_base + where; /* @@ -569,8 +566,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie) struct mobiveil_root_port *rp = &pcie->rp; struct pci_host_bridge *bridge = rp->bridge; struct device *dev = &pcie->pdev->dev; - struct pci_bus *bus; - struct pci_bus *child; int ret; ret = mobiveil_pcie_parse_dt(pcie); @@ -582,14 +577,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie) if (!mobiveil_pcie_is_bridge(pcie)) return -ENODEV; - /* parse the host bridge base addresses from the device tree file */ - ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (ret) { - dev_err(dev, "Getting bridge resources failed\n"); - return ret; - } - /* * configure all inbound and outbound windows and prepare the RC for * config access @@ -607,12 +594,8 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie) } /* Initialize bridge */ - bridge->dev.parent = dev; bridge->sysdata = pcie; - bridge->busnr = rp->root_bus_nr; bridge->ops = &mobiveil_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; ret = mobiveil_bringup_link(pcie); if (ret) { @@ -620,17 +603,5 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie) return ret; } - /* setup the kernel resources for the newly added PCIe root bus */ - ret = pci_scan_root_bus_bridge(bridge); - if (ret) - return ret; - - bus = bridge->bus; - - pci_assign_unassigned_bus_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - pci_bus_add_devices(bus); - - return 0; + return pci_host_probe(bridge); } diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h index 767e36a8522d..6082b8afbc31 100644 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h @@ -149,7 +149,6 @@ struct mobiveil_rp_ops { }; struct mobiveil_root_port { - char root_bus_nr; void __iomem *config_axi_slave_base; /* endpoint config base */ struct resource *ob_io_res; struct mobiveil_rp_ops *ops; diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 1258f45cbc11..1559f79e63b6 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -195,7 +195,6 @@ struct advk_pcie { DECLARE_BITMAP(msi_used, MSI_IRQ_NUM); struct mutex msi_used_lock; u16 msi_msg; - int root_bus_nr; int link_gen; struct pci_bridge_emul bridge; struct gpio_desc *reset_gpio; @@ -641,14 +640,14 @@ static void advk_sw_pci_bridge_init(struct advk_pcie *pcie) static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus, int devfn) { - if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) + if (pci_is_root_bus(bus) && PCI_SLOT(devfn) != 0) return false; /* * If the link goes down after we check for link-up, nothing bad * happens but the config access times out. */ - if (bus->number != pcie->root_bus_nr && !advk_pcie_link_up(pcie)) + if (!pci_is_root_bus(bus) && !advk_pcie_link_up(pcie)) return false; return true; @@ -666,7 +665,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, return PCIBIOS_DEVICE_NOT_FOUND; } - if (bus->number == pcie->root_bus_nr) + if (pci_is_root_bus(bus)) return pci_bridge_emul_conf_read(&pcie->bridge, where, size, val); @@ -677,7 +676,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, /* Program the control register */ reg = advk_readl(pcie, PIO_CTRL); reg &= ~PIO_CTRL_TYPE_MASK; - if (bus->primary == pcie->root_bus_nr) + if (pci_is_root_bus(bus->parent)) reg |= PCIE_CONFIG_RD_TYPE0; else reg |= PCIE_CONFIG_RD_TYPE1; @@ -724,7 +723,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (!advk_pcie_valid_device(pcie, bus, devfn)) return PCIBIOS_DEVICE_NOT_FOUND; - if (bus->number == pcie->root_bus_nr) + if (pci_is_root_bus(bus)) return pci_bridge_emul_conf_write(&pcie->bridge, where, size, val); @@ -738,7 +737,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, /* Program the control register */ reg = advk_readl(pcie, PIO_CTRL); reg &= ~PIO_CTRL_TYPE_MASK; - if (bus->primary == pcie->root_bus_nr) + if (pci_is_root_bus(bus->parent)) reg |= PCIE_CONFIG_WR_TYPE0; else reg |= PCIE_CONFIG_WR_TYPE1; @@ -1114,7 +1113,6 @@ static int advk_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct advk_pcie *pcie; - struct resource *res, *bus; struct pci_host_bridge *bridge; int ret, irq; @@ -1125,8 +1123,7 @@ static int advk_pcie_probe(struct platform_device *pdev) pcie = pci_host_bridge_priv(bridge); pcie->pdev = pdev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pcie->base = devm_ioremap_resource(dev, res); + pcie->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); @@ -1142,14 +1139,6 @@ static int advk_pcie_probe(struct platform_device *pdev) return ret; } - ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, &bus); - if (ret) { - dev_err(dev, "Failed to parse resources\n"); - return ret; - } - pcie->root_bus_nr = bus->start; - pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, "reset-gpios", 0, GPIOD_OUT_LOW, @@ -1193,12 +1182,8 @@ static int advk_pcie_probe(struct platform_device *pdev) return ret; } - bridge->dev.parent = dev; bridge->sysdata = pcie; - bridge->busnr = 0; bridge->ops = &advk_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; ret = pci_host_probe(bridge); if (ret < 0) { diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index 1b67564de7af..da3cd216da00 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c @@ -422,7 +422,6 @@ static int faraday_pci_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const struct faraday_pci_variant *variant = of_device_get_match_data(dev); - struct resource *regs; struct resource_entry *win; struct faraday_pci *p; struct resource *io; @@ -437,12 +436,7 @@ static int faraday_pci_probe(struct platform_device *pdev) if (!host) return -ENOMEM; - host->dev.parent = dev; host->ops = &faraday_pci_ops; - host->busnr = 0; - host->msi = NULL; - host->map_irq = of_irq_parse_and_map_pci; - host->swizzle_irq = pci_common_swizzle; p = pci_host_bridge_priv(host); host->sysdata = p; p->dev = dev; @@ -465,16 +459,10 @@ static int faraday_pci_probe(struct platform_device *pdev) return ret; } - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - p->base = devm_ioremap_resource(dev, regs); + p->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(p->base)) return PTR_ERR(p->base); - ret = pci_parse_request_of_pci_ranges(dev, &host->windows, - &host->dma_ranges, NULL); - if (ret) - return ret; - win = resource_list_first_type(&host->windows, IORESOURCE_IO); if (win) { io = win->res; diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c index 953de57f6c57..6ce34a1deecb 100644 --- a/drivers/pci/controller/pci-host-common.c +++ b/drivers/pci/controller/pci-host-common.c @@ -21,39 +21,32 @@ static void gen_pci_unmap_cfg(void *ptr) } static struct pci_config_window *gen_pci_init(struct device *dev, - struct list_head *resources, const struct pci_ecam_ops *ops) + struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops) { int err; struct resource cfgres; - struct resource *bus_range = NULL; + struct resource_entry *bus; struct pci_config_window *cfg; - /* Parse our PCI ranges and request their resources */ - err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range); - if (err) - return ERR_PTR(err); - err = of_address_to_resource(dev->of_node, 0, &cfgres); if (err) { dev_err(dev, "missing \"reg\" property\n"); - goto err_out; + return ERR_PTR(err); } - cfg = pci_ecam_create(dev, &cfgres, bus_range, ops); - if (IS_ERR(cfg)) { - err = PTR_ERR(cfg); - goto err_out; - } + bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); + if (!bus) + return ERR_PTR(-ENODEV); + + cfg = pci_ecam_create(dev, &cfgres, bus->res, ops); + if (IS_ERR(cfg)) + return cfg; err = devm_add_action_or_reset(dev, gen_pci_unmap_cfg, cfg); - if (err) { - goto err_out; - } - return cfg; + if (err) + return ERR_PTR(err); -err_out: - pci_free_resource_list(resources); - return ERR_PTR(err); + return cfg; } int pci_host_common_probe(struct platform_device *pdev) @@ -61,9 +54,7 @@ int pci_host_common_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct pci_host_bridge *bridge; struct pci_config_window *cfg; - struct list_head resources; const struct pci_ecam_ops *ops; - int ret; ops = of_device_get_match_data(&pdev->dev); if (!ops) @@ -76,7 +67,7 @@ int pci_host_common_probe(struct platform_device *pdev) of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - cfg = gen_pci_init(dev, &resources, ops); + cfg = gen_pci_init(dev, bridge, ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); @@ -84,32 +75,22 @@ int pci_host_common_probe(struct platform_device *pdev) if (!pci_has_flag(PCI_PROBE_ONLY)) pci_add_flags(PCI_REASSIGN_ALL_BUS); - list_splice_init(&resources, &bridge->windows); - bridge->dev.parent = dev; bridge->sysdata = cfg; - bridge->busnr = cfg->busr.start; bridge->ops = (struct pci_ops *)&ops->pci_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; - ret = pci_host_probe(bridge); - if (ret < 0) { - pci_free_resource_list(&resources); - return ret; - } + platform_set_drvdata(pdev, bridge); - platform_set_drvdata(pdev, bridge->bus); - return 0; + return pci_host_probe(bridge); } EXPORT_SYMBOL_GPL(pci_host_common_probe); int pci_host_common_remove(struct platform_device *pdev) { - struct pci_bus *bus = platform_get_drvdata(pdev); + struct pci_host_bridge *bridge = platform_get_drvdata(pdev); pci_lock_rescan_remove(); - pci_stop_root_bus(bus); - pci_remove_root_bus(bus); + pci_stop_root_bus(bridge->bus); + pci_remove_root_bus(bridge->bus); pci_unlock_rescan_remove(); return 0; diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 58b862aaa6e9..719c19fe2bfb 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -218,14 +218,6 @@ static int loongson_pci_probe(struct platform_device *pdev) } } - err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (err) { - dev_err(dev, "failed to get bridge resources\n"); - return err; - } - - bridge->dev.parent = dev; bridge->sysdata = priv; bridge->ops = &loongson_pci_ops; bridge->map_irq = loongson_map_irq; diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index 101c06602aa1..c39978b750ec 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c @@ -71,7 +71,6 @@ struct mvebu_pcie { struct platform_device *pdev; struct mvebu_pcie_port *ports; struct msi_controller *msi; - struct list_head resources; struct resource io; struct resource realio; struct resource mem; @@ -969,17 +968,16 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie) { struct device *dev = &pcie->pdev->dev; struct device_node *np = dev->of_node; + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); int ret; - INIT_LIST_HEAD(&pcie->resources); - /* Get the bus range */ ret = of_pci_parse_bus_range(np, &pcie->busn); if (ret) { dev_err(dev, "failed to parse bus-range property: %d\n", ret); return ret; } - pci_add_resource(&pcie->resources, &pcie->busn); + pci_add_resource(&bridge->windows, &pcie->busn); /* Get the PCIe memory aperture */ mvebu_mbus_get_pcie_mem_aperture(&pcie->mem); @@ -989,7 +987,7 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie) } pcie->mem.name = "PCI MEM"; - pci_add_resource(&pcie->resources, &pcie->mem); + pci_add_resource(&bridge->windows, &pcie->mem); /* Get the PCIe IO aperture */ mvebu_mbus_get_pcie_io_aperture(&pcie->io); @@ -1002,10 +1000,10 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie) resource_size(&pcie->io) - 1); pcie->realio.name = "PCI I/O"; - pci_add_resource(&pcie->resources, &pcie->realio); + pci_add_resource(&bridge->windows, &pcie->realio); } - return devm_request_pci_bus_resources(dev, &pcie->resources); + return devm_request_pci_bus_resources(dev, &bridge->windows); } /* @@ -1126,13 +1124,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev) pcie->nports = i; - list_splice_init(&pcie->resources, &bridge->windows); - bridge->dev.parent = dev; bridge->sysdata = pcie; - bridge->busnr = 0; bridge->ops = &mvebu_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; bridge->align_resource = mvebu_pcie_align_resource; bridge->msi = pcie->msi; diff --git a/drivers/pci/controller/pci-rcar-gen2.c b/drivers/pci/controller/pci-rcar-gen2.c index 326171cb1a97..c9530038ca9a 100644 --- a/drivers/pci/controller/pci-rcar-gen2.c +++ b/drivers/pci/controller/pci-rcar-gen2.c @@ -98,22 +98,17 @@ struct rcar_pci_priv { void __iomem *reg; struct resource mem_res; struct resource *cfg_res; - unsigned busnr; int irq; - unsigned long window_size; - unsigned long window_addr; - unsigned long window_pci; }; /* PCI configuration space operations */ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, int where) { - struct pci_sys_data *sys = bus->sysdata; - struct rcar_pci_priv *priv = sys->private_data; + struct rcar_pci_priv *priv = bus->sysdata; int slot, val; - if (sys->busnr != bus->number || PCI_FUNC(devfn)) + if (!pci_is_root_bus(bus) || PCI_FUNC(devfn)) return NULL; /* Only one EHCI/OHCI device built-in */ @@ -132,20 +127,6 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, return priv->reg + (slot >> 1) * 0x100 + where; } -/* PCI interrupt mapping */ -static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - struct pci_sys_data *sys = dev->bus->sysdata; - struct rcar_pci_priv *priv = sys->private_data; - int irq; - - irq = of_irq_parse_and_map_pci(dev, slot, pin); - if (!irq) - irq = priv->irq; - - return irq; -} - #ifdef CONFIG_PCI_DEBUG /* if debug enabled, then attach an error handler irq to the bridge */ @@ -189,19 +170,33 @@ static inline void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) { } #endif /* PCI host controller setup */ -static int rcar_pci_setup(int nr, struct pci_sys_data *sys) +static void rcar_pci_setup(struct rcar_pci_priv *priv) { - struct rcar_pci_priv *priv = sys->private_data; + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(priv); struct device *dev = priv->dev; void __iomem *reg = priv->reg; + struct resource_entry *entry; + unsigned long window_size; + unsigned long window_addr; + unsigned long window_pci; u32 val; - int ret; + + entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM); + if (!entry) { + window_addr = 0x40000000; + window_pci = 0x40000000; + window_size = SZ_1G; + } else { + window_addr = entry->res->start; + window_pci = entry->res->start - entry->offset; + window_size = resource_size(entry->res); + } pm_runtime_enable(dev); pm_runtime_get_sync(dev); val = ioread32(reg + RCAR_PCI_UNIT_REV_REG); - dev_info(dev, "PCI: bus%u revision %x\n", sys->busnr, val); + dev_info(dev, "PCI: revision %x\n", val); /* Disable Direct Power Down State and assert reset */ val = ioread32(reg + RCAR_USBCTR_REG) & ~RCAR_USBCTR_DIRPD; @@ -214,7 +209,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST); /* Setup PCIAHB window1 size */ - switch (priv->window_size) { + switch (window_size) { case SZ_2G: val |= RCAR_USBCTR_PCIAHB_WIN1_2G; break; @@ -226,8 +221,8 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) break; default: pr_warn("unknown window size %ld - defaulting to 256M\n", - priv->window_size); - priv->window_size = SZ_256M; + window_size); + window_size = SZ_256M; /* fall-through */ case SZ_256M: val |= RCAR_USBCTR_PCIAHB_WIN1_256M; @@ -245,7 +240,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG); /* PCI-AHB mapping */ - iowrite32(priv->window_addr | RCAR_PCIAHB_PREFETCH16, + iowrite32(window_addr | RCAR_PCIAHB_PREFETCH16, reg + RCAR_PCIAHB_WIN1_CTR_REG); /* AHB-PCI mapping: OHCI/EHCI registers */ @@ -256,7 +251,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG, reg + RCAR_AHBPCI_WIN1_CTR_REG); /* Set PCI-AHB Window1 address */ - iowrite32(priv->window_pci | PCI_BASE_ADDRESS_MEM_PREFETCH, + iowrite32(window_pci | PCI_BASE_ADDRESS_MEM_PREFETCH, reg + PCI_BASE_ADDRESS_1); /* Set AHB-PCI bridge PCI communication area address */ val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET; @@ -271,18 +266,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME, reg + RCAR_PCI_INT_ENABLE_REG); - if (priv->irq > 0) - rcar_pci_setup_errirq(priv); - - /* Add PCI resources */ - pci_add_resource(&sys->resources, &priv->mem_res); - ret = devm_request_pci_bus_resources(dev, &sys->resources); - if (ret < 0) - return ret; - - /* Setup bus number based on platform device id / of bus-range */ - sys->busnr = priv->busnr; - return 1; + rcar_pci_setup_errirq(priv); } static struct pci_ops rcar_pci_ops = { @@ -291,55 +275,20 @@ static struct pci_ops rcar_pci_ops = { .write = pci_generic_config_write, }; -static int rcar_pci_parse_map_dma_ranges(struct rcar_pci_priv *pci, - struct device_node *np) -{ - struct device *dev = pci->dev; - struct of_pci_range range; - struct of_pci_range_parser parser; - int index = 0; - - /* Failure to parse is ok as we fall back to defaults */ - if (of_pci_dma_range_parser_init(&parser, np)) - return 0; - - /* Get the dma-ranges from DT */ - for_each_of_pci_range(&parser, &range) { - /* Hardware only allows one inbound 32-bit range */ - if (index) - return -EINVAL; - - pci->window_addr = (unsigned long)range.cpu_addr; - pci->window_pci = (unsigned long)range.pci_addr; - pci->window_size = (unsigned long)range.size; - - /* Catch HW limitations */ - if (!(range.flags & IORESOURCE_PREFETCH)) { - dev_err(dev, "window must be prefetchable\n"); - return -EINVAL; - } - if (pci->window_addr) { - u32 lowaddr = 1 << (ffs(pci->window_addr) - 1); - - if (lowaddr < pci->window_size) { - dev_err(dev, "invalid window size/addr\n"); - return -EINVAL; - } - } - index++; - } - - return 0; -} - static int rcar_pci_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct resource *cfg_res, *mem_res; struct rcar_pci_priv *priv; + struct pci_host_bridge *bridge; void __iomem *reg; - struct hw_pci hw; - void *hw_private[1]; + + bridge = devm_pci_alloc_host_bridge(dev, sizeof(*priv)); + if (!bridge) + return -ENOMEM; + + priv = pci_host_bridge_priv(bridge); + bridge->sysdata = priv; cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(dev, cfg_res); @@ -353,10 +302,6 @@ static int rcar_pci_probe(struct platform_device *pdev) if (mem_res->start & 0xFFFF) return -EINVAL; - priv = devm_kzalloc(dev, sizeof(struct rcar_pci_priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - priv->mem_res = *mem_res; priv->cfg_res = cfg_res; @@ -369,44 +314,13 @@ static int rcar_pci_probe(struct platform_device *pdev) return priv->irq; } - /* default window addr and size if not specified in DT */ - priv->window_addr = 0x40000000; - priv->window_pci = 0x40000000; - priv->window_size = SZ_1G; - - if (dev->of_node) { - struct resource busnr; - int ret; - - ret = of_pci_parse_bus_range(dev->of_node, &busnr); - if (ret < 0) { - dev_err(dev, "failed to parse bus-range\n"); - return ret; - } - - priv->busnr = busnr.start; - if (busnr.end != busnr.start) - dev_warn(dev, "only one bus number supported\n"); - - ret = rcar_pci_parse_map_dma_ranges(priv, dev->of_node); - if (ret < 0) { - dev_err(dev, "failed to parse dma-range\n"); - return ret; - } - } else { - priv->busnr = pdev->id; - } + bridge->ops = &rcar_pci_ops; + + pci_add_flags(PCI_REASSIGN_ALL_BUS); + + rcar_pci_setup(priv); - hw_private[0] = priv; - memset(&hw, 0, sizeof(hw)); - hw.nr_controllers = ARRAY_SIZE(hw_private); - hw.io_optional = 1; - hw.private_data = hw_private; - hw.map_irq = rcar_pci_map_irq; - hw.ops = &rcar_pci_ops; - hw.setup = rcar_pci_setup; - pci_common_init_dev(dev, &hw); - return 0; + return pci_host_probe(bridge); } static const struct of_device_id rcar_pci_of_match[] = { diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index e25e661a652c..fdbcf0d6b9c3 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -1437,7 +1437,7 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) { struct device *dev = pcie->dev; struct platform_device *pdev = to_platform_device(dev); - struct resource *pads, *afi, *res; + struct resource *res; const struct tegra_pcie_soc *soc = pcie->soc; int err; @@ -1461,15 +1461,13 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) } } - pads = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pads"); - pcie->pads = devm_ioremap_resource(dev, pads); + pcie->pads = devm_platform_ioremap_resource_byname(pdev, "pads"); if (IS_ERR(pcie->pads)) { err = PTR_ERR(pcie->pads); goto phys_put; } - afi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "afi"); - pcie->afi = devm_ioremap_resource(dev, afi); + pcie->afi = devm_platform_ioremap_resource_byname(pdev, "afi"); if (IS_ERR(pcie->afi)) { err = PTR_ERR(pcie->afi); goto phys_put; @@ -2632,8 +2630,6 @@ static int tegra_pcie_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct pci_host_bridge *host; struct tegra_pcie *pcie; - struct pci_bus *child; - struct resource *bus; int err; host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); @@ -2648,12 +2644,6 @@ static int tegra_pcie_probe(struct platform_device *pdev) INIT_LIST_HEAD(&pcie->ports); pcie->dev = dev; - err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus); - if (err) { - dev_err(dev, "Getting bridge resources failed\n"); - return err; - } - err = tegra_pcie_parse_dt(pcie); if (err < 0) return err; @@ -2677,26 +2667,15 @@ static int tegra_pcie_probe(struct platform_device *pdev) goto pm_runtime_put; } - host->busnr = bus->start; - host->dev.parent = &pdev->dev; host->ops = &tegra_pcie_ops; host->map_irq = tegra_pcie_map_irq; - host->swizzle_irq = pci_common_swizzle; - err = pci_scan_root_bus_bridge(host); + err = pci_host_probe(host); if (err < 0) { dev_err(dev, "failed to register host: %d\n", err); goto pm_runtime_put; } - pci_bus_size_bridges(host->bus); - pci_bus_assign_resources(host->bus); - - list_for_each_entry(child, &host->bus->children, node) - pcie_bus_configure_settings(child); - - pci_bus_add_devices(host->bus); - if (IS_ENABLED(CONFIG_DEBUG_FS)) { err = tegra_pcie_debugfs_init(pcie); if (err < 0) diff --git a/drivers/pci/controller/pci-v3-semi.c b/drivers/pci/controller/pci-v3-semi.c index 3681e5af3878..a38a416bcf3b 100644 --- a/drivers/pci/controller/pci-v3-semi.c +++ b/drivers/pci/controller/pci-v3-semi.c @@ -239,7 +239,6 @@ struct v3_pci { struct device *dev; void __iomem *base; void __iomem *config_base; - struct pci_bus *bus; u32 config_mem; u32 non_pre_mem; u32 pre_mem; @@ -585,8 +584,6 @@ static int v3_pci_setup_resource(struct v3_pci *v3, } break; case IORESOURCE_BUS: - dev_dbg(dev, "BUS %pR\n", win->res); - host->busnr = win->res->start; break; default: dev_info(dev, "Unknown resource type %lu\n", @@ -724,12 +721,7 @@ static int v3_pci_probe(struct platform_device *pdev) if (!host) return -ENOMEM; - host->dev.parent = dev; host->ops = &v3_pci_ops; - host->busnr = 0; - host->msi = NULL; - host->map_irq = of_irq_parse_and_map_pci; - host->swizzle_irq = pci_common_swizzle; v3 = pci_host_bridge_priv(host); host->sysdata = v3; v3->dev = dev; @@ -770,11 +762,6 @@ static int v3_pci_probe(struct platform_device *pdev) if (IS_ERR(v3->config_base)) return PTR_ERR(v3->config_base); - ret = pci_parse_request_of_pci_ranges(dev, &host->windows, - &host->dma_ranges, NULL); - if (ret) - return ret; - /* Get and request error IRQ resource */ irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -904,17 +891,7 @@ static int v3_pci_probe(struct platform_device *pdev) val |= V3_SYSTEM_M_LOCK; writew(val, v3->base + V3_SYSTEM); - ret = pci_scan_root_bus_bridge(host); - if (ret) { - dev_err(dev, "failed to register host: %d\n", ret); - return ret; - } - v3->bus = host->bus; - - pci_bus_assign_resources(v3->bus); - pci_bus_add_devices(v3->bus); - - return 0; + return pci_host_probe(host); } static const struct of_device_id v3_pci_of_match[] = { diff --git a/drivers/pci/controller/pci-versatile.c b/drivers/pci/controller/pci-versatile.c index b911359b6d81..653d5d0ecf81 100644 --- a/drivers/pci/controller/pci-versatile.c +++ b/drivers/pci/controller/pci-versatile.c @@ -67,23 +67,20 @@ static int versatile_pci_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct resource *res; struct resource_entry *entry; - int ret, i, myslot = -1, mem = 1; + int i, myslot = -1, mem = 1; u32 val; void __iomem *local_pci_cfg_base; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; bridge = devm_pci_alloc_host_bridge(dev, 0); if (!bridge) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - versatile_pci_base = devm_ioremap_resource(dev, res); + versatile_pci_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(versatile_pci_base)) return PTR_ERR(versatile_pci_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - versatile_cfg_base[0] = devm_ioremap_resource(dev, res); + versatile_cfg_base[0] = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(versatile_cfg_base[0])) return PTR_ERR(versatile_cfg_base[0]); @@ -92,11 +89,6 @@ static int versatile_pci_probe(struct platform_device *pdev) if (IS_ERR(versatile_cfg_base[1])) return PTR_ERR(versatile_cfg_base[1]); - ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - NULL, NULL); - if (ret) - return ret; - resource_list_for_each_entry(entry, &bridge->windows) { if (resource_type(entry->res) == IORESOURCE_MEM) { writel(entry->res->start >> 28, PCI_IMAP(mem)); @@ -154,28 +146,11 @@ static int versatile_pci_probe(struct platform_device *pdev) */ writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE); - pci_add_flags(PCI_ENABLE_PROC_DOMAINS); pci_add_flags(PCI_REASSIGN_ALL_BUS); - bridge->dev.parent = dev; - bridge->sysdata = NULL; - bridge->busnr = 0; bridge->ops = &pci_versatile_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; - - ret = pci_scan_root_bus_bridge(bridge); - if (ret < 0) - return ret; - - bus = bridge->bus; - - pci_assign_unassigned_bus_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - pci_bus_add_devices(bus); - return 0; + return pci_host_probe(bridge); } static const struct of_device_id versatile_pci_of_match[] = { diff --git a/drivers/pci/controller/pci-xgene.c b/drivers/pci/controller/pci-xgene.c index d1efa8ffbae1..8e0db84f089d 100644 --- a/drivers/pci/controller/pci-xgene.c +++ b/drivers/pci/controller/pci-xgene.c @@ -355,8 +355,7 @@ static int xgene_pcie_map_reg(struct xgene_pcie_port *port, if (IS_ERR(port->csr_base)) return PTR_ERR(port->csr_base); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); - port->cfg_base = devm_ioremap_resource(dev, res); + port->cfg_base = devm_platform_ioremap_resource_byname(pdev, "cfg"); if (IS_ERR(port->cfg_base)) return PTR_ERR(port->cfg_base); port->cfg_addr = res->start; @@ -591,7 +590,6 @@ static int xgene_pcie_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *dn = dev->of_node; struct xgene_pcie_port *port; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; int ret; @@ -616,33 +614,14 @@ static int xgene_pcie_probe(struct platform_device *pdev) if (ret) return ret; - ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (ret) - return ret; - ret = xgene_pcie_setup(port); if (ret) return ret; - bridge->dev.parent = dev; bridge->sysdata = port; - bridge->busnr = 0; bridge->ops = &xgene_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); - if (ret < 0) - return ret; - - bus = bridge->bus; - - pci_assign_unassigned_bus_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - pci_bus_add_devices(bus); - return 0; + return pci_host_probe(bridge); } static const struct of_device_id xgene_pcie_match_table[] = { diff --git a/drivers/pci/controller/pcie-altera-msi.c b/drivers/pci/controller/pcie-altera-msi.c index 16d938920ca5..613e19af71bd 100644 --- a/drivers/pci/controller/pcie-altera-msi.c +++ b/drivers/pci/controller/pcie-altera-msi.c @@ -228,8 +228,7 @@ static int altera_msi_probe(struct platform_device *pdev) mutex_init(&msi->lock); msi->pdev = pdev; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr"); - msi->csr_base = devm_ioremap_resource(&pdev->dev, res); + msi->csr_base = devm_platform_ioremap_resource_byname(pdev, "csr"); if (IS_ERR(msi->csr_base)) { dev_err(&pdev->dev, "failed to map csr memory\n"); return PTR_ERR(msi->csr_base); diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c index 24cb1c331058..70c04829b819 100644 --- a/drivers/pci/controller/pcie-altera.c +++ b/drivers/pci/controller/pcie-altera.c @@ -696,17 +696,14 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) { struct device *dev = &pcie->pdev->dev; struct platform_device *pdev = pcie->pdev; - struct resource *cra; - struct resource *hip; - cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra"); - pcie->cra_base = devm_ioremap_resource(dev, cra); + pcie->cra_base = devm_platform_ioremap_resource_byname(pdev, "Cra"); if (IS_ERR(pcie->cra_base)) return PTR_ERR(pcie->cra_base); if (pcie->pcie_data->version == ALTERA_PCIE_V2) { - hip = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Hip"); - pcie->hip_base = devm_ioremap_resource(&pdev->dev, hip); + pcie->hip_base = + devm_platform_ioremap_resource_byname(pdev, "Hip"); if (IS_ERR(pcie->hip_base)) return PTR_ERR(pcie->hip_base); } @@ -773,8 +770,6 @@ static int altera_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct altera_pcie *pcie; - struct pci_bus *bus; - struct pci_bus *child; struct pci_host_bridge *bridge; int ret; const struct of_device_id *match; @@ -799,13 +794,6 @@ static int altera_pcie_probe(struct platform_device *pdev) return ret; } - ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (ret) { - dev_err(dev, "Failed add resources\n"); - return ret; - } - ret = altera_pcie_init_irq_domain(pcie); if (ret) { dev_err(dev, "Failed creating IRQ Domain\n"); @@ -818,27 +806,11 @@ static int altera_pcie_probe(struct platform_device *pdev) cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE); altera_pcie_host_init(pcie); - bridge->dev.parent = dev; bridge->sysdata = pcie; bridge->busnr = pcie->root_bus_nr; bridge->ops = &altera_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; - - ret = pci_scan_root_bus_bridge(bridge); - if (ret < 0) - return ret; - - bus = bridge->bus; - - pci_assign_unassigned_bus_resources(bus); - /* Configure PCI Express setting. */ - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - - pci_bus_add_devices(bus); - return ret; + return pci_host_probe(bridge); } static int altera_pcie_remove(struct platform_device *pdev) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 7730ea845ff2..85fa7d54f11f 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -172,7 +172,6 @@ struct brcm_pcie { struct device *dev; void __iomem *base; struct clk *clk; - struct pci_bus *root_bus; struct device_node *np; bool ssc; int gen; @@ -919,9 +918,10 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie) static int brcm_pcie_remove(struct platform_device *pdev) { struct brcm_pcie *pcie = platform_get_drvdata(pdev); + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); - pci_stop_root_bus(pcie->root_bus); - pci_remove_root_bus(pcie->root_bus); + pci_stop_root_bus(bridge->bus); + pci_remove_root_bus(bridge->bus); __brcm_pcie_remove(pcie); return 0; @@ -933,8 +933,6 @@ static int brcm_pcie_probe(struct platform_device *pdev) struct pci_host_bridge *bridge; struct device_node *fw_np; struct brcm_pcie *pcie; - struct pci_bus *child; - struct resource *res; int ret; /* @@ -959,8 +957,7 @@ static int brcm_pcie_probe(struct platform_device *pdev) pcie->dev = &pdev->dev; pcie->np = np; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pcie->base = devm_ioremap_resource(&pdev->dev, res); + pcie->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); @@ -973,11 +970,6 @@ static int brcm_pcie_probe(struct platform_device *pdev) pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc"); - ret = pci_parse_request_of_pci_ranges(pcie->dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (ret) - return ret; - ret = clk_prepare_enable(pcie->clk); if (ret) { dev_err(&pdev->dev, "could not enable clock\n"); @@ -997,27 +989,12 @@ static int brcm_pcie_probe(struct platform_device *pdev) } } - bridge->dev.parent = &pdev->dev; - bridge->busnr = 0; bridge->ops = &brcm_pcie_ops; bridge->sysdata = pcie; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); - if (ret < 0) { - dev_err(pcie->dev, "Scanning root bridge failed\n"); - goto fail; - } - - pci_assign_unassigned_bus_resources(bridge->bus); - list_for_each_entry(child, &bridge->bus->children, node) - pcie_bus_configure_settings(child); - pci_bus_add_devices(bridge->bus); platform_set_drvdata(pdev, pcie); - pcie->root_bus = bridge->bus; - return 0; + return pci_host_probe(bridge); fail: __brcm_pcie_remove(pcie); return ret; diff --git a/drivers/pci/controller/pcie-iproc-platform.c b/drivers/pci/controller/pcie-iproc-platform.c index ff0a81a632a1..a956b0c18bd1 100644 --- a/drivers/pci/controller/pcie-iproc-platform.c +++ b/drivers/pci/controller/pcie-iproc-platform.c @@ -95,20 +95,14 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev) if (IS_ERR(pcie->phy)) return PTR_ERR(pcie->phy); - ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (ret) { - dev_err(dev, "unable to get PCI host bridge resources\n"); - return ret; - } - /* PAXC doesn't support legacy IRQs, skip mapping */ switch (pcie->type) { case IPROC_PCIE_PAXC: case IPROC_PCIE_PAXC_V2: + pcie->map_irq = 0; break; default: - pcie->map_irq = of_irq_parse_and_map_pci; + break; } ret = iproc_pcie_setup(pcie, &bridge->windows); diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c index 8c7f875acf7f..905e93808243 100644 --- a/drivers/pci/controller/pcie-iproc.c +++ b/drivers/pci/controller/pcie-iproc.c @@ -1470,7 +1470,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) { struct device *dev; int ret; - struct pci_bus *child; struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); dev = pcie->dev; @@ -1524,28 +1523,16 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) if (iproc_pcie_msi_enable(pcie)) dev_info(dev, "not using iProc MSI\n"); - host->busnr = 0; - host->dev.parent = dev; host->ops = &iproc_pcie_ops; host->sysdata = pcie; host->map_irq = pcie->map_irq; - host->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(host); + ret = pci_host_probe(host); if (ret < 0) { dev_err(dev, "failed to scan host: %d\n", ret); goto err_power_off_phy; } - pci_assign_unassigned_bus_resources(host->bus); - - pcie->root_bus = host->bus; - - list_for_each_entry(child, &host->bus->children, node) - pcie_bus_configure_settings(child); - - pci_bus_add_devices(host->bus); - return 0; err_power_off_phy: @@ -1558,8 +1545,10 @@ EXPORT_SYMBOL(iproc_pcie_setup); int iproc_pcie_remove(struct iproc_pcie *pcie) { - pci_stop_root_bus(pcie->root_bus); - pci_remove_root_bus(pcie->root_bus); + struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); + + pci_stop_root_bus(host->bus); + pci_remove_root_bus(host->bus); iproc_pcie_msi_disable(pcie); diff --git a/drivers/pci/controller/pcie-iproc.h b/drivers/pci/controller/pcie-iproc.h index 4f03ea539805..c2676e442f55 100644 --- a/drivers/pci/controller/pcie-iproc.h +++ b/drivers/pci/controller/pcie-iproc.h @@ -54,7 +54,6 @@ struct iproc_msi; * @reg_offsets: register offsets * @base: PCIe host controller I/O register base * @base_addr: PCIe host controller register base physical address - * @root_bus: pointer to root bus * @phy: optional PHY device that controls the Serdes * @map_irq: function callback to map interrupts * @ep_is_internal: indicates an internal emulated endpoint device is connected @@ -85,7 +84,6 @@ struct iproc_pcie { void __iomem *base; phys_addr_t base_addr; struct resource mem; - struct pci_bus *root_bus; struct phy *phy; int (*map_irq)(const struct pci_dev *, u8, u8); bool ep_is_internal; diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c index ebfa7d5a4e2d..cf4c18f0c25a 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c @@ -209,7 +209,6 @@ struct mtk_pcie_port { * @mem: non-prefetchable memory resource * @ports: pointer to PCIe port information * @soc: pointer to SoC-dependent operations - * @busnr: root bus number */ struct mtk_pcie { struct device *dev; @@ -218,7 +217,6 @@ struct mtk_pcie { struct list_head ports; const struct mtk_pcie_soc *soc; - unsigned int busnr; }; static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie) @@ -905,7 +903,6 @@ static int mtk_pcie_parse_port(struct mtk_pcie *pcie, int slot) { struct mtk_pcie_port *port; - struct resource *regs; struct device *dev = pcie->dev; struct platform_device *pdev = to_platform_device(dev); char name[10]; @@ -916,8 +913,7 @@ static int mtk_pcie_parse_port(struct mtk_pcie *pcie, return -ENOMEM; snprintf(name, sizeof(name), "port%d", slot); - regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); - port->base = devm_ioremap_resource(dev, regs); + port->base = devm_platform_ioremap_resource_byname(pdev, name); if (IS_ERR(port->base)) { dev_err(dev, "failed to map port%d base\n", slot); return PTR_ERR(port->base); @@ -1031,18 +1027,8 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie) struct device *dev = pcie->dev; struct device_node *node = dev->of_node, *child; struct mtk_pcie_port *port, *tmp; - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); - struct list_head *windows = &host->windows; - struct resource *bus; int err; - err = pci_parse_request_of_pci_ranges(dev, windows, - &host->dma_ranges, &bus); - if (err) - return err; - - pcie->busnr = bus->start; - for_each_available_child_of_node(node, child) { int slot; @@ -1096,11 +1082,7 @@ static int mtk_pcie_probe(struct platform_device *pdev) if (err) return err; - host->busnr = pcie->busnr; - host->dev.parent = pcie->dev; host->ops = pcie->soc->ops; - host->map_irq = of_irq_parse_and_map_pci; - host->swizzle_irq = pci_common_swizzle; host->sysdata = pcie; err = pci_host_probe(host); diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c index 060c24f5221e..cdc0963f154e 100644 --- a/drivers/pci/controller/pcie-rcar-host.c +++ b/drivers/pci/controller/pcie-rcar-host.c @@ -53,8 +53,6 @@ struct rcar_pcie_host { struct device *dev; struct phy *phy; void __iomem *base; - struct list_head resources; - int root_bus_nr; struct clk *bus_clk; struct rcar_msi msi; int (*phy_init_fn)(struct rcar_pcie_host *host); @@ -100,22 +98,14 @@ static int rcar_pcie_config_access(struct rcar_pcie_host *host, if (dev != 0) return PCIBIOS_DEVICE_NOT_FOUND; - if (access_type == RCAR_PCI_ACCESS_READ) { + if (access_type == RCAR_PCI_ACCESS_READ) *data = rcar_pci_read_reg(pcie, PCICONF(index)); - } else { - /* Keep an eye out for changes to the root bus number */ - if (pci_is_root_bus(bus) && (reg == PCI_PRIMARY_BUS)) - host->root_bus_nr = *data & 0xff; - + else rcar_pci_write_reg(pcie, *data, PCICONF(index)); - } return PCIBIOS_SUCCESSFUL; } - if (host->root_bus_nr < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - /* Clear errors */ rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR); @@ -124,7 +114,7 @@ static int rcar_pcie_config_access(struct rcar_pcie_host *host, PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR); /* Enable the configuration access */ - if (bus->parent->number == host->root_bus_nr) + if (pci_is_root_bus(bus->parent)) rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR); else rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR); @@ -212,38 +202,6 @@ static struct pci_ops rcar_pcie_ops = { .write = rcar_pcie_write_conf, }; -static int rcar_pcie_setup(struct list_head *resource, - struct rcar_pcie_host *host) -{ - struct resource_entry *win; - int i = 0; - - /* Setup PCI resources */ - resource_list_for_each_entry(win, &host->resources) { - struct resource *res = win->res; - - if (!res->flags) - continue; - - switch (resource_type(res)) { - case IORESOURCE_IO: - case IORESOURCE_MEM: - rcar_pcie_set_outbound(&host->pcie, i, win); - i++; - break; - case IORESOURCE_BUS: - host->root_bus_nr = res->start; - break; - default: - continue; - } - - pci_add_resource(resource, res); - } - - return 1; -} - static void rcar_pcie_force_speedup(struct rcar_pcie *pcie) { struct device *dev = pcie->dev; @@ -301,6 +259,7 @@ done: static void rcar_pcie_hw_enable(struct rcar_pcie_host *host) { struct rcar_pcie *pcie = &host->pcie; + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host); struct resource_entry *win; LIST_HEAD(res); int i = 0; @@ -309,7 +268,7 @@ static void rcar_pcie_hw_enable(struct rcar_pcie_host *host) rcar_pcie_force_speedup(pcie); /* Setup PCI resources */ - resource_list_for_each_entry(win, &host->resources) { + resource_list_for_each_entry(win, &bridge->windows) { struct resource *res = win->res; if (!res->flags) @@ -328,42 +287,17 @@ static void rcar_pcie_hw_enable(struct rcar_pcie_host *host) static int rcar_pcie_enable(struct rcar_pcie_host *host) { struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host); - struct rcar_pcie *pcie = &host->pcie; - struct device *dev = pcie->dev; - struct pci_bus *bus, *child; - int ret; - - /* Try setting 5 GT/s link speed */ - rcar_pcie_force_speedup(pcie); - rcar_pcie_setup(&bridge->windows, host); + rcar_pcie_hw_enable(host); pci_add_flags(PCI_REASSIGN_ALL_BUS); - bridge->dev.parent = dev; bridge->sysdata = host; - bridge->busnr = host->root_bus_nr; bridge->ops = &rcar_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; if (IS_ENABLED(CONFIG_PCI_MSI)) bridge->msi = &host->msi.chip; - ret = pci_scan_root_bus_bridge(bridge); - if (ret < 0) - return ret; - - bus = bridge->bus; - - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - - pci_bus_add_devices(bus); - - return 0; + return pci_host_probe(bridge); } static int phy_wait_for_ack(struct rcar_pcie *pcie) @@ -968,7 +902,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) int err; struct pci_host_bridge *bridge; - bridge = pci_alloc_host_bridge(sizeof(*host)); + bridge = devm_pci_alloc_host_bridge(dev, sizeof(*host)); if (!bridge) return -ENOMEM; @@ -977,11 +911,6 @@ static int rcar_pcie_probe(struct platform_device *pdev) pcie->dev = dev; platform_set_drvdata(pdev, host); - err = pci_parse_request_of_pci_ranges(dev, &host->resources, - &bridge->dma_ranges, NULL); - if (err) - goto err_free_bridge; - pm_runtime_enable(pcie->dev); err = pm_runtime_get_sync(pcie->dev); if (err < 0) { @@ -1058,10 +987,6 @@ err_unmap_msi_irqs: err_pm_put: pm_runtime_put(dev); pm_runtime_disable(dev); - pci_free_resource_list(&host->resources); - -err_free_bridge: - pci_free_host_bridge(bridge); return err; } diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c index 94af6f5828a3..153bc95ab29f 100644 --- a/drivers/pci/controller/pcie-rockchip-host.c +++ b/drivers/pci/controller/pcie-rockchip-host.c @@ -72,14 +72,14 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip, struct pci_bus *bus, int dev) { /* access only one slot on each root port */ - if (bus->number == rockchip->root_bus_nr && dev > 0) + if (pci_is_root_bus(bus) && dev > 0) return 0; /* * do not read more than one device on the bus directly attached * to RC's downstream side. */ - if (bus->primary == rockchip->root_bus_nr && dev > 0) + if (pci_is_root_bus(bus->parent) && dev > 0) return 0; return 1; @@ -170,7 +170,7 @@ static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip, return PCIBIOS_BAD_REGISTER_NUMBER; } - if (bus->parent->number == rockchip->root_bus_nr) + if (pci_is_root_bus(bus->parent)) rockchip_pcie_cfg_configuration_accesses(rockchip, AXI_WRAPPER_TYPE0_CFG); else @@ -201,7 +201,7 @@ static int rockchip_pcie_wr_other_conf(struct rockchip_pcie *rockchip, if (!IS_ALIGNED(busdev, size)) return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus->parent->number == rockchip->root_bus_nr) + if (pci_is_root_bus(bus->parent)) rockchip_pcie_cfg_configuration_accesses(rockchip, AXI_WRAPPER_TYPE0_CFG); else @@ -230,7 +230,7 @@ static int rockchip_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, return PCIBIOS_DEVICE_NOT_FOUND; } - if (bus->number == rockchip->root_bus_nr) + if (pci_is_root_bus(bus)) return rockchip_pcie_rd_own_conf(rockchip, where, size, val); return rockchip_pcie_rd_other_conf(rockchip, bus, devfn, where, size, @@ -245,7 +245,7 @@ static int rockchip_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (!rockchip_pcie_valid_device(rockchip, bus, PCI_SLOT(devfn))) return PCIBIOS_DEVICE_NOT_FOUND; - if (bus->number == rockchip->root_bus_nr) + if (pci_is_root_bus(bus)) return rockchip_pcie_wr_own_conf(rockchip, where, size, val); return rockchip_pcie_wr_other_conf(rockchip, bus, devfn, where, size, @@ -949,9 +949,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) { struct rockchip_pcie *rockchip; struct device *dev = &pdev->dev; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; - struct resource *bus_res; int err; if (!dev->of_node) @@ -991,13 +989,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev) if (err < 0) goto err_deinit_port; - err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, &bus_res); - if (err) - goto err_remove_irq_domain; - - rockchip->root_bus_nr = bus_res->start; - err = rockchip_pcie_cfg_atu(rockchip); if (err) goto err_remove_irq_domain; @@ -1008,27 +999,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev) goto err_remove_irq_domain; } - bridge->dev.parent = dev; bridge->sysdata = rockchip; - bridge->busnr = 0; bridge->ops = &rockchip_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; - err = pci_scan_root_bus_bridge(bridge); + err = pci_host_probe(bridge); if (err < 0) goto err_remove_irq_domain; - bus = bridge->bus; - - rockchip->root_bus = bus; - - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - - pci_bus_add_devices(bus); return 0; err_remove_irq_domain: @@ -1051,9 +1028,10 @@ static int rockchip_pcie_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rockchip_pcie *rockchip = dev_get_drvdata(dev); + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rockchip); - pci_stop_root_bus(rockchip->root_bus); - pci_remove_root_bus(rockchip->root_bus); + pci_stop_root_bus(bridge->bus); + pci_remove_root_bus(bridge->bus); irq_domain_remove(rockchip->irq_domain); rockchip_pcie_deinit_phys(rockchip); diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c index c53d1322a3d6..904dec0d3a88 100644 --- a/drivers/pci/controller/pcie-rockchip.c +++ b/drivers/pci/controller/pcie-rockchip.c @@ -45,9 +45,8 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) return -EINVAL; } - regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "apb-base"); - rockchip->apb_base = devm_ioremap_resource(dev, regs); + rockchip->apb_base = + devm_platform_ioremap_resource_byname(pdev, "apb-base"); if (IS_ERR(rockchip->apb_base)) return PTR_ERR(rockchip->apb_base); diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h index d90dfb354573..c7d0178fc8c2 100644 --- a/drivers/pci/controller/pcie-rockchip.h +++ b/drivers/pci/controller/pcie-rockchip.h @@ -298,12 +298,10 @@ struct rockchip_pcie { struct gpio_desc *ep_gpio; u32 lanes; u8 lanes_map; - u8 root_bus_nr; int link_gen; struct device *dev; struct irq_domain *irq_domain; int offset; - struct pci_bus *root_bus; void __iomem *msg_region; phys_addr_t msg_bus_addr; bool is_rc; diff --git a/drivers/pci/controller/pcie-xilinx-cpm.c b/drivers/pci/controller/pcie-xilinx-cpm.c index cd8c77457b5f..f3082de44e8a 100644 --- a/drivers/pci/controller/pcie-xilinx-cpm.c +++ b/drivers/pci/controller/pcie-xilinx-cpm.c @@ -539,7 +539,7 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev) struct xilinx_cpm_pcie_port *port; struct device *dev = &pdev->dev; struct pci_host_bridge *bridge; - struct resource *bus_range; + struct resource_entry *bus; int err; bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port)); @@ -550,18 +550,15 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev) port->dev = dev; - err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, &bus_range); - if (err) { - dev_err(dev, "Getting bridge resources failed\n"); - return err; - } - err = xilinx_cpm_pcie_init_irq_domain(port); if (err) return err; - err = xilinx_cpm_pcie_parse_dt(port, bus_range); + bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); + if (!bus) + return -ENODEV; + + err = xilinx_cpm_pcie_parse_dt(port, bus->res); if (err) { dev_err(dev, "Parsing DT failed\n"); goto err_parse_dt; diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c index 9bd1427f2fd6..97305bfe81b5 100644 --- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c @@ -166,7 +166,6 @@ struct nwl_pcie { int irq_misc; u32 ecam_value; u8 last_busno; - u8 root_busno; struct nwl_msi msi; struct irq_domain *legacy_irq_domain; raw_spinlock_t leg_mask_lock; @@ -217,13 +216,11 @@ static bool nwl_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) struct nwl_pcie *pcie = bus->sysdata; /* Check link before accessing downstream ports */ - if (bus->number != pcie->root_busno) { + if (!pci_is_root_bus(bus)) { if (!nwl_pcie_link_up(pcie)) return false; - } - - /* Only one device down on each root port */ - if (bus->number == pcie->root_busno && devfn > 0) + } else if (devfn > 0) + /* Only one device down on each root port */ return false; return true; @@ -817,8 +814,6 @@ static int nwl_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct nwl_pcie *pcie; - struct pci_bus *bus; - struct pci_bus *child; struct pci_host_bridge *bridge; int err; @@ -843,25 +838,14 @@ static int nwl_pcie_probe(struct platform_device *pdev) return err; } - err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (err) { - dev_err(dev, "Getting bridge resources failed\n"); - return err; - } - err = nwl_pcie_init_irq_domain(pcie); if (err) { dev_err(dev, "Failed creating IRQ Domain\n"); return err; } - bridge->dev.parent = dev; bridge->sysdata = pcie; - bridge->busnr = pcie->root_busno; bridge->ops = &nwl_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; if (IS_ENABLED(CONFIG_PCI_MSI)) { err = nwl_pcie_enable_msi(pcie); @@ -871,17 +855,7 @@ static int nwl_pcie_probe(struct platform_device *pdev) } } - err = pci_scan_root_bus_bridge(bridge); - if (err) - return err; - - bus = bridge->bus; - - pci_assign_unassigned_bus_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - pci_bus_add_devices(bus); - return 0; + return pci_host_probe(bridge); } static struct platform_driver nwl_pcie_driver = { diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c index 98e55297815b..8523be61bba5 100644 --- a/drivers/pci/controller/pcie-xilinx.c +++ b/drivers/pci/controller/pcie-xilinx.c @@ -98,7 +98,6 @@ * @reg_base: IO Mapped Register Base * @irq: Interrupt number * @msi_pages: MSI pages - * @root_busno: Root Bus number * @dev: Device pointer * @msi_domain: MSI IRQ domain pointer * @leg_domain: Legacy IRQ domain pointer @@ -108,7 +107,6 @@ struct xilinx_pcie_port { void __iomem *reg_base; u32 irq; unsigned long msi_pages; - u8 root_busno; struct device *dev; struct irq_domain *msi_domain; struct irq_domain *leg_domain; @@ -162,14 +160,13 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) struct xilinx_pcie_port *port = bus->sysdata; /* Check if link is up when trying to access downstream ports */ - if (bus->number != port->root_busno) + if (!pci_is_root_bus(bus)) { if (!xilinx_pcie_link_up(port)) return false; - - /* Only one device down on each root port */ - if (bus->number == port->root_busno && devfn > 0) + } else if (devfn > 0) { + /* Only one device down on each root port */ return false; - + } return true; } @@ -616,7 +613,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct xilinx_pcie_port *port; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; int err; @@ -645,35 +641,14 @@ static int xilinx_pcie_probe(struct platform_device *pdev) return err; } - err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, - &bridge->dma_ranges, NULL); - if (err) { - dev_err(dev, "Getting bridge resources failed\n"); - return err; - } - - bridge->dev.parent = dev; bridge->sysdata = port; - bridge->busnr = 0; bridge->ops = &xilinx_pcie_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; #ifdef CONFIG_PCI_MSI xilinx_pcie_msi_chip.dev = dev; bridge->msi = &xilinx_pcie_msi_chip; #endif - err = pci_scan_root_bus_bridge(bridge); - if (err < 0) - return err; - - bus = bridge->bus; - - pci_assign_unassigned_bus_resources(bus); - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child); - pci_bus_add_devices(bus); - return 0; + return pci_host_probe(bridge); } static const struct of_device_id xilinx_pcie_of_match[] = { diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 22727fc9558d..2ebc5e32e8a0 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -521,28 +521,26 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci); #endif /* CONFIG_OF_IRQ */ -int pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, - struct list_head *ib_resources, - struct resource **bus_range) +static int pci_parse_request_of_pci_ranges(struct device *dev, + struct pci_host_bridge *bridge) { int err, res_valid = 0; resource_size_t iobase; struct resource_entry *win, *tmp; - INIT_LIST_HEAD(resources); - if (ib_resources) - INIT_LIST_HEAD(ib_resources); - err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, resources, - ib_resources, &iobase); + INIT_LIST_HEAD(&bridge->windows); + INIT_LIST_HEAD(&bridge->dma_ranges); + + err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &bridge->windows, + &bridge->dma_ranges, &iobase); if (err) return err; - err = devm_request_pci_bus_resources(dev, resources); + err = devm_request_pci_bus_resources(dev, &bridge->windows); if (err) - goto out_release_res; + return err; - resource_list_for_each_entry_safe(win, tmp, resources) { + resource_list_for_each_entry_safe(win, tmp, &bridge->windows) { struct resource *res = win->res; switch (resource_type(res)) { @@ -557,24 +555,25 @@ int pci_parse_request_of_pci_ranges(struct device *dev, case IORESOURCE_MEM: res_valid |= !(res->flags & IORESOURCE_PREFETCH); break; - case IORESOURCE_BUS: - if (bus_range) - *bus_range = res; - break; } } - if (res_valid) + if (!res_valid) + dev_warn(dev, "non-prefetchable memory resource required\n"); + + return 0; +} + +int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge) +{ + if (!dev->of_node) return 0; - dev_err(dev, "non-prefetchable memory resource required\n"); - err = -EINVAL; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = of_irq_parse_and_map_pci; - out_release_res: - pci_free_resource_list(resources); - return err; + return pci_parse_request_of_pci_ranges(dev, bridge); } -EXPORT_SYMBOL_GPL(pci_parse_request_of_pci_ranges); #endif /* CONFIG_PCI */ diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 42b95dba772a..fa12f7cbc1a0 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -628,6 +628,8 @@ void pci_release_of_node(struct pci_dev *dev); void pci_set_bus_of_node(struct pci_bus *bus); void pci_release_bus_of_node(struct pci_bus *bus); +int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge); + #else static inline int of_pci_parse_bus_range(struct device_node *node, struct resource *res) @@ -651,6 +653,12 @@ static inline void pci_set_of_node(struct pci_dev *dev) { } static inline void pci_release_of_node(struct pci_dev *dev) { } static inline void pci_set_bus_of_node(struct pci_bus *bus) { } static inline void pci_release_bus_of_node(struct pci_bus *bus) { } + +static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge) +{ + return 0; +} + #endif /* CONFIG_OF */ #ifdef CONFIG_PCIEAER diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 494333df46af..03d37128a24f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -628,11 +628,17 @@ struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev, if (!bridge) return NULL; + bridge->dev.parent = dev; + ret = devm_add_action_or_reset(dev, devm_pci_alloc_host_bridge_release, bridge); if (ret) return NULL; + ret = devm_of_pci_bridge_init(dev, bridge); + if (ret) + return NULL; + return bridge; } EXPORT_SYMBOL(devm_pci_alloc_host_bridge); @@ -3086,6 +3092,7 @@ int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge) resource_list_for_each_entry(window, &bridge->windows) if (window->res->flags & IORESOURCE_BUS) { + bridge->busnr = window->res->start; found = true; break; } |