pmdomain: amlogic: add driver to support power parent node
authorxianwei.zhao <xianwei.zhao@amlogic.com>
Mon, 11 Sep 2023 02:52:19 +0000 (10:52 +0800)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 13 Sep 2023 22:10:00 +0000 (00:10 +0200)
Some power domains depends on other domains, Such as Amlogic T7 SoC.
Add parent node to support this case.

Signed-off-by: xianwei.zhao <xianwei.zhao@amlogic.com>
Link: https://lore.kernel.org/r/20230911025223.3433776-3-xianwei.zhao@amlogic.com
[Ulf: Re-based to fit the pmdomain subsystem]
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/pmdomain/amlogic/meson-secure-pwrc.c

index 5ac2437ab8adb0155168966327b600cd59bf32d7..ecada537b19c964d6278f325bd5a3dfd4c1396cd 100644 (file)
 
 #define PWRC_ON                1
 #define PWRC_OFF       0
+#define PWRC_NO_PARENT UINT_MAX
 
 struct meson_secure_pwrc_domain {
        struct generic_pm_domain base;
        unsigned int index;
+       unsigned int parent;
        struct meson_secure_pwrc *pwrc;
 };
 
@@ -34,6 +36,7 @@ struct meson_secure_pwrc {
 
 struct meson_secure_pwrc_domain_desc {
        unsigned int index;
+       unsigned int parent;
        unsigned int flags;
        char *name;
        bool (*is_off)(struct meson_secure_pwrc_domain *pwrc_domain);
@@ -90,8 +93,19 @@ static int meson_secure_pwrc_on(struct generic_pm_domain *domain)
 {                                              \
        .name = #__name,                        \
        .index = PWRC_##__name##_ID,            \
-       .is_off = pwrc_secure_is_off,   \
+       .is_off = pwrc_secure_is_off,           \
        .flags = __flag,                        \
+       .parent = PWRC_NO_PARENT,               \
+}
+
+#define TOP_PD(__name, __flag, __parent)       \
+[PWRC_##__name##_ID] =                         \
+{                                              \
+       .name = #__name,                        \
+       .index = PWRC_##__name##_ID,            \
+       .is_off = pwrc_secure_is_off,           \
+       .flags = __flag,                        \
+       .parent = __parent,                     \
 }
 
 static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
@@ -202,6 +216,7 @@ static int meson_secure_pwrc_probe(struct platform_device *pdev)
 
                dom->pwrc = pwrc;
                dom->index = match->domains[i].index;
+               dom->parent = match->domains[i].parent;
                dom->base.name = match->domains[i].name;
                dom->base.flags = match->domains[i].flags;
                dom->base.power_on = meson_secure_pwrc_on;
@@ -212,6 +227,15 @@ static int meson_secure_pwrc_probe(struct platform_device *pdev)
                pwrc->xlate.domains[i] = &dom->base;
        }
 
+       for (i = 0; i < match->count; i++) {
+               struct meson_secure_pwrc_domain *dom = pwrc->domains;
+
+               if (!match->domains[i].name || match->domains[i].parent == PWRC_NO_PARENT)
+                       continue;
+
+               pm_genpd_add_subdomain(&dom[dom[i].parent].base, &dom[i].base);
+       }
+
        return of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate);
 }