[PATCH v3 10/16] PCI: dwc: qcom-ep: Use cached PCIe capability offset
Hans Zhang <[email protected]> Mon, 20 Jul 2026 23:06:13 +0800
| Newsgroups | dev.linux.lists.sophgo,dev.linux.lists.imx,dev.linux.lists.spacemit,org.infradead.lists.linux-amlogic,org.infradead.lists.linux-riscv,org.infradead.lists.linux-rockchip,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci,org.kernel.vger.linux-tegra,org.ozlabs.lists.linuxppc-dev |
|---|---|
| Message-ID | <[email protected]> |
dw_pcie_ep_init() no longer caches the offset automatically. For qcom-ep, hardware (clocks, PHY) is enabled only after PERST# deassert. Therefore, we must call dw_pcie_get_pcie_cap() in qcom_pcie_perst_deassert() after the resources are enabled, before any DBI access. This ensures the cached offset is valid for subsequent uses in interrupt handlers and ICC updates. Signed-off-by: Hans Zhang <[email protected]> --- In pcie-qcom-ep, dw_pcie_find_capability() appears in: qcom_pcie_ep_probe() -> dw_pcie_ep_init() -> qcom_pcie_ep_enable_irq_resources() -> qcom_pcie_ep_global_irq_thread() -> qcom_pcie_ep_icc_update() -> dw_pcie_find_capability() -> qcom_pcie_ep_perst_irq_thread() -> qcom_pcie_perst_deassert() -> offset = dw_pcie_find_capability() (called twice) --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 56184e6ca6e6..16b0891f9571 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -307,15 +307,13 @@ 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; - int speed, width; - int ret; + int speed, width, ret; + u32 status; if (!pcie_ep->icc_mem) return; - offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); - status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA); + status = readw(pci->dbi_base + pci->pcie_cap + PCI_EXP_LNKSTA); speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status); width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status); @@ -491,14 +489,15 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) dw_pcie_dbi_ro_wr_en(pci); + dw_pcie_get_pcie_cap(pci); + /* Set the L0s Exit Latency to 2us-4us = 0x6 */ - offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + offset = pci->pcie_cap; 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.34.1