[PATCH v3 11/16] PCI: dwc: qcom: Use cached PCIe capability offset
From: Hans Zhang <18255117159@163.com>
Date: 2026-07-20 15:08:31
Also in:
imx, linux-amlogic, linux-arm-msm, linux-pci, linux-riscv, linux-rockchip, linux-tegra, lkml, spacemit
Subsystem:
arm/qualcomm mailing list, pci native host bridge and endpoint drivers, pci subsystem, pcie driver for qualcomm msm, the rest · Maintainers:
Lorenzo Pieralisi, Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas, Linus Torvalds
dw_pcie_host_init() caches the offset after .init, so .post_init callbacks
and later functions (.link_up, icc_opp_update) can use pci->pcie_cap
directly. For .init itself, we must call dw_pcie_get_pcie_cap() inside
qcom_pcie_host_init() to obtain the offset (hardware is already enabled).
Signed-off-by: Hans Zhang <18255117159@163.com>
---
In pcie-qcom, dw_pcie_find_capability() appears in multiple call chains:
static const struct dw_pcie_host_ops qcom_pcie_dw_ops = {
.init = qcom_pcie_host_init,
};
qcom_pcie_host_init()
-> qcom_pcie_clear_aspm_l0s()
-> dw_pcie_find_capability()
static const struct qcom_pcie_ops ops_* = {
.post_init = qcom_pcie_post_init_*,
};
qcom_pcie_post_init_*()
-> qcom_pcie_set_slot_nccs() (for many versions)
-> dw_pcie_find_capability()
-> For 2_3_3 and 2_9_0: also calls dw_pcie_find_capability() directly
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = qcom_pcie_link_up,
};
qcom_pcie_link_up()
-> dw_pcie_find_capability()
qcom_pcie_probe()
-> dw_pcie_host_init()
-> qcom_pcie_icc_opp_update()
-> dw_pcie_find_capability()
---
drivers/pci/controller/dwc/pcie-qcom.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index d8eb52857f69..bd383d7cb02b 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c@@ -341,13 +341,13 @@ static int qcom_pcie_start_link(struct dw_pcie *pci) static void qcom_pcie_clear_aspm_l0s(struct dw_pcie *pci) { struct qcom_pcie *pcie = to_qcom_pcie(pci); - u16 offset; + u8 offset; u32 val; if (!pcie->cfg->no_l0s) return; - offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + offset = dw_pcie_get_pcie_cap(pci); dw_pcie_dbi_ro_wr_en(pci);
@@ -360,7 +360,6 @@ static void qcom_pcie_clear_aspm_l0s(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);
@@ -370,9 +369,9 @@ static void qcom_pcie_set_slot_nccs(struct dw_pcie *pci) * 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 = readl(pci->dbi_base + pci->pcie_cap + PCI_EXP_SLTCAP); val |= PCI_EXP_SLTCAP_NCCS; - writel(val, pci->dbi_base + offset + PCI_EXP_SLTCAP); + writel(val, pci->dbi_base + pci->pcie_cap + PCI_EXP_SLTCAP); dw_pcie_dbi_ro_wr_dis(pci); }
@@ -935,7 +934,7 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) static int qcom_pcie_post_init_2_3_3(struct qcom_pcie *pcie) { struct dw_pcie *pci = pcie->pci; - u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + u8 offset = pci->pcie_cap; u32 val; /* Force PHY out of lowest power state */
@@ -1257,7 +1256,7 @@ static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie) static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie) { struct dw_pcie *pci = pcie->pci; - u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + u8 offset = pci->pcie_cap; u32 val; int i;
@@ -1303,8 +1302,7 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie) static bool qcom_pcie_link_up(struct dw_pcie *pci) { - u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); - u16 val = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA); + u16 val = readw(pci->dbi_base + pci->pcie_cap + PCI_EXP_LNKSTA); return val & PCI_EXP_LNKSTA_DLLLA; }
@@ -1664,15 +1662,14 @@ static int qcom_pcie_icc_init(struct qcom_pcie *pcie) static void qcom_pcie_icc_opp_update(struct qcom_pcie *pcie) { - u32 offset, status, width, speed; + u32 status, width, speed; struct dw_pcie *pci = pcie->pci; struct dev_pm_opp_key key = {}; unsigned long freq_kbps; struct dev_pm_opp *opp; int ret, freq_mbps; - 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); /* Only update constraints if link is up. */ if (!(status & PCI_EXP_LNKSTA_DLLLA))
--
2.34.1