[PATCH v7 07/10] pmdomain: samsung: add support for google,gs101-pd

Peter Griffin peter.griffin at linaro.org
Fri Mar 6 07:20:29 PST 2026


On Fri, 6 Mar 2026 at 10:29, André Draszik <andre.draszik at linaro.org> wrote:
>
> On Google gs101, direct mmio register access to the PMU registers
> doesn't work and access must happen via a regmap created by the PMU
> driver instead.
>
> Add a flag to the device match data to denote this case, and obtain
> the regmap using the parent node in DT if true, while keeping to use
> the traditional direct mmio regmap otherwise.
>
> Additionally, the status is just one bit on gs101.
>
> Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Signed-off-by: André Draszik <andre.draszik at linaro.org>
>
> ---

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

> v4:
> - add 'use_parent_regmap' flag instead of going by 'syscon' compatible
>   in parent, as it's not a given that the parent provides a syscon-
>   compatible regmap (it actually doesn't anymore after recent changes
>   on gs101)
>
> I've still kept Marek's Tested-by from v3, as legacy Exynos code
> doesn't change.
> ---
>  drivers/pmdomain/samsung/exynos-pm-domains.c | 66 +++++++++++++++++++---------
>  1 file changed, 46 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/pmdomain/samsung/exynos-pm-domains.c b/drivers/pmdomain/samsung/exynos-pm-domains.c
> index 8df46b41f9bc..2214d9f32d59 100644
> --- a/drivers/pmdomain/samsung/exynos-pm-domains.c
> +++ b/drivers/pmdomain/samsung/exynos-pm-domains.c
> @@ -12,6 +12,7 @@
>  #include <linux/err.h>
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/pm_domain.h>
>  #include <linux/delay.h>
>  #include <linux/of.h>
> @@ -21,6 +22,7 @@
>  struct exynos_pm_domain_config {
>         /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */
>         u32 local_pwr_cfg;
> +       bool use_parent_regmap;
>  };
>
>  /*
> @@ -93,8 +95,16 @@ static const struct exynos_pm_domain_config exynos5433_cfg = {
>         .local_pwr_cfg          = 0xf,
>  };
>
> +static const struct exynos_pm_domain_config gs101_cfg = {
> +       .local_pwr_cfg          = BIT(0),
> +       .use_parent_regmap      = true,
> +};
> +
>  static const struct of_device_id exynos_pm_domain_of_match[] = {
>         {
> +               .compatible = "google,gs101-pd",
> +               .data = &gs101_cfg,
> +       }, {
>                 .compatible = "samsung,exynos4210-pd",
>                 .data = &exynos4210_cfg,
>         }, {
> @@ -122,17 +132,9 @@ static int exynos_pd_probe(struct platform_device *pdev)
>         struct of_phandle_args child, parent;
>         struct exynos_pm_domain *pd;
>         struct resource *res;
> -       void __iomem *base;
>         unsigned int val;
>         int on, ret;
>
> -       struct regmap_config reg_config = {
> -               .reg_bits = 32,
> -               .val_bits = 32,
> -               .reg_stride = 4,
> -               .use_relaxed_mmio = true,
> -       };
> -
>         pm_domain_cfg = of_device_get_match_data(dev);
>         pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
>         if (!pd)
> @@ -143,25 +145,49 @@ static int exynos_pd_probe(struct platform_device *pdev)
>                 return -ENOMEM;
>
>         /*
> -        * The resource typically points into the address space of the PMU.
> +        * The resource typically points into the address space of the PMU and
> +        * we have to consider two cases:
> +        *   1) some implementations require a custom regmap (from PMU parent)
> +        *   2) this driver might map the same addresses as the PMU driver
>          * Therefore, avoid using devm_platform_get_and_ioremap_resource() and
> -        * instead use platform_get_resource() and devm_ioremap() to avoid
> +        * instead use platform_get_resource() here, and below for case 1) use
> +        * syscon_node_to_regmap() while for case 2) use devm_ioremap() to avoid
>          * conflicts due to address space overlap.
>          */
>         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>         if (!res)
>                 return dev_err_probe(dev, -ENXIO, "missing IO resources");
>
> -       base = devm_ioremap(dev, res->start, resource_size(res));
> -       if (!base)
> -               return dev_err_probe(dev, -ENOMEM,
> -                                    "failed to ioremap PMU registers");
> -
> -       reg_config.max_register = resource_size(res) - reg_config.reg_stride;
> -       pd->regmap = devm_regmap_init_mmio(dev, base, &reg_config);
> -       if (IS_ERR(pd->regmap))
> -               return dev_err_probe(dev, PTR_ERR(base),
> -                                    "failed to init regmap");
> +       if (pm_domain_cfg->use_parent_regmap) {
> +               pd->regmap = syscon_node_to_regmap(dev->parent->of_node);
> +               if (IS_ERR(pd->regmap))
> +                       return dev_err_probe(dev, PTR_ERR(pd->regmap),
> +                                            "failed to acquire PMU regmap");
> +
> +               pd->configuration_reg = res->start;
> +               pd->status_reg = res->start;
> +       } else {
> +               void __iomem *base;
> +
> +               const struct regmap_config reg_config = {
> +                       .reg_bits = 32,
> +                       .val_bits = 32,
> +                       .reg_stride = 4,
> +                       .use_relaxed_mmio = true,
> +                       .max_register = (resource_size(res)
> +                                        - reg_config.reg_stride),
> +               };
> +
> +               base = devm_ioremap(dev, res->start, resource_size(res));
> +               if (!base)
> +                       return dev_err_probe(dev, -ENOMEM,
> +                                            "failed to ioremap PMU registers");
> +
> +               pd->regmap = devm_regmap_init_mmio(dev, base, &reg_config);
> +               if (IS_ERR(pd->regmap))
> +                       return dev_err_probe(dev, PTR_ERR(base),
> +                                            "failed to init regmap");
> +       }
>
>         pd->pd.power_off = exynos_pd_power_off;
>         pd->pd.power_on = exynos_pd_power_on;
>
> --
> 2.53.0.473.g4a7958ca14-goog
>



More information about the linux-arm-kernel mailing list