[PATCH v2 08/15] PCI: rcar-gen4: Add a controller reinitialization callback

From: Koichiro Den

Date: Mon Sep 28 2026 - 13:12:38 EST


Root Port recovery needs to reset and restore the controller while
keeping the clocks enabled and the Gen5 PHY initialized. Reusing .init()
would acquire these resources again, while calling .deinit() first would
make the APP registers inaccessible to interrupt handling.

Add a per-SoC .reinit() callback that repeats the power reset and register
setup without acquiring or releasing resources. Use the same reset and
register setup helpers as .init().

Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
Changes in v2:
- Adapt to the per-SoC .init()/.deinit() callbacks in next-20260925.
Add .reinit() for recovery without changing their resource ownership
or taking another PHY initialization reference.
- Move hardware setup extraction and Gen5 initialization cleanup into
preceding patches. This patch only adds the callback and its
implementations.

drivers/pci/controller/dwc/pcie-rcar-gen4.c | 33 +++++++++++++++++++++
1 file changed, 33 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index e73ef6ccb145..d1ea94272711 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -99,6 +99,8 @@ struct rcar_gen4_pcie;
struct rcar_gen4_pcie_drvdata {
int (*init)(struct rcar_gen4_pcie *rcar);
void (*deinit)(struct rcar_gen4_pcie *rcar);
+ /* Reset and restore registers while clocks and PHY remain initialized. */
+ int (*reinit)(struct rcar_gen4_pcie *rcar);
int (*ltssm_control)(struct rcar_gen4_pcie *rcar, bool enable);
int (*speed_control)(struct rcar_gen4_pcie *rcar);
enum dw_pcie_device_mode mode;
@@ -341,6 +343,19 @@ static void rcar_gen4_v4h_v4m_pcie_configure(struct rcar_gen4_pcie *rcar)
writel(val, rcar->base + PCIEPWRMNGCTRL);
}

+static int rcar_gen4_v4h_v4m_pcie_reinit(struct rcar_gen4_pcie *rcar)
+{
+ int ret;
+
+ ret = rcar_gen4_pcie_reset(rcar);
+ if (ret)
+ return ret;
+
+ rcar_gen4_v4h_v4m_pcie_configure(rcar);
+
+ return 0;
+}
+
static int rcar_gen4_v4h_v4m_pcie_init(struct rcar_gen4_pcie *rcar)
{
int ret;
@@ -385,6 +400,19 @@ static void rcar_gen5_pcie_configure(struct rcar_gen4_pcie *rcar)
writel(val, rcar->base + PCIEPWRMNGCTRL);
}

+static int rcar_gen5_pcie_reinit(struct rcar_gen4_pcie *rcar)
+{
+ int ret;
+
+ ret = rcar_gen4_pcie_reset(rcar);
+ if (ret)
+ return ret;
+
+ rcar_gen5_pcie_configure(rcar);
+
+ return 0;
+}
+
static int rcar_gen5_pcie_init(struct rcar_gen4_pcie *rcar)
{
int ret;
@@ -1105,6 +1133,7 @@ static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable
static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
.init = rcar_gen4_pcie_common_init,
.deinit = rcar_gen4_pcie_common_deinit,
+ .reinit = rcar_gen4_pcie_reset,
.ltssm_control = r8a779f0_pcie_ltssm_control,
.speed_control = rcar_gen4_pcie_speed_control,
.mode = DW_PCIE_RC_TYPE,
@@ -1113,6 +1142,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
.init = rcar_gen4_pcie_common_init,
.deinit = rcar_gen4_pcie_common_deinit,
+ .reinit = rcar_gen4_pcie_reset,
.ltssm_control = r8a779f0_pcie_ltssm_control,
.speed_control = rcar_gen4_pcie_speed_control,
.mode = DW_PCIE_EP_TYPE,
@@ -1121,6 +1151,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie = {
.init = rcar_gen4_v4h_v4m_pcie_init,
.deinit = rcar_gen4_pcie_common_deinit,
+ .reinit = rcar_gen4_v4h_v4m_pcie_reinit,
.ltssm_control = rcar_gen4_pcie_ltssm_control,
.speed_control = rcar_gen4_pcie_speed_control,
.mode = DW_PCIE_RC_TYPE,
@@ -1129,6 +1160,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie = {
static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
.init = rcar_gen4_v4h_v4m_pcie_init,
.deinit = rcar_gen4_pcie_common_deinit,
+ .reinit = rcar_gen4_v4h_v4m_pcie_reinit,
.ltssm_control = rcar_gen4_pcie_ltssm_control,
.speed_control = rcar_gen4_pcie_speed_control,
.mode = DW_PCIE_EP_TYPE,
@@ -1137,6 +1169,7 @@ static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen5_pcie = {
.init = rcar_gen5_pcie_init,
.deinit = rcar_gen5_pcie_deinit,
+ .reinit = rcar_gen5_pcie_reinit,
.ltssm_control = rcar_gen5_pcie_ltssm_control,
.speed_control = rcar_gen5_pcie_speed_control,
.mode = DW_PCIE_RC_TYPE,
--
2.51.0