This is a note to let you know that I've just added the patch titled PCI: qcom: Power on PHY before IPQ8074 DBI register accesses to the 5.19-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: pci-qcom-power-on-phy-before-ipq8074-dbi-register-ac.patch and it can be found in the queue-5.19 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 6b7e8c26356c83671bddb493326d7b6ba6b45b6f Author: Robert Marko <robimarko@xxxxxxxxx> Date: Thu Jun 23 17:50:03 2022 +0200 PCI: qcom: Power on PHY before IPQ8074 DBI register accesses [ Upstream commit a0e43bb9973b06ce5c666f0901e104e2037c1b34 ] Currently the Gen2 port in IPQ8074 will cause the system to hang as it accesses DBI registers in qcom_pcie_init_2_3_3(), and those are only accesible after phy_power_on(). Move the DBI read/writes to a new qcom_pcie_post_init_2_3_3(), which is executed after phy_power_on(). Link: https://lore.kernel.org/r/20220623155004.688090-1-robimarko@xxxxxxxxx Fixes: a0fd361db8e5 ("PCI: dwc: Move "dbi", "dbi2", and "addr_space" resource setup into common code") Signed-off-by: Robert Marko <robimarko@xxxxxxxxx> Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx # v5.11+ Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 2ea13750b492..3bbe1612a930 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1038,9 +1038,7 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3; struct dw_pcie *pci = pcie->pci; struct device *dev = pci->dev; - u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); int i, ret; - u32 val; for (i = 0; i < ARRAY_SIZE(res->rst); i++) { ret = reset_control_assert(res->rst[i]); @@ -1097,6 +1095,33 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) goto err_clk_aux; } + return 0; + +err_clk_aux: + clk_disable_unprepare(res->ahb_clk); +err_clk_ahb: + clk_disable_unprepare(res->axi_s_clk); +err_clk_axi_s: + clk_disable_unprepare(res->axi_m_clk); +err_clk_axi_m: + clk_disable_unprepare(res->iface); +err_clk_iface: + /* + * Not checking for failure, will anyway return + * the original failure in 'ret'. + */ + for (i = 0; i < ARRAY_SIZE(res->rst); i++) + reset_control_assert(res->rst[i]); + + return ret; +} + +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); + u32 val; + writel(SLV_ADDR_SPACE_SZ, pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE); @@ -1124,24 +1149,6 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) PCI_EXP_DEVCTL2); return 0; - -err_clk_aux: - clk_disable_unprepare(res->ahb_clk); -err_clk_ahb: - clk_disable_unprepare(res->axi_s_clk); -err_clk_axi_s: - clk_disable_unprepare(res->axi_m_clk); -err_clk_axi_m: - clk_disable_unprepare(res->iface); -err_clk_iface: - /* - * Not checking for failure, will anyway return - * the original failure in 'ret'. - */ - for (i = 0; i < ARRAY_SIZE(res->rst); i++) - reset_control_assert(res->rst[i]); - - return ret; } static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) @@ -1467,6 +1474,7 @@ static const struct qcom_pcie_ops ops_2_4_0 = { static const struct qcom_pcie_ops ops_2_3_3 = { .get_resources = qcom_pcie_get_resources_2_3_3, .init = qcom_pcie_init_2_3_3, + .post_init = qcom_pcie_post_init_2_3_3, .deinit = qcom_pcie_deinit_2_3_3, .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, };