From: John Madieu Date: Fri, 6 Mar 2026 14:34:16 +0000 (+0100) Subject: PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks X-Git-Tag: v7.1-rc1~151^2~1^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5f2c4de717786150f8d6cdbdbffb986cd3c59edb;p=thirdparty%2Fkernel%2Flinux.git PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks 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 callbacks that fall back to the reset framework - RZ/G3E: Sets num_cfg_resets=0, provides cfg_pre_init/cfg_post_init/cfg_deinit Signed-off-by: John Madieu Signed-off-by: Manivannan Sadhasivam Tested-by: Lad Prabhakar # RZ/V2N EVK Tested-by: Claudiu Beznea Reviewed-by: Claudiu Beznea Link: https://patch.msgid.link/20260306143423.19562-10-john.madieu.xa@bp.renesas.com --- diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c index c818651c0b750..be6b7fa1a053f 100644 --- a/drivers/pci/controller/pcie-rzg3s-host.c +++ b/drivers/pci/controller/pcie-rzg3s-host.c @@ -233,6 +233,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 @@ -243,6 +246,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; @@ -1109,6 +1115,18 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host) return 0; } +static int rzg3s_pcie_config_post_init(struct rzg3s_pcie_host *host) +{ + return reset_control_bulk_deassert(host->data->num_cfg_resets, + host->cfg_resets); +} + +static int rzg3s_pcie_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) { /* @@ -1257,22 +1275,26 @@ 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; + goto config_deinit_and_refclk; /* Wait for link up */ ret = readl_poll_timeout(host->axi + RZG3S_PCI_PCSTAT1, val, @@ -1281,18 +1303,20 @@ 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); -disable_port_refclk: +config_deinit_post: + host->data->config_deinit(host); +config_deinit_and_refclk: clk_disable_unprepare(host->port.refclk); +config_deinit: + if (host->data->config_pre_init) + host->data->config_deinit(host); return ret; } @@ -1653,7 +1677,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: @@ -1686,15 +1710,15 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev) clk_disable_unprepare(port->refclk); - ret = reset_control_bulk_assert(data->num_cfg_resets, - host->cfg_resets); + /* SoC-specific de-initialization */ + ret = data->config_deinit(host); if (ret) goto refclk_restore; ret = reset_control_bulk_assert(data->num_power_resets, host->power_resets); if (ret) - goto cfg_resets_restore; + goto config_reinit; ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0); if (ret) @@ -1706,9 +1730,10 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev) power_resets_restore: reset_control_bulk_deassert(data->num_power_resets, host->power_resets); -cfg_resets_restore: - reset_control_bulk_deassert(data->num_cfg_resets, - host->cfg_resets); +config_reinit: + if (data->config_pre_init) + data->config_pre_init(host); + data->config_post_init(host); refclk_restore: clk_prepare_enable(port->refclk); pm_runtime_resume_and_get(dev); @@ -1773,6 +1798,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_pcie_config_post_init, + .config_deinit = rzg3s_pcie_config_deinit, .init_phy = rzg3s_soc_pcie_init_phy, .sysc_info = { .functions = {