Re: [PATCH v2 08/10] clk: renesas: rzg2l-cpg: Add suspend/resume support for power domains
From: Geert Uytterhoeven
Date: Mon Mar 18 2024 - 12:51:29 EST
Hi Claudiu,
On Thu, Mar 7, 2024 at 3:07 PM Claudiu <claudiu.beznea@xxxxxxxxx> wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
>
> RZ/G3S supports deep sleep states that it can reach with the help of the
> TF-A.
>
> RZ/G3S has a few power domains (e.g. GIC) that need to be always-on while
> Linux is running. These domains are initialized (and powered on) when
> clock driver is probed.
>
> As the TF-A takes control at the very last(suspend)/first(resume)
> phase of configuring the deep sleep state, it can do it's own settings on
> power domains.
>
> Thus, to restore the proper Linux state, add rzg2l_cpg_resume() which
> powers on the always-on domains and rzg2l_cpg_complete() which activates
> the power down mode for the IPs selected through CPG_PWRDN_IP{1, 2}.
>
> Along with it, added the suspend_check member to the RZ/G2L power domain
> data structure whose purpose is to checks if a domain can be powered off
> while the system is going to suspend. This is necessary for the serial
> console domain which needs to be powered on if no_console_suspend is
> available in bootargs.
>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
> ---
>
> Changes in v2:
> - none; this patch is new
Thanks for your patch!
> --- a/drivers/clk/renesas/rzg2l-cpg.c
> +++ b/drivers/clk/renesas/rzg2l-cpg.c
> @@ -1700,6 +1719,8 @@ static int __init rzg2l_cpg_pd_setup(struct rzg2l_cpg_pd *pd, bool always_on)
> } else {
> pd->genpd.power_on = rzg2l_cpg_power_on;
> pd->genpd.power_off = rzg2l_cpg_power_off;
> + if (flags & RZG2L_PD_F_CONSOLE)
I think this should be replaced by some dynamic check, cfr. my comments
on PATCH 9/10.
> + pd->suspend_check = rzg2l_pd_suspend_check_console;
> governor = &simple_qos_governor;
> }
>
> @@ -1890,9 +1911,43 @@ static int __init rzg2l_cpg_probe(struct platform_device *pdev)
> if (error)
> return error;
>
> + dev_set_drvdata(dev, priv);
> +
> return 0;
> }
>
> +static int rzg2l_cpg_resume(struct device *dev)
> +{
> + struct rzg2l_cpg_priv *priv = dev_get_drvdata(dev);
> + const struct rzg2l_cpg_info *info = priv->info;
> +
> + /* Power on always ON domains. */
> + for (unsigned int i = 0; i < info->num_pm_domains; i++) {
> + if (info->pm_domains[i].flags & RZG2L_PD_F_ALWAYS_ON) {
If you would check "priv-domains[i].flags & GENPD_FLAG_ALWAYS_ON"
instead, I think you can make r9a08g045_pm_domains[] __initconst.
You may need to make a copy of the name for pd->genpd.name, though.
> + int ret = rzg2l_cpg_power_on(priv->domains[i]);
I assume you are sure none of these domains are enabled by TF/A after
system resume, or by the pmdomain core code?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68korg
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds