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

From: Marek Vasut

Date: Sat Oct 03 2026 - 20:01:50 EST


On 9/28/26 6:52 PM, Koichiro Den wrote:
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.
Could we introduce .configure callback instead, and deduplicate the two rcar_{gen4_v4h_v4m,gen5}_pcie_reinit() functions ? What do you think ?

This kind of a change (this would likely require folding this patch into 09/15):

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 3d667f25fb32e..3691c2ddbf6bc 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -100,7 +100,7 @@ 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);
+ void (*configure)(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;
@@ -326,6 +326,20 @@ static void rcar_gen4_pcie_common_deinit(struct rcar_gen4_pcie *rcar)
clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks);
}

+static int rcar_gen4_pcie_common_reinit(struct rcar_gen4_pcie *rcar)
+{
+ int ret;
+
+ ret = rcar_gen4_pcie_reset(rcar);
+ if (ret)
+ return ret;
+
+ if (rcar->drvdata->configure)
+ rcar->drvdata->configure(rcar);
+
+ return 0;
+}
+
static void rcar_gen4_v4h_v4m_pcie_configure(struct rcar_gen4_pcie *rcar)
{
struct dw_pcie *dw = &rcar->dw;
@@ -343,19 +357,6 @@ 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;
@@ -400,19 +401,6 @@ 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;
@@ -1133,7 +1121,6 @@ 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,
@@ -1142,7 +1129,6 @@ 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,
@@ -1151,7 +1137,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,
+ .configure = rcar_gen4_v4h_v4m_pcie_configure,
.ltssm_control = rcar_gen4_pcie_ltssm_control,
.speed_control = rcar_gen4_pcie_speed_control,
.mode = DW_PCIE_RC_TYPE,
@@ -1160,7 +1146,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,
+ .configure = rcar_gen4_v4h_v4m_pcie_configure,
.ltssm_control = rcar_gen4_pcie_ltssm_control,
.speed_control = rcar_gen4_pcie_speed_control,
.mode = DW_PCIE_EP_TYPE,
@@ -1169,7 +1155,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,
+ .configure = rcar_gen5_pcie_configure,
.ltssm_control = rcar_gen5_pcie_ltssm_control,
.speed_control = rcar_gen5_pcie_speed_control,
.mode = DW_PCIE_RC_TYPE,