PCI: designware: Add generic dw_pcie_wait_for_link()
Several DesignWare-based drivers (dra7xx, exynos, imx6, keystone, qcom, and
spear13xx) had similar loops waiting for the link to come up.
Add a generic dw_pcie_wait_for_link() for use by all these drivers so the
waiting is done consistently, e.g., always using usleep_range() rather than
mdelay() and using similar timeouts and retry counts.
Note that this changes the Keystone link training/wait for link strategy,
so we initiate link training, then wait longer for the link to come up
before re-initiating link training.
[bhelgaas: changelog, split into its own patch, update pci-keystone.c, pcie-qcom.c]
Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index d997d22..2199761 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -318,7 +318,6 @@
{
struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
u32 val;
- unsigned int retries;
if (dw_pcie_link_up(pp)) {
dev_err(pp->dev, "Link already up\n");
@@ -357,13 +356,8 @@
PCIE_APP_LTSSM_ENABLE);
/* check if the link is up or not */
- for (retries = 0; retries < 10; retries++) {
- if (dw_pcie_link_up(pp)) {
- dev_info(pp->dev, "Link up\n");
- return 0;
- }
- mdelay(100);
- }
+ if (!dw_pcie_wait_for_link(pp))
+ return 0;
while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) {
val = exynos_blk_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED);
@@ -372,8 +366,7 @@
/* power off phy */
exynos_pcie_power_off_phy(pp);
- dev_err(pp->dev, "PCIe Link Fail\n");
- return -EINVAL;
+ return -ETIMEDOUT;
}
static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp)