dw_pcie_setup_rc(pp);
 
-       dra7xx_pcie_establish_link(pci);
-       dw_pcie_wait_for_link(pci);
        dw_pcie_msi_init(pp);
        dra7xx_pcie_enable_interrupts(dra7xx);
 
 
                                GPIOF_OUT_INIT_HIGH, "RESET");
 }
 
-static int exynos_pcie_establish_link(struct exynos_pcie *ep)
+static int exynos_pcie_start_link(struct dw_pcie *pci)
 {
-       struct dw_pcie *pci = ep->pci;
-       struct pcie_port *pp = &pci->pp;
-       struct device *dev = pci->dev;
-
-       if (dw_pcie_link_up(pci)) {
-               dev_err(dev, "Link already up\n");
-               return 0;
-       }
-
-       exynos_pcie_assert_core_reset(ep);
-
-       phy_reset(ep->phy);
-
-       exynos_pcie_writel(ep->mem_res->elbi_base, 1,
-                       PCIE_PWR_RESET);
-
-       phy_power_on(ep->phy);
-       phy_init(ep->phy);
-
-       exynos_pcie_deassert_core_reset(ep);
-       dw_pcie_setup_rc(pp);
-       exynos_pcie_assert_reset(ep);
+       struct exynos_pcie *ep = to_exynos_pcie(pci);
 
        /* assert LTSSM enable */
        exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
 
        pp->bridge->ops = &exynos_pci_ops;
 
-       exynos_pcie_establish_link(ep);
+       exynos_pcie_assert_core_reset(ep);
+
+       phy_reset(ep->phy);
+
+       exynos_pcie_writel(ep->mem_res->elbi_base, 1,
+                       PCIE_PWR_RESET);
+
+       phy_power_on(ep->phy);
+       phy_init(ep->phy);
+
+       exynos_pcie_deassert_core_reset(ep);
+       dw_pcie_setup_rc(pp);
+       exynos_pcie_assert_reset(ep);
+
        exynos_pcie_enable_interrupts(ep);
 
        return 0;
        .read_dbi = exynos_pcie_read_dbi,
        .write_dbi = exynos_pcie_write_dbi,
        .link_up = exynos_pcie_link_up,
+       .start_link = exynos_pcie_start_link,
 };
 
 static int __init exynos_pcie_probe(struct platform_device *pdev)
 
        }
 }
 
-static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
+static int imx6_pcie_start_link(struct dw_pcie *pci)
 {
-       struct dw_pcie *pci = imx6_pcie->pci;
+       struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
        struct device *dev = pci->dev;
        u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
        u32 tmp;
        imx6_pcie_deassert_core_reset(imx6_pcie);
        imx6_setup_phy_mpll(imx6_pcie);
        dw_pcie_setup_rc(pp);
-       imx6_pcie_establish_link(imx6_pcie);
        dw_pcie_msi_init(pp);
 
        return 0;
 }
 
 static const struct dw_pcie_ops dw_pcie_ops = {
-       /* No special ops needed, but pcie-designware still expects this struct */
+       .start_link = imx6_pcie_start_link,
 };
 
 #ifdef CONFIG_PM_SLEEP
        imx6_pcie_deassert_core_reset(imx6_pcie);
        dw_pcie_setup_rc(pp);
 
-       ret = imx6_pcie_establish_link(imx6_pcie);
+       ret = imx6_pcie_start_link(imx6_pcie->pci);
        if (ret < 0)
                dev_info(dev, "pcie link is down after resume.\n");
 
 
 static int ks_pcie_start_link(struct dw_pcie *pci)
 {
        struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
-       struct device *dev = pci->dev;
        u32 val;
 
-       if (dw_pcie_link_up(pci)) {
-               dev_dbg(dev, "link is already up\n");
-               return 0;
-       }
-
        /* Initiate Link Training */
        val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);
        ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val);
                        "Asynchronous external abort");
 #endif
 
-       ks_pcie_start_link(pci);
-       dw_pcie_wait_for_link(pci);
-
        return 0;
 }
 
 
        gpiod_set_value_cansleep(mp->reset_gpio, 0);
 }
 
-static void meson_pcie_init_dw(struct meson_pcie *mp)
+static void meson_pcie_ltssm_enable(struct meson_pcie *mp)
 {
        u32 val;
 
        dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);
 }
 
-static int meson_pcie_establish_link(struct meson_pcie *mp)
+static int meson_pcie_start_link(struct dw_pcie *pci)
 {
-       struct dw_pcie *pci = &mp->pci;
-       struct pcie_port *pp = &pci->pp;
-
-       meson_pcie_init_dw(mp);
-       meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
-       meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
-
-       dw_pcie_setup_rc(pp);
+       struct meson_pcie *mp = to_meson_pcie(pci);
 
+       meson_pcie_ltssm_enable(mp);
        meson_pcie_assert_reset(mp);
 
-       return dw_pcie_wait_for_link(pci);
+       return 0;
 }
 
 static int meson_pcie_rd_own_conf(struct pci_bus *bus, u32 devfn,
 {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
        struct meson_pcie *mp = to_meson_pcie(pci);
-       int ret;
 
        pp->bridge->ops = &meson_pci_ops;
 
-       ret = meson_pcie_establish_link(mp);
-       if (ret)
-               return ret;
+       meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
+       meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
 
+       dw_pcie_setup_rc(pp);
        dw_pcie_msi_init(pp);
 
        return 0;
 
 static const struct dw_pcie_ops dw_pcie_ops = {
        .link_up = meson_pcie_link_up,
+       .start_link = meson_pcie_start_link,
 };
 
 static int meson_pcie_probe(struct platform_device *pdev)
 
        return 0;
 }
 
-static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)
+static int armada8k_pcie_start_link(struct dw_pcie *pci)
+{
+       u32 reg;
+
+       /* Start LTSSM */
+       reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
+       reg |= PCIE_APP_LTSSM_EN;
+       dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg);
+
+       return 0;
+}
+
+static int armada8k_pcie_host_init(struct pcie_port *pp)
 {
-       struct dw_pcie *pci = pcie->pci;
        u32 reg;
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+       dw_pcie_setup_rc(pp);
 
        if (!dw_pcie_link_up(pci)) {
                /* Disable LTSSM state machine to enable configuration */
               PCIE_INT_C_ASSERT_MASK | PCIE_INT_D_ASSERT_MASK;
        dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK1_REG, reg);
 
-       if (!dw_pcie_link_up(pci)) {
-               /* Configuration done. Start LTSSM */
-               reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
-               reg |= PCIE_APP_LTSSM_EN;
-               dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg);
-       }
-
-       /* Wait until the link becomes active again */
-       if (dw_pcie_wait_for_link(pci))
-               dev_err(pci->dev, "Link not up after reconfiguration\n");
-}
-
-static int armada8k_pcie_host_init(struct pcie_port *pp)
-{
-       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-       struct armada8k_pcie *pcie = to_armada8k_pcie(pci);
-
-       dw_pcie_setup_rc(pp);
-       armada8k_pcie_establish_link(pcie);
-
        return 0;
 }
 
 
 static const struct dw_pcie_ops dw_pcie_ops = {
        .link_up = armada8k_pcie_link_up,
+       .start_link = armada8k_pcie_start_link,
 };
 
 static int armada8k_pcie_probe(struct platform_device *pdev)
 
        artpec6_pcie_deassert_core_reset(artpec6_pcie);
        artpec6_pcie_wait_for_phy(artpec6_pcie);
        dw_pcie_setup_rc(pp);
-       artpec6_pcie_establish_link(pci);
-       dw_pcie_wait_for_link(pci);
        dw_pcie_msi_init(pp);
 
        return 0;
 
                        goto err_free_msi;
        }
 
+       if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
+               ret = pci->ops->start_link(pci);
+               if (ret)
+                       goto err_free_msi;
+       }
+
+       /* Ignore errors, the link may come up later */
+       dw_pcie_wait_for_link(pci);
+
        bridge->sysdata = pp;
 
        ret = pci_host_probe(bridge);
 
 
 static int dw_plat_pcie_host_init(struct pcie_port *pp)
 {
-       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-
        dw_pcie_setup_rc(pp);
-       dw_pcie_wait_for_link(pci);
        dw_pcie_msi_init(pp);
 
        return 0;
 
        return 0;
 }
 
-static int histb_pcie_establish_link(struct pcie_port *pp)
+static int histb_pcie_start_link(struct dw_pcie *pci)
 {
-       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
        struct histb_pcie *hipcie = to_histb_pcie(pci);
        u32 regval;
 
-       if (dw_pcie_link_up(pci)) {
-               dev_info(pci->dev, "Link already up\n");
-               return 0;
-       }
-
-       /* PCIe RC work mode */
-       regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
-       regval &= ~PCIE_DEVICE_TYPE_MASK;
-       regval |= PCIE_WM_RC;
-       histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
-
-       /* setup root complex */
-       dw_pcie_setup_rc(pp);
-
        /* assert LTSSM enable */
        regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7);
        regval |= PCIE_APP_LTSSM_ENABLE;
        histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval);
 
-       return dw_pcie_wait_for_link(pci);
+       return 0;
 }
 
 static int histb_pcie_host_init(struct pcie_port *pp)
 {
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct histb_pcie *hipcie = to_histb_pcie(pci);
+       u32 regval;
+
        pp->bridge->ops = &histb_pci_ops;
 
-       histb_pcie_establish_link(pp);
+       /* PCIe RC work mode */
+       regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
+       regval &= ~PCIE_DEVICE_TYPE_MASK;
+       regval |= PCIE_WM_RC;
+       histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
+
+       /* setup root complex */
+       dw_pcie_setup_rc(pp);
+
        dw_pcie_msi_init(pp);
 
        return 0;
        .read_dbi = histb_pcie_read_dbi,
        .write_dbi = histb_pcie_write_dbi,
        .link_up = histb_pcie_link_up,
+       .start_link = histb_pcie_start_link,
 };
 
 static int histb_pcie_probe(struct platform_device *pdev)
 
        return 0;
 }
 
-static int kirin_pcie_establish_link(struct pcie_port *pp)
+static int kirin_pcie_start_link(struct dw_pcie *pci)
 {
-       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
        struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);
-       struct device *dev = kirin_pcie->pci->dev;
-       int count = 0;
-
-       if (kirin_pcie_link_up(pci))
-               return 0;
-
-       dw_pcie_setup_rc(pp);
 
        /* assert LTSSM enable */
        kirin_apb_ctrl_writel(kirin_pcie, PCIE_LTSSM_ENABLE_BIT,
                              PCIE_APP_LTSSM_ENABLE);
 
-       /* check if the link is up or not */
-       while (!kirin_pcie_link_up(pci)) {
-               usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
-               count++;
-               if (count == 1000) {
-                       dev_err(dev, "Link Fail\n");
-                       return -EINVAL;
-               }
-       }
-
        return 0;
 }
 
 {
        pp->bridge->ops = &kirin_pci_ops;
 
-       kirin_pcie_establish_link(pp);
+       dw_pcie_setup_rc(pp);
        dw_pcie_msi_init(pp);
 
        return 0;
        .read_dbi = kirin_pcie_read_dbi,
        .write_dbi = kirin_pcie_write_dbi,
        .link_up = kirin_pcie_link_up,
+       .start_link = kirin_pcie_start_link,
 };
 
 static const struct dw_pcie_host_ops kirin_pcie_host_ops = {
 
        usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
 }
 
-static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
+static int qcom_pcie_start_link(struct dw_pcie *pci)
 {
-       struct dw_pcie *pci = pcie->pci;
-
-       if (dw_pcie_link_up(pci))
-               return 0;
+       struct qcom_pcie *pcie = to_qcom_pcie(pci);
 
        /* Enable Link Training state machine */
        if (pcie->ops->ltssm_enable)
                pcie->ops->ltssm_enable(pcie);
 
-       return dw_pcie_wait_for_link(pci);
+       return 0;
 }
 
 static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie)
 
        qcom_ep_reset_deassert(pcie);
 
-       ret = qcom_pcie_establish_link(pcie);
-       if (ret)
-               goto err;
-
        return 0;
-err:
-       qcom_ep_reset_assert(pcie);
-       if (pcie->ops->post_deinit)
-               pcie->ops->post_deinit(pcie);
+
 err_disable_phy:
        phy_power_off(pcie->phy);
 err_deinit:
 
 static const struct dw_pcie_ops dw_pcie_ops = {
        .link_up = qcom_pcie_link_up,
+       .start_link = qcom_pcie_start_link,
 };
 
 static int qcom_pcie_probe(struct platform_device *pdev)
 
 
 #define to_spear13xx_pcie(x)   dev_get_drvdata((x)->dev)
 
-static int spear13xx_pcie_establish_link(struct spear13xx_pcie *spear13xx_pcie)
+static int spear13xx_pcie_start_link(struct dw_pcie *pci)
 {
-       struct dw_pcie *pci = spear13xx_pcie->pci;
-       struct pcie_port *pp = &pci->pp;
+       struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);
        struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
-       u32 val;
-       u32 exp_cap_off = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
-
-       if (dw_pcie_link_up(pci)) {
-               dev_err(pci->dev, "link already up\n");
-               return 0;
-       }
-
-       dw_pcie_setup_rc(pp);
-
-       /*
-        * this controller support only 128 bytes read size, however its
-        * default value in capability register is 512 bytes. So force
-        * it to 128 here.
-        */
-       val = dw_pcie_readw_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL);
-       val &= ~PCI_EXP_DEVCTL_READRQ;
-       dw_pcie_writew_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL, val);
-
-       dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, 0x104A);
-       dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, 0xCD80);
 
        /* enable ltssm */
        writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID)
                        | ((u32)1 << REG_TRANSLATION_ENABLE),
                        &app_reg->app_ctrl_0);
 
-       return dw_pcie_wait_for_link(pci);
+       return 0;
 }
 
 static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)
 {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
        struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);
+       u32 exp_cap_off = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+       u32 val;
 
        spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
 
-       spear13xx_pcie_establish_link(spear13xx_pcie);
+       dw_pcie_setup_rc(pp);
+
+       /*
+        * this controller support only 128 bytes read size, however its
+        * default value in capability register is 512 bytes. So force
+        * it to 128 here.
+        */
+       val = dw_pcie_readw_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL);
+       val &= ~PCI_EXP_DEVCTL_READRQ;
+       dw_pcie_writew_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL, val);
+
+       dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, 0x104A);
+       dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, 0xCD80);
+
        spear13xx_pcie_enable_interrupts(spear13xx_pcie);
 
        return 0;
 
 static const struct dw_pcie_ops dw_pcie_ops = {
        .link_up = spear13xx_pcie_link_up,
+       .start_link = spear13xx_pcie_start_link,
 };
 
 static int spear13xx_pcie_probe(struct platform_device *pdev)
 
 
 static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
 {
-       struct pcie_port *pp = &pcie->pci.pp;
        struct device *dev = pcie->dev;
        char *name;
        int ret;
 
        return (val & mask) == mask;
 }
 
-static int uniphier_pcie_establish_link(struct dw_pcie *pci)
+static int uniphier_pcie_start_link(struct dw_pcie *pci)
 {
        struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
 
-       if (dw_pcie_link_up(pci))
-               return 0;
-
        uniphier_pcie_ltssm_enable(priv, true);
 
-       return dw_pcie_wait_for_link(pci);
+       return 0;
 }
 
 static void uniphier_pcie_stop_link(struct dw_pcie *pci)
        uniphier_pcie_irq_enable(priv);
 
        dw_pcie_setup_rc(pp);
-       ret = uniphier_pcie_establish_link(pci);
-       if (ret)
-               return ret;
-
        dw_pcie_msi_init(pp);
 
        return 0;
 }
 
 static const struct dw_pcie_ops dw_pcie_ops = {
-       .start_link = uniphier_pcie_establish_link,
+       .start_link = uniphier_pcie_start_link,
        .stop_link = uniphier_pcie_stop_link,
        .link_up = uniphier_pcie_link_up,
 };