aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLey Foon Tan <lftan@altera.com>2016-06-21 04:53:13 -0400
committerBjorn Helgaas <bhelgaas@google.com>2016-07-22 17:02:57 -0400
commit3a928e98a833e1a470a60d2fedf3c55502185fb7 (patch)
tree43e091a7819c1c7fccdefdc9aed21787697a21b4
parentc622032ebc538cb3869c312ae3ad235a99da84b6 (diff)
PCI: altera: Poll for link up status after retraining the link
Some PCIe devices take a long time to reach link up state after retrain. Poll for link up status after retraining the link. This is to make sure the link is up before we access configuration space. [bhelgaas: changelog] Signed-off-by: Ley Foon Tan <lftan@altera.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/host/pcie-altera.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index b61025ee07de..e4154b2a23ce 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -61,6 +61,8 @@
61#define TLP_LOOP 500 61#define TLP_LOOP 500
62#define RP_DEVFN 0 62#define RP_DEVFN 0
63 63
64#define LINK_UP_TIMEOUT 5000
65
64#define INTX_NUM 4 66#define INTX_NUM 4
65 67
66#define DWORD_MASK 3 68#define DWORD_MASK 3
@@ -101,6 +103,7 @@ static void altera_pcie_retrain(struct pci_dev *dev)
101{ 103{
102 u16 linkcap, linkstat; 104 u16 linkcap, linkstat;
103 struct altera_pcie *pcie = dev->bus->sysdata; 105 struct altera_pcie *pcie = dev->bus->sysdata;
106 int timeout = 0;
104 107
105 if (!altera_pcie_link_is_up(pcie)) 108 if (!altera_pcie_link_is_up(pcie))
106 return; 109 return;
@@ -115,9 +118,16 @@ static void altera_pcie_retrain(struct pci_dev *dev)
115 return; 118 return;
116 119
117 pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat); 120 pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
118 if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) 121 if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
119 pcie_capability_set_word(dev, PCI_EXP_LNKCTL, 122 pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
120 PCI_EXP_LNKCTL_RL); 123 PCI_EXP_LNKCTL_RL);
124 while (!altera_pcie_link_is_up(pcie)) {
125 timeout++;
126 if (timeout > LINK_UP_TIMEOUT)
127 break;
128 udelay(5);
129 }
130 }
121} 131}
122DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain); 132DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain);
123 133