From 295657e392df0ccd19e95f3eb7db309ee2aad449 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 3 Sep 2026 22:50:54 +0200 Subject: [PATCH] PCI: rcar-gen4: Add Application/Local register reset control The R-Car Gen4 PCIe controller does contain core reset, which puts the controller back into well-defined state, but it does also tear down the PCIe link. This is called Application/Local register reset in the documentation. Deassert the core reset after the core clock has been enabled, and assert the core reset in case of error or when shutting down the controller. This also fixes reinitialization failure of the controller, where if the controller driver is unbound and bound again via sysfs attributes, the controller driver will fail to probe the second time because it fails to access the controller DBI, which returns all zeroes unless the core reset is toggled. The following commands trigger this fault on R-Car V4H: $ echo e65d0000.pcie > /sys/bus/platform/drivers/pcie-rcar-gen4/unbind $ echo e65d0000.pcie > /sys/bus/platform/drivers/pcie-rcar-gen4/bind Fixes: faf5a975ee3b ("PCI: rcar-gen4: Add support for R-Car V4H") Signed-off-by: Marek Vasut [mani: added fixes tag and cced noautosel] Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Cc: # DTS dependency Link: https://patch.msgid.link/20260903205153.283553-3-marek.vasut+renesas@mailbox.org --- drivers/pci/controller/dwc/pcie-rcar-gen4.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c index 0b7ae4a69308..21c3dd9b8891 100644 --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c @@ -237,6 +237,8 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) return ret; } + reset_control_deassert(dw->core_rsts[DW_PCIE_CORE_RST].rstc); + if (!reset_control_status(dw->core_rsts[DW_PCIE_PWR_RST].rstc)) { reset_control_assert(dw->core_rsts[DW_PCIE_PWR_RST].rstc); /* @@ -284,6 +286,7 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) return 0; err_unprepare: + reset_control_assert(dw->core_rsts[DW_PCIE_CORE_RST].rstc); clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks); return ret; @@ -362,6 +365,7 @@ static void rcar_gen4_pcie_common_deinit(struct rcar_gen4_pcie *rcar) struct dw_pcie *dw = &rcar->dw; reset_control_assert(dw->core_rsts[DW_PCIE_PWR_RST].rstc); + reset_control_assert(dw->core_rsts[DW_PCIE_CORE_RST].rstc); clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks); }