[PATCH v4 09/15] PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks
From: John Madieu <john.madieu.xa@bp.renesas.com>
Date: 2026-01-29 21:42:53
Also in:
linux-clk, linux-pci, linux-renesas-soc
Subsystem:
pci native host bridge and endpoint drivers, pci subsystem, pcie driver for renesas rz/g3s series, the rest · Maintainers:
Lorenzo Pieralisi, Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas, Claudiu Beznea, Linus Torvalds
Add optional cfg_pre_init, cfg_post_init, and cfg_deinit callbacks to handle SoC-specific configuration methods. While RZ/G3S uses the Linux reset framework with dedicated reset lines, other SoC variants like RZ/G3E control configuration resets through PCIe AXI registers. As Linux reset bulk API gracefully handles optional NULL reset lines (num_cfg_resets = 0 for RZ/G3E), the driver continues to use the standard reset framework when reset lines are available, while custom callbacks are only invoked when provided. This provides a balanced pattern where: - RZ/G3S: Uses reset framework only, no callbacks needed - RZ/G3E: Sets num_cfg_resets=0, provides cfg_pre_init/cfg_post_init/cfg_deinit - In addition to that, RZ/G3E requires explicit cfg reset and clock turned off to put the PCIe IP in a known state. Add cfg_pre_init, cfg_post_init, and cfg_deinit callbacks to support custom configuration mechanism in preparation to RZ/G3E PCIe support. Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com> --- Changes: v4: No changes v3: No changes v2: - Renamed callbacks as per Claudiu's comments - Reworded goto labels to be consistents with callbacks drivers/pci/controller/pcie-rzg3s-host.c | 66 +++++++++++++++++------- 1 file changed, 46 insertions(+), 20 deletions(-)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index a6fb2ec4a341..15ccd9095a3e 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c@@ -223,6 +223,9 @@ struct rzg3s_pcie_host; /** * struct rzg3s_pcie_soc_data - SoC specific data * @init_phy: PHY initialization function + * @config_pre_init: Optional callback for SoC-specific pre-configuration + * @config_post_init: Callback for SoC-specific post-configuration + * @config_deinit: Callback for SoC-specific de-initialization * @power_resets: array with the resets that need to be de-asserted after * power-on * @cfg_resets: array with the resets that need to be de-asserted after
@@ -233,6 +236,9 @@ struct rzg3s_pcie_host; */ struct rzg3s_pcie_soc_data { int (*init_phy)(struct rzg3s_pcie_host *host); + void (*config_pre_init)(struct rzg3s_pcie_host *host); + int (*config_post_init)(struct rzg3s_pcie_host *host); + int (*config_deinit)(struct rzg3s_pcie_host *host); const char * const *power_resets; const char * const *cfg_resets; struct rzg3s_sysc_info sysc_info;
@@ -1082,6 +1088,18 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host) return 0; } +static int rzg3s_config_post_init(struct rzg3s_pcie_host *host) +{ + return reset_control_bulk_deassert(host->data->num_cfg_resets, + host->cfg_resets); +} + +static int rzg3s_config_deinit(struct rzg3s_pcie_host *host) +{ + return reset_control_bulk_assert(host->data->num_cfg_resets, + host->cfg_resets); +} + static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host) { /*
@@ -1229,20 +1247,24 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host) u32 val; int ret; + /* SoC-specific pre-configuration */ + if (host->data->config_pre_init) + host->data->config_pre_init(host); + /* Initialize the PCIe related registers */ ret = rzg3s_pcie_config_init(host); if (ret) - return ret; + goto config_deinit; ret = rzg3s_pcie_host_init_port(host); if (ret) - return ret; + goto config_deinit; /* Initialize the interrupts */ rzg3s_pcie_irq_init(host); - ret = reset_control_bulk_deassert(host->data->num_cfg_resets, - host->cfg_resets); + /* SoC-specific post-configuration */ + ret = host->data->config_post_init(host); if (ret) goto disable_port_refclk;
@@ -1253,19 +1275,22 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host) PCIE_LINK_WAIT_SLEEP_MS * MILLI * PCIE_LINK_WAIT_MAX_RETRIES); if (ret) - goto cfg_resets_deassert; + goto config_deinit_post; val = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2); dev_info(host->dev, "PCIe link status [0x%x]\n", val); return 0; -cfg_resets_deassert: - reset_control_bulk_assert(host->data->num_cfg_resets, - host->cfg_resets); +config_deinit_post: + host->data->config_deinit(host); disable_port_refclk: clk_disable_unprepare(host->port.refclk); return ret; + +config_deinit: + host->data->config_deinit(host); + return ret; } static void rzg3s_pcie_set_inbound_window(struct rzg3s_pcie_host *host,
@@ -1631,7 +1656,7 @@ static int rzg3s_pcie_probe(struct platform_device *pdev) host_probe_teardown: rzg3s_pcie_teardown_irqdomain(host); - reset_control_bulk_assert(host->data->num_cfg_resets, host->cfg_resets); + host->data->config_deinit(host); rpm_put: pm_runtime_put_sync(dev); rpm_disable:
@@ -1666,32 +1691,31 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev) clk_disable_unprepare(port->refclk); - ret = reset_control_bulk_assert(data->num_power_resets, - host->power_resets); + /* SoC-specific de-initialization */ + ret = data->config_deinit(host); if (ret) - goto refclk_restore; + goto config_reinit; - ret = reset_control_bulk_assert(data->num_cfg_resets, - host->cfg_resets); + ret = reset_control_bulk_assert(data->num_power_resets, + host->power_resets); if (ret) - goto power_resets_restore; + goto config_reinit; ret = regmap_update_bits(sysc->regmap, sysc->info->rst_rsm_b.offset, sysc->info->rst_rsm_b.mask, field_prep(sysc->info->rst_rsm_b.mask, 0)); if (ret) - goto cfg_resets_restore; + goto power_resets_restore; return 0; /* Restore the previous state if any error happens */ -cfg_resets_restore: - reset_control_bulk_deassert(data->num_cfg_resets, - host->cfg_resets); power_resets_restore: reset_control_bulk_deassert(data->num_power_resets, host->power_resets); -refclk_restore: +config_reinit: + data->config_post_init(host); + clk_prepare_enable(port->refclk); pm_runtime_resume_and_get(dev); return ret;
@@ -1759,6 +1783,8 @@ static const struct rzg3s_pcie_soc_data rzg3s_soc_data = { .num_power_resets = ARRAY_SIZE(rzg3s_soc_power_resets), .cfg_resets = rzg3s_soc_cfg_resets, .num_cfg_resets = ARRAY_SIZE(rzg3s_soc_cfg_resets), + .config_post_init = rzg3s_config_post_init, + .config_deinit = rzg3s_config_deinit, .init_phy = rzg3s_soc_pcie_init_phy, .sysc_info = { .rst_rsm_b = {
--
2.25.1