[PATCH v5 10/16] PCI: dwc: qcom-ep: Use cached PCIe capability offset

From: Hans Zhang

Date: Tue Oct 27 2026 - 23:10:42 EST


Replace the three dw_pcie_find_capability(pci, PCI_CAP_ID_EXP) calls in
the qcom-ep driver with dw_pcie_get_pcie_cap().

qcom_pcie_perst_deassert() is the point where the controller resources
have just been enabled and DBI becomes accessible, so the offset is
looked up and cached there. Both the L0s and the L1 exit latency are
then programmed using that same cached offset instead of walking the
capability list again.

qcom_pcie_ep_icc_update() may run from the global IRQ handler, which is
requested before the PERST# IRQ. The helper performs its lookup at that
point of use, i.e. exactly where the open coded search happened before,
so this change neither adds nor moves a DBI access and does not
introduce a new race with the PERST# handler.

Signed-off-by: Hans Zhang <18255117159@xxxxxxx>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index e6afdc6198acc..3e2068f3fa117 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -308,14 +308,15 @@ static void qcom_pcie_dw_write_dbi2(struct dw_pcie *pci, void __iomem *base,
static void qcom_pcie_ep_icc_update(struct qcom_pcie_ep *pcie_ep)
{
struct dw_pcie *pci = &pcie_ep->pci;
- u32 offset, status;
+ u8 offset;
+ u32 status;
int speed, width;
int ret;

if (!pcie_ep->icc_mem)
return;

- offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+ offset = dw_pcie_get_pcie_cap(pci);
status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);

speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status);
@@ -398,7 +399,8 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
{
struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci);
struct device *dev = pci->dev;
- u32 val, offset;
+ u32 val;
+ u8 offset;
int ret;

ret = pm_runtime_resume_and_get(dev);
@@ -493,13 +495,12 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
dw_pcie_dbi_ro_wr_en(pci);

/* Set the L0s Exit Latency to 2us-4us = 0x6 */
- offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+ offset = dw_pcie_get_pcie_cap(pci);
val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
FIELD_MODIFY(PCI_EXP_LNKCAP_L0SEL, &val, 0x6);
dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, val);

/* Set the L1 Exit Latency to be 32us-64 us = 0x6 */
- offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
FIELD_MODIFY(PCI_EXP_LNKCAP_L1EL, &val, 0x6);
dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, val);
--
2.43.0