On Mon, Aug 15, 2016 at 02:06:02PM +0800, Ley Foon Tan wrote: > Poll for link training status is cleared before poll for link up status. > This can help to get the reliable link up status, especially when PCIe > is in Gen 3 speed. > > Signed-off-by: Ley Foon Tan <lftan@xxxxxxxxxx> Applied to pci/host-altera for v4.9, thanks! > --- > drivers/pci/host/pcie-altera.c | 45 ++++++++++++++++++++++++++++++++++-------- > 1 file changed, 37 insertions(+), 8 deletions(-) > > diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c > index 2b78376..58eef99 100644 > --- a/drivers/pci/host/pcie-altera.c > +++ b/drivers/pci/host/pcie-altera.c > @@ -61,7 +61,8 @@ > #define TLP_LOOP 500 > #define RP_DEVFN 0 > > -#define LINK_UP_TIMEOUT 5000 > +#define LINK_UP_TIMEOUT HZ > +#define LINK_RETRAIN_TIMEOUT HZ > > #define INTX_NUM 4 > > @@ -99,11 +100,44 @@ static bool altera_pcie_link_is_up(struct altera_pcie *pcie) > return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); > } > > +static void altera_wait_link_retrain(struct pci_dev *dev) > +{ > + u16 reg16; > + unsigned long start_jiffies; > + struct altera_pcie *pcie = dev->bus->sysdata; > + > + /* Wait for link training end. */ > + start_jiffies = jiffies; > + for (;;) { > + pcie_capability_read_word(dev, PCI_EXP_LNKSTA, ®16); > + if (!(reg16 & PCI_EXP_LNKSTA_LT)) > + break; > + > + if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) { > + dev_err(&pcie->pdev->dev, "link retrain timeout\n"); > + break; > + } > + udelay(100); > + } > + > + /* Wait for link is up */ > + start_jiffies = jiffies; > + for (;;) { > + if (altera_pcie_link_is_up(pcie)) > + break; > + > + if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) { > + dev_err(&pcie->pdev->dev, "link up timeout\n"); > + break; > + } > + udelay(100); > + } > +} > + > static void altera_pcie_retrain(struct pci_dev *dev) > { > u16 linkcap, linkstat; > struct altera_pcie *pcie = dev->bus->sysdata; > - int timeout = 0; > > if (!altera_pcie_link_is_up(pcie)) > return; > @@ -121,12 +155,7 @@ static void altera_pcie_retrain(struct pci_dev *dev) > if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) { > pcie_capability_set_word(dev, PCI_EXP_LNKCTL, > PCI_EXP_LNKCTL_RL); > - while (!altera_pcie_link_is_up(pcie)) { > - timeout++; > - if (timeout > LINK_UP_TIMEOUT) > - break; > - udelay(5); > - } > + altera_wait_link_retrain(dev); > } > } > DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain); > -- > 1.8.2.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html