[PATCH v3 02/10] PCI: tegra194: Check core reset deassertion

From: Manikanta Maddireddy

Date: Mon Nov 02 2026 - 06:59:51 EST


Several paths access DBI registers after deasserting the controller core
reset. If reset_control_deassert() fails, those DBI accesses can trigger a
CBB timeout, or setup can return success with the core still in reset.

Check core reset deassertion in Root Port setup, the DLF retry path and the
Endpoint PERST# deassert path. Unwind before DBI access when deassertion
fails.

Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
Signed-off-by: Manikanta Maddireddy <mmaddireddy@xxxxxxxxxx>
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
---
Changes V2 -> V3: None apart from rebasing.

Changes V1 -> V2: None

drivers/pci/controller/dwc/pcie-tegra194.c | 23 +++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 4490627a539a..d504d7cd3c49 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -955,6 +955,7 @@ static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
struct dw_pcie_rp *pp = &pci->pp;
u32 val, offset, tmp;
+ int ret;
bool retry = true;

if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
@@ -1010,7 +1011,12 @@ static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
appl_writel(pcie, val, APPL_CTRL);

reset_control_assert(pcie->core_rst);
- reset_control_deassert(pcie->core_rst);
+ ret = reset_control_deassert(pcie->core_rst);
+ if (ret) {
+ dev_err(pci->dev, "Failed to deassert core reset: %d\n",
+ ret);
+ return ret;
+ }

offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_DLF);
val = dw_pcie_readl_dbi(pci, offset + PCI_DLF_CAP);
@@ -1456,10 +1462,16 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
pcie->atu_dma_res->start & APPL_CFG_IATU_DMA_BASE_ADDR_MASK,
APPL_CFG_IATU_DMA_BASE_ADDR);

- reset_control_deassert(pcie->core_rst);
+ ret = reset_control_deassert(pcie->core_rst);
+ if (ret) {
+ dev_err(pcie->dev, "Failed to deassert core reset: %d\n", ret);
+ goto fail_core_rst;
+ }

return ret;

+fail_core_rst:
+ tegra_pcie_disable_phy(pcie);
fail_phy:
reset_control_assert(pcie->core_apb_rst);
fail_core_apb_rst:
@@ -1854,7 +1866,11 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
LTR_NOSNOOP_MSG_REQ;
appl_writel(pcie, val, APPL_LTR_MSG_1);

- reset_control_deassert(pcie->core_rst);
+ ret = reset_control_deassert(pcie->core_rst);
+ if (ret) {
+ dev_err(dev, "Failed to deassert core reset: %d\n", ret);
+ goto fail_core_rst;
+ }

/* Perform cleanup that requires refclk and core reset deasserted */
pci_epc_deinit_notify(pcie->pci.ep.epc);
@@ -1928,6 +1944,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)

fail_init_complete:
reset_control_assert(pcie->core_rst);
+fail_core_rst:
tegra_pcie_disable_phy(pcie);
fail_phy:
reset_control_assert(pcie->core_apb_rst);
--
2.34.1