forked from mirrors/linux
		
	PCI: iproc: Allow multiple devices except on PAXC
Commit943ebae781("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:943ebae781("PCI: iproc: Add PAXC interface support") Reported-by: Rafal Milecki <zajec5@gmail.com> Signed-off-by: Ray Jui <rjui@broadcom.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
		
							parent
							
								
									4ae2182b1e
								
							
						
					
					
						commit
						46560388c4
					
				
					 1 changed files with 11 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -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) |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue