[PATCH v7 10/10] pmdomain: samsung: implement domain-supply regulator

Peter Griffin peter.griffin at linaro.org
Fri Mar 6 07:47:24 PST 2026


On Fri, 6 Mar 2026 at 10:30, André Draszik <andre.draszik at linaro.org> wrote:
>
> Some power domains on Exynos are fed by a regulator rail and therefore
> regulator control needs be implemented for Exynos power domains.
>
> On Google gs101, HSI0 (USB) is one example of such a power domain.
>
> While at it, add a to_exynos_pd() to avoid direct use of
> container_of() in various additional places, and update existing code
> to use it.
>
> Signed-off-by: André Draszik <andre.draszik at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>

>  drivers/pmdomain/samsung/exynos-pm-domains.c | 53 +++++++++++++++++++++++++---
>  1 file changed, 48 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pmdomain/samsung/exynos-pm-domains.c b/drivers/pmdomain/samsung/exynos-pm-domains.c
> index f59986b56213..ed7a5807555b 100644
> --- a/drivers/pmdomain/samsung/exynos-pm-domains.c
> +++ b/drivers/pmdomain/samsung/exynos-pm-domains.c
> @@ -20,12 +20,15 @@
>  #include <linux/of_address.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
>
>  #define EXYNOS_SMC_CMD_PREPARE_PD_ONOFF                0x82000410
>  #define EXYNOS_GET_IN_PD_DOWN                  0
>  #define EXYNOS_WAKEUP_PD_DOWN                  1
>  #define EXYNOS_RUNTIME_PM_TZPC_GROUP           2
>
> +#define to_exynos_pd(gpd) container_of_const(gpd, struct exynos_pm_domain, pd)
> +
>  struct exynos_pm_domain_config {
>         /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */
>         u32 local_pwr_cfg;
> @@ -39,6 +42,7 @@ struct exynos_pm_domain_config {
>  struct exynos_pm_domain {
>         struct regmap *regmap;
>         struct device *dev;
> +       struct regulator *supply;
>         struct generic_pm_domain pd;
>         const struct exynos_pm_domain_config *cfg;
>         u32 configuration_reg;
> @@ -64,12 +68,10 @@ static int exynos_pd_access_controller_power(struct exynos_pm_domain *pd,
>
>  static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
>  {
> -       struct exynos_pm_domain *pd;
> +       struct exynos_pm_domain *pd = to_exynos_pd(domain);
>         u32 timeout, pwr;
>         int err;
>
> -       pd = container_of(domain, struct exynos_pm_domain, pd);
> -
>         if (!power_on) {
>                 err = exynos_pd_access_controller_power(pd, power_on);
>                 if (err) {
> @@ -126,14 +128,45 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
>         return err;
>  }
>
> +static int exynos_pd_regulator_enable(struct regulator *supply)
> +{
> +       return supply ? regulator_enable(supply) : 0;
> +}
> +
> +static int exynos_pd_regulator_disable(struct regulator *supply)
> +{
> +       return supply ? regulator_disable(supply) : 0;
> +}
> +
>  static int exynos_pd_power_on(struct generic_pm_domain *domain)
>  {
> -       return exynos_pd_power(domain, true);
> +       struct exynos_pm_domain *pd = to_exynos_pd(domain);
> +       int ret;
> +
> +       ret = exynos_pd_regulator_enable(pd->supply);
> +       if (ret)
> +               return ret;
> +
> +       ret = exynos_pd_power(domain, true);
> +       if (ret)
> +               exynos_pd_regulator_disable(pd->supply);
> +
> +       return ret;
>  }
>
>  static int exynos_pd_power_off(struct generic_pm_domain *domain)
>  {
> -       return exynos_pd_power(domain, false);
> +       struct exynos_pm_domain *pd = to_exynos_pd(domain);
> +       int ret;
> +
> +       ret = exynos_pd_power(domain, false);
> +       if (ret)
> +               return ret;
> +
> +       /* Ignore regulator errors - the domain was disabled after all. */
> +       exynos_pd_regulator_disable(pd->supply);
> +
> +       return 0;
>  }
>
>  static const struct exynos_pm_domain_config exynos4210_cfg = {
> @@ -283,6 +316,16 @@ static int exynos_pd_probe(struct platform_device *pdev)
>         if (ret)
>                 return ret;
>
> +       /* get the domain power supply if required */
> +       pd->supply = devm_regulator_get_optional(dev, "domain");
> +       if (IS_ERR(pd->supply)) {
> +               if (PTR_ERR(pd->supply) != -ENODEV)
> +                       return dev_err_probe(dev, PTR_ERR(pd->supply),
> +                                            "failed to get domain supply");
> +
> +               pd->supply = NULL;
> +       }
> +
>         /*
>          * Some Samsung platforms with bootloaders turning on the splash-screen
>          * and handing it over to the kernel, requires the power-domains to be
>
> --
> 2.53.0.473.g4a7958ca14-goog
>



More information about the linux-arm-kernel mailing list