Commit 49e427e6 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

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
parents f8917db9 b64aa11e
Loading
Loading
Loading
Loading
+2 −10
Original line number Diff line number Diff line
@@ -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);

+5 −6
Original line number Diff line number Diff line
@@ -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);
+35 −69
Original line number Diff line number Diff line
@@ -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,11 +321,10 @@ 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 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;

 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;
}
+5 −4
Original line number Diff line number Diff line
@@ -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);
	}
+3 −5
Original line number Diff line number Diff line
@@ -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);
Loading