From ef513af4af3ca6ad664155e6f4908cf720d6afb6 Mon Sep 17 00:00:00 2001 Message-Id: From: Amit Kucheria Date: Thu, 10 Sep 2020 15:02:21 +0530 Subject: [PATCH] powercap_em: automatic registration of powercap em zones based on genpd genpd already captures the physical and virtual hierarchy of how blocks in an SoC are powered and their various dependencies. Use that to create an equivalent powercap hierarchy. FIXME: This is proof-of-concept that doesn't take in to account child and sibling relationships in genpd. Currently, all powercap zones are created at the root level. This needs to be fixed. FIXME #2: The energy costing for devices could be looked up from the energy model during init to fill up the constraint table. FIXME #3: Revisit if there is a need for a separate property inside genpd DT bindings to powercap. Signed-off-by: Amit Kucheria --- drivers/base/power/domain.c | 4 ++-- drivers/powercap/powercap_em.c | 19 +++++++++++++++++++ include/linux/powercap.h | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 2cb5e04cf86cd..f81a7c4060b65 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -38,8 +38,8 @@ __ret; \ }) -static LIST_HEAD(gpd_list); -static DEFINE_MUTEX(gpd_list_lock); +LIST_HEAD(gpd_list); +DEFINE_MUTEX(gpd_list_lock); struct genpd_lock_ops { void (*lock)(struct generic_pm_domain *genpd); diff --git a/drivers/powercap/powercap_em.c b/drivers/powercap/powercap_em.c index 725d604330c70..c616f7f3bce08 100644 --- a/drivers/powercap/powercap_em.c +++ b/drivers/powercap/powercap_em.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -464,6 +465,9 @@ static int cpuhp_powercap_em_online(unsigned int cpu) static int __init powercap_em_init(void) { + struct generic_pm_domain *genpd; + struct powercap_em *pc_dev; + pct = powercap_register_control_type(NULL, "energy_model", NULL); if (!pct) { pr_err("Failed to register control type\n"); @@ -480,6 +484,21 @@ static int __init powercap_em_init(void) if (!pc_package) return -EINVAL; + mutex_lock(&gpd_list_lock); + + list_for_each_entry(genpd, &gpd_list, gpd_list_node) { + dev_err(&genpd->dev, "registering powercap em zone"); + pc_dev = powercap_em_register(pct, dev_name(&genpd->dev), NULL, + &zone_ops, 1, &constraint_ops); + + if (!pc_dev) { + dev_err(&genpd->dev, "error registering powercap em zone"); + } + } + + mutex_unlock(&gpd_list_lock); + + return cpuhp_setup_state(CPUHP_AP_POWERCAP_EM_ONLINE, "powercap_em:online", cpuhp_powercap_em_online, NULL); diff --git a/include/linux/powercap.h b/include/linux/powercap.h index babf10261744f..943ddc108d663 100644 --- a/include/linux/powercap.h +++ b/include/linux/powercap.h @@ -20,6 +20,9 @@ struct powercap_control_type; struct powercap_zone; struct powercap_zone_constraint; +extern struct list_head gpd_list; +extern struct mutex gpd_list_lock; + /** * struct powercap_control_type_ops - Define control type callbacks * @set_enable: Enable/Disable whole control type. -- 2.25.1