diff options
Diffstat (limited to 'drivers/pci/controller/cadence/pcie-cadence-ep.c')
-rw-r--r-- | drivers/pci/controller/cadence/pcie-cadence-ep.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index 2d0a8d78bffb..81c50dc64da9 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -565,7 +565,8 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) struct cdns_pcie *pcie = &ep->pcie; struct device *dev = pcie->dev; int max_epfs = sizeof(epc->function_num_map) * 8; - int ret, value, epf; + int ret, epf, last_fn; + u32 reg, value; /* * BIT(0) is hardwired to 1, hence function 0 is always enabled @@ -573,6 +574,17 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) */ cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, epc->function_num_map); + /* + * Next function field in ARI_CAP_AND_CTR register for last function + * should be 0. + * Clearing Next Function Number field for the last function used. + */ + last_fn = find_last_bit(&epc->function_num_map, BITS_PER_LONG); + reg = CDNS_PCIE_CORE_PF_I_ARI_CAP_AND_CTRL(last_fn); + value = cdns_pcie_readl(pcie, reg); + value &= ~CDNS_PCIE_ARI_CAP_NFN_MASK; + cdns_pcie_writel(pcie, reg, value); + if (ep->quirk_disable_flr) { for (epf = 0; epf < max_epfs; epf++) { if (!(epc->function_num_map & BIT(epf))) |