Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46560388 authored by Ray Jui's avatar Ray Jui Committed by Bjorn Helgaas
Browse files

PCI: iproc: Allow multiple devices except on PAXC



Commit 943ebae7 ("PCI: iproc: Add PAXC interface support") only allowed
device 0, which is a regression on BCMA-based platforms.

All systems support only one device, a Root Port at 00:00.0, on the root
bus.  PAXC-based systems support only the Root Port (00:00.0) and a single
device (with multiple functions) below it, e.g., 01:00.0, 01:00.1, etc.
Non-PAXC systems support arbitrary devices below the Root Port.

[bhelgaas: changelog, fold in removal of MAX_NUM_PAXC_PF check]
Fixes: 943ebae7 ("PCI: iproc: Add PAXC interface support")
Reported-by: default avatarRafal Milecki <zajec5@gmail.com>
Signed-off-by: default avatarRay Jui <rjui@broadcom.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 4ae2182b
Loading
Loading
Loading
Loading
+11 −18
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@
#define OARR_SIZE_CFG                BIT(OARR_SIZE_CFG_SHIFT)

#define MAX_NUM_OB_WINDOWS           2
#define MAX_NUM_PAXC_PF              4

#define IPROC_PCIE_REG_INVALID 0xffff

@@ -170,20 +169,6 @@ static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie,
	writel(val, pcie->base + offset + (window * 8));
}

static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie,
					      unsigned int slot,
					      unsigned int fn)
{
	if (slot > 0)
		return false;

	/* PAXC can only support limited number of functions */
	if (pcie->type == IPROC_PCIE_PAXC && fn >= MAX_NUM_PAXC_PF)
		return false;

	return true;
}

/**
 * Note access to the configuration registers are protected at the higher layer
 * by 'pci_lock' in drivers/pci/access.c
@@ -199,11 +184,11 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
	u32 val;
	u16 offset;

	if (!iproc_pcie_device_is_valid(pcie, slot, fn))
		return NULL;

	/* root complex access */
	if (busno == 0) {
		if (slot > 0 || fn > 0)
			return NULL;

		iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
				     where & CFG_IND_ADDR_MASK);
		offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
@@ -213,6 +198,14 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
			return (pcie->base + offset);
	}

	/*
	 * PAXC is connected to an internally emulated EP within the SoC.  It
	 * allows only one device.
	 */
	if (pcie->type == IPROC_PCIE_PAXC)
		if (slot > 0)
			return NULL;

	/* EP device access */
	val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
		(slot << CFG_ADDR_DEV_NUM_SHIFT) |