Re: [PATCH v4 5/8] PCI: rzg3s-host: Move suspend/resume code into dedicated functions

From: Lad, Prabhakar

Date: Thu Sep 24 2026 - 08:36:21 EST


On Tue, Sep 22, 2026 at 3:56 PM Claudiu Beznea
<claudiu.beznea@xxxxxxxxxx> wrote:
>
> From: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
>
> In preparation for implementing hotplug using
> pci_host_bridge::reset_root_port(), move the suspend/resume code into
> rzg3s_pcie_host_stop() and rzg3s_pcie_host_start(). These functions
> will later be reused by the hotplug implementation through
> pci_host_bridge::reset_root_port().
>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
> ---
>
> Changes in v4:
> - none
>
> Changes in v3:
> - none, this patch is new
>
> drivers/pci/controller/pcie-rzg3s-host.c | 181 ++++++++++++-----------
> 1 file changed, 96 insertions(+), 85 deletions(-)
>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>

Cheers,
Prabhakar

> diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
> index 3ecada238402..40d5ef3e347e 100644
> --- a/drivers/pci/controller/pcie-rzg3s-host.c
> +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> @@ -1742,6 +1742,100 @@ rzg3s_pcie_host_setup(struct rzg3s_pcie_host *host,
> return ret;
> }
>
> +static int rzg3s_pcie_host_stop(struct rzg3s_pcie_host *host)
> +{
> + const struct rzg3s_pcie_soc_data *data = host->data;
> + struct rzg3s_pcie_port *port = &host->port;
> + struct rzg3s_sysc *sysc = host->sysc;
> + int ret;
> +
> + clk_disable_unprepare(port->refclk);
> +
> + /* 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 config_reinit;
> +
> + /*
> + * Since the power domain's genpd_suspend_noirq() will disable clocks,
> + * there is no need to manually invoke runtime PM API here.
> + */
> +
> + ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
> + if (ret)
> + goto power_resets_restore;
> +
> + return 0;
> +
> + /* Restore the previous state if any error happens */
> +power_resets_restore:
> + reset_control_bulk_deassert(data->num_power_resets,
> + host->power_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);
> + return ret;
> +}
> +
> +static int rzg3s_pcie_host_start(struct rzg3s_pcie_host *host)
> +{
> + const struct rzg3s_pcie_soc_data *data = host->data;
> + struct rzg3s_sysc *sysc = host->sysc;
> + int ret;
> +
> + ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_MODE, 1);
> + if (ret)
> + return ret;
> +
> + ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 1);
> + if (ret)
> + return ret;
> +
> + if (host->num_lanes) {
> + ret = rzg3s_sysc_config_func(host->sysc,
> + RZG3S_SYSC_FUNC_ID_LINK_MASTER,
> + host->num_lanes == 2 ?
> + RZG3S_SYSC_LINK_MODE_DUAL_X2 :
> + RZG3S_SYSC_LINK_MODE_SINGLE_X4);
> + if (ret)
> + goto assert_rst_rsm_b;
> + }
> +
> + /*
> + * Since the power domain's genpd_resume_noirq() will enable clocks,
> + * there is no need to manually invoke runtime PM API here.
> + */
> +
> + ret = rzg3s_pcie_power_resets_deassert(host);
> + if (ret)
> + goto assert_rst_rsm_b;
> +
> + ret = rzg3s_pcie_host_setup(host, rzg3s_pcie_msi_hw_setup,
> + rzg3s_pcie_msi_hw_teardown);
> + if (ret)
> + goto assert_power_resets;
> +
> + return 0;
> +
> + /*
> + * If any error happens there is no way to recover the IP. Put it in the
> + * lowest possible power state.
> + */
> +assert_power_resets:
> + reset_control_bulk_assert(data->num_power_resets, host->power_resets);
> +assert_rst_rsm_b:
> + rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
> + return ret;
> +}
> +
> static int rzg3s_pcie_get_controller_id(struct rzg3s_pcie_host *host)
> {
> struct device_node *np = host->dev->of_node;
> @@ -1939,98 +2033,15 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
> static int rzg3s_pcie_suspend_noirq(struct device *dev)
> {
> struct rzg3s_pcie_host *host = dev_get_drvdata(dev);
> - const struct rzg3s_pcie_soc_data *data = host->data;
> - struct rzg3s_pcie_port *port = &host->port;
> - struct rzg3s_sysc *sysc = host->sysc;
> - int ret;
> -
> - clk_disable_unprepare(port->refclk);
> -
> - /* 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 config_reinit;
> -
> - /*
> - * Since the power domain's genpd_suspend_noirq() will disable clocks,
> - * there is no need to manually invoke runtime PM API here.
> - */
> -
> - ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
> - if (ret)
> - goto power_resets_restore;
>
> - return 0;
> -
> - /* Restore the previous state if any error happens */
> -power_resets_restore:
> - reset_control_bulk_deassert(data->num_power_resets,
> - host->power_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);
> - return ret;
> + return rzg3s_pcie_host_stop(host);
> }
>
> static int rzg3s_pcie_resume_noirq(struct device *dev)
> {
> struct rzg3s_pcie_host *host = dev_get_drvdata(dev);
> - const struct rzg3s_pcie_soc_data *data = host->data;
> - struct rzg3s_sysc *sysc = host->sysc;
> - int ret;
>
> - ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_MODE, 1);
> - if (ret)
> - return ret;
> -
> - ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 1);
> - if (ret)
> - return ret;
> -
> - if (host->num_lanes) {
> - ret = rzg3s_sysc_config_func(host->sysc,
> - RZG3S_SYSC_FUNC_ID_LINK_MASTER,
> - host->num_lanes == 2 ?
> - RZG3S_SYSC_LINK_MODE_DUAL_X2 :
> - RZG3S_SYSC_LINK_MODE_SINGLE_X4);
> - if (ret)
> - goto assert_rst_rsm_b;
> - }
> -
> - /*
> - * Since the power domain's genpd_resume_noirq() will enable clocks,
> - * there is no need to manually invoke runtime PM API here.
> - */
> -
> - ret = rzg3s_pcie_power_resets_deassert(host);
> - if (ret)
> - goto assert_rst_rsm_b;
> -
> - ret = rzg3s_pcie_host_setup(host, rzg3s_pcie_msi_hw_setup,
> - rzg3s_pcie_msi_hw_teardown);
> - if (ret)
> - goto assert_power_resets;
> -
> - return 0;
> -
> - /*
> - * If any error happens there is no way to recover the IP. Put it in the
> - * lowest possible power state.
> - */
> -assert_power_resets:
> - reset_control_bulk_assert(data->num_power_resets,
> - host->power_resets);
> -assert_rst_rsm_b:
> - rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
> - return ret;
> + return rzg3s_pcie_host_start(host);
> }
>
> static const struct dev_pm_ops rzg3s_pcie_pm_ops = {
> --
> 2.43.0
>
>