PCI: dwc: Wait for link up only if link is started
authorAjay Agarwal <ajayagarwal@google.com>
Wed, 12 Apr 2023 09:34:25 +0000 (15:04 +0530)
committerLorenzo Pieralisi <lpieralisi@kernel.org>
Fri, 26 May 2023 08:45:12 +0000 (10:45 +0200)
In dw_pcie_host_init() regardless of whether the link has been
started or not, the code waits for the link to come up. Even in
cases where start_link() is not defined the code ends up spinning
in a loop for 1 second. Since in some systems dw_pcie_host_init()
gets called during probe, this one second loop for each pcie
interface instance ends up extending the boot time.

Wait for the link up in only if the start_link() is defined.

Link: https://lore.kernel.org/r/20230412093425.3659088-1-ajayagarwal@google.com
Tested-by: Will McVicker <willmcvicker@google.com>
Signed-off-by: Sajid Dalvi <sdalvi@google.com>
Signed-off-by: Ajay Agarwal <ajayagarwal@google.com>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
drivers/pci/controller/dwc/pcie-designware-host.c
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/controller/dwc/pcie-designware.h

index 9952057..cf61733 100644 (file)
@@ -485,14 +485,19 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
        if (ret)
                goto err_remove_edma;
 
-       if (!dw_pcie_link_up(pci)) {
+       if (dw_pcie_link_up(pci)) {
+               dw_pcie_print_link_status(pci);
+       } else {
                ret = dw_pcie_start_link(pci);
                if (ret)
                        goto err_remove_edma;
-       }
 
-       /* Ignore errors, the link may come up later */
-       dw_pcie_wait_for_link(pci);
+               if (pci->ops && pci->ops->start_link) {
+                       ret = dw_pcie_wait_for_link(pci);
+                       if (ret)
+                               goto err_stop_link;
+               }
+       }
 
        bridge->sysdata = pp;
 
index 8e33e6e..df09222 100644 (file)
@@ -644,9 +644,20 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index)
        dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0);
 }
 
-int dw_pcie_wait_for_link(struct dw_pcie *pci)
+void dw_pcie_print_link_status(struct dw_pcie *pci)
 {
        u32 offset, val;
+
+       offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+       val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
+
+       dev_info(pci->dev, "PCIe Gen.%u x%u link up\n",
+                FIELD_GET(PCI_EXP_LNKSTA_CLS, val),
+                FIELD_GET(PCI_EXP_LNKSTA_NLW, val));
+}
+
+int dw_pcie_wait_for_link(struct dw_pcie *pci)
+{
        int retries;
 
        /* Check if the link is up or not */
@@ -662,12 +673,7 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
                return -ETIMEDOUT;
        }
 
-       offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
-       val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
-
-       dev_info(pci->dev, "PCIe Gen.%u x%u link up\n",
-                FIELD_GET(PCI_EXP_LNKSTA_CLS, val),
-                FIELD_GET(PCI_EXP_LNKSTA_NLW, val));
+       dw_pcie_print_link_status(pci);
 
        return 0;
 }
index 79713ce..6156606 100644 (file)
@@ -429,6 +429,7 @@ void dw_pcie_setup(struct dw_pcie *pci);
 void dw_pcie_iatu_detect(struct dw_pcie *pci);
 int dw_pcie_edma_detect(struct dw_pcie *pci);
 void dw_pcie_edma_remove(struct dw_pcie *pci);
+void dw_pcie_print_link_status(struct dw_pcie *pci);
 
 static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
 {