84 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 46560388c476c8471fde7712c10f9fad8d0d1875 Mon Sep 17 00:00:00 2001
 | |
| From: Ray Jui <rjui@broadcom.com>
 | |
| Date: Wed, 27 Jan 2016 16:52:24 -0600
 | |
| Subject: [PATCH] PCI: iproc: Allow multiple devices except on PAXC
 | |
| 
 | |
| Commit 943ebae781f5 ("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: 943ebae781f5 ("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>
 | |
| ---
 | |
|  drivers/pci/host/pcie-iproc.c | 29 +++++++++++------------------
 | |
|  1 file changed, 11 insertions(+), 18 deletions(-)
 | |
| 
 | |
| --- a/drivers/pci/host/pcie-iproc.c
 | |
| +++ b/drivers/pci/host/pcie-iproc.c
 | |
| @@ -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(s
 | |
|  	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_
 | |
|  	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_
 | |
|  			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) |
 | 
