]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: qcom: Advertise Hotplug Slot Capability with no Command Completion support
authorKrishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Sat, 14 Mar 2026 01:56:34 +0000 (07:26 +0530)
committerManivannan Sadhasivam <mani@kernel.org>
Thu, 26 Mar 2026 18:02:23 +0000 (23:32 +0530)
Qcom PCIe Root Ports advertise hotplug capability in hardware, but do not
support hotplug command completion. As a result, the hotplug commands
issued by the pciehp driver never gets completion notification, leading to
repeated timeout warnings and multi-second delays during boot and
suspend/resume.

Commit a54db86ddc153 ("PCI: qcom: Do not advertise hotplug capability for
IPs v2.7.0 and v1.9.0") mistakenly assumed that the Root Ports doesn't
support Hotplug due to timeouts and disabled the Hotplug functionality
altogether. But the Root Ports does support reporting Hotplug events like
DL_Up/Down events.

So to fix the command completion timeout issues, just set the No Command
Completed Support (NCCS) bit and enable Hotplug in Slot Capability field
back.

Fixes: a54db86ddc153 ("PCI: qcom: Do not advertise hotplug capability for IPs v2.7.0 and v1.9.0")
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
[mani: renamed function, commit log and added comment]
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Tested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> # Hamoa CRD, tunneled link
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://patch.msgid.link/20260314-hotplug-v1-1-96ac87d93867@oss.qualcomm.com
drivers/pci/controller/dwc/pcie-qcom.c

index 67a16af69ddc75fca1b123e70715e692a91a9135..9fdfc88ac15120b2b01cad746772ae612a2c9690 100644 (file)
@@ -350,15 +350,20 @@ static void qcom_pcie_clear_aspm_l0s(struct dw_pcie *pci)
        dw_pcie_dbi_ro_wr_dis(pci);
 }
 
-static void qcom_pcie_clear_hpc(struct dw_pcie *pci)
+static void qcom_pcie_set_slot_nccs(struct dw_pcie *pci)
 {
        u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
        u32 val;
 
        dw_pcie_dbi_ro_wr_en(pci);
 
+       /*
+        * Qcom PCIe Root Ports do not support generating command completion
+        * notifications for the Hot-Plug commands. So set the NCCS field to
+        * avoid waiting for the completions.
+        */
        val = readl(pci->dbi_base + offset + PCI_EXP_SLTCAP);
-       val &= ~PCI_EXP_SLTCAP_HPC;
+       val |= PCI_EXP_SLTCAP_NCCS;
        writel(val, pci->dbi_base + offset + PCI_EXP_SLTCAP);
 
        dw_pcie_dbi_ro_wr_dis(pci);
@@ -558,7 +563,7 @@ static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
        writel(CFG_BRIDGE_SB_INIT,
               pci->dbi_base + AXI_MSTR_RESP_COMP_CTRL1);
 
-       qcom_pcie_clear_hpc(pcie->pci);
+       qcom_pcie_set_slot_nccs(pcie->pci);
 
        return 0;
 }
@@ -638,7 +643,7 @@ static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
                writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT);
        }
 
-       qcom_pcie_clear_hpc(pcie->pci);
+       qcom_pcie_set_slot_nccs(pcie->pci);
 
        return 0;
 }
@@ -731,7 +736,7 @@ static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie)
        val |= EN;
        writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
 
-       qcom_pcie_clear_hpc(pcie->pci);
+       qcom_pcie_set_slot_nccs(pcie->pci);
 
        return 0;
 }
@@ -1037,7 +1042,7 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)
                writel(WR_NO_SNOOP_OVERRIDE_EN | RD_NO_SNOOP_OVERRIDE_EN,
                                pcie->parf + PARF_NO_SNOOP_OVERRIDE);
 
-       qcom_pcie_clear_hpc(pcie->pci);
+       qcom_pcie_set_slot_nccs(pcie->pci);
 
        return 0;
 }