diff mbox series

[v2,2/4] PCI: qcom: Do not enumerate bus before endpoint devices are ready

Message ID 20250506073934.433176-8-cassel@kernel.org
State Superseded
Headers show
Series PCI: dwc: Link Up IRQ fixes | expand

Commit Message

Niklas Cassel May 6, 2025, 7:39 a.m. UTC
Commit 36971d6c5a9a ("PCI: qcom: Don't wait for link if we can detect Link
Up") changed so that we no longer call dw_pcie_wait_for_link(), and instead
enumerate the bus when receiving a Link Up IRQ.

Before 36971d6c5a9a, we called dw_pcie_wait_for_link(), and in the first
iteration of the loop, the link will never be up (because the link was just
started), dw_pcie_wait_for_link() will then sleep for LINK_WAIT_SLEEP_MS
(90 ms), before trying again.

This means that even if a driver was missing a msleep(PCIE_T_RRS_READY_MS)
(100 ms), because of the call to dw_pcie_wait_for_link(), enumerating the
bus would essentially be delayed by that time anyway (because of the sleep
LINK_WAIT_SLEEP_MS (90 ms)).

While we could add the msleep(PCIE_T_RRS_READY_MS) after deasserting PERST
(qcom already has an unconditional 1 ms sleep after deasserting PERST),
that would essentially bring back an unconditional delay during probe (the
whole reason to use a Link Up IRQ was to avoid an unconditional delay
during probe).

Thus, add the msleep(PCIE_T_RRS_READY_MS) before enumerating the bus in the
IRQ handler. This way, for qcom SoCs that has a link up IRQ, we will not
have a 100 ms unconditional delay during boot for unpopulated PCIe slots.

Fixes: 36971d6c5a9a ("PCI: qcom: Don't wait for link if we can detect Link Up")
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Laszlo Fiat May 6, 2025, 11:29 a.m. UTC | #1
On Tuesday, May 6th, 2025 at 9:39 AM, Niklas Cassel <cassel@kernel.org> wrote:

> Commit 36971d6c5a9a ("PCI: qcom: Don't wait for link if we can detect Link
> Up") changed so that we no longer call dw_pcie_wait_for_link(), and instead
> enumerate the bus when receiving a Link Up IRQ.
> 
> Before 36971d6c5a9a, we called dw_pcie_wait_for_link(), and in the first
> iteration of the loop, the link will never be up (because the link was just
> started), dw_pcie_wait_for_link() will then sleep for LINK_WAIT_SLEEP_MS
> (90 ms), before trying again.
> 
> This means that even if a driver was missing a msleep(PCIE_T_RRS_READY_MS)
> (100 ms), because of the call to dw_pcie_wait_for_link(), enumerating the
> bus would essentially be delayed by that time anyway (because of the sleep
> LINK_WAIT_SLEEP_MS (90 ms)).
> 
> While we could add the msleep(PCIE_T_RRS_READY_MS) after deasserting PERST
> (qcom already has an unconditional 1 ms sleep after deasserting PERST),
> that would essentially bring back an unconditional delay during probe (the
> whole reason to use a Link Up IRQ was to avoid an unconditional delay
> during probe).
> 
> Thus, add the msleep(PCIE_T_RRS_READY_MS) before enumerating the bus in the
> IRQ handler. This way, for qcom SoCs that has a link up IRQ, we will not
> have a 100 ms unconditional delay during boot for unpopulated PCIe slots.
> 
> Fixes: 36971d6c5a9a ("PCI: qcom: Don't wait for link if we can detect Link Up")
> Signed-off-by: Niklas Cassel cassel@kernel.org
> 
> ---
> drivers/pci/controller/dwc/pcie-qcom.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index dc98ae63362d..01a60d1f372a 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1565,6 +1565,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void data)
> 
> if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
> dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> + msleep(PCIE_T_RRS_READY_MS);
> / Rescan the bus to enumerate endpoint devices */
> pci_lock_rescan_remove();
> pci_rescan_bus(pp->bridge->bus);
> 
> --
> 2.49.0

Tested-by: Laszlo Fiat <laszlo.fiat@proton.me>
diff mbox series

Patch

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index dc98ae63362d..01a60d1f372a 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1565,6 +1565,7 @@  static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
 
 	if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
 		dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
+		msleep(PCIE_T_RRS_READY_MS);
 		/* Rescan the bus to enumerate endpoint devices */
 		pci_lock_rescan_remove();
 		pci_rescan_bus(pp->bridge->bus);