[PATCH 07/11] pmdomain: core: Export a common ->sync_state() helper for genpd providers

Ulf Hansson posted 11 patches 8 months ago
There is a newer version of this series
[PATCH 07/11] pmdomain: core: Export a common ->sync_state() helper for genpd providers
Posted by Ulf Hansson 8 months ago
In some cases the typical platform driver that act as genpd provider, may
need its own ->sync_state() callback to manage various things. In this
regards, the provider most likely wants to allow its corresponding genpds
to be powered-off.

For this reason, let's introduce a new genpd helper function,
of_genpd_sync_state() that helps genpd provider drivers to achieve this.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c   | 28 ++++++++++++++++++++++++++++
 include/linux/pm_domain.h |  3 +++
 2 files changed, 31 insertions(+)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 5aba66ac78f1..512f89e6d302 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2619,6 +2619,34 @@ static bool genpd_present(const struct generic_pm_domain *genpd)
 	return ret;
 }
 
+/**
+ * of_genpd_sync_state() - A common sync_state function for genpd providers
+ * @dev: The device the genpd provider is associated with.
+ *
+ * The @dev that corresponds to a genpd provider may provide one or multiple
+ * genpds. This function makes use of the device node for @dev to find the
+ * genpds that belongs to the provider. For each genpd we try a power-off.
+ */
+void of_genpd_sync_state(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct generic_pm_domain *genpd;
+
+	if (!np)
+		return;
+
+	mutex_lock(&gpd_list_lock);
+	list_for_each_entry(genpd, &gpd_list, gpd_list_node) {
+		if (genpd->provider == &np->fwnode) {
+			genpd_lock(genpd);
+			genpd_power_off(genpd, false, 0);
+			genpd_unlock(genpd);
+		}
+	}
+	mutex_unlock(&gpd_list_lock);
+}
+EXPORT_SYMBOL_GPL(of_genpd_sync_state);
+
 /**
  * of_genpd_add_provider_simple() - Register a simple PM domain provider
  * @np: Device node pointer associated with the PM domain provider.
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 0b18160901a2..e9a1f8975c4f 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -418,6 +418,7 @@ struct genpd_onecell_data {
 };
 
 #ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+void of_genpd_sync_state(struct device *dev);
 int of_genpd_add_provider_simple(struct device_node *np,
 				 struct generic_pm_domain *genpd);
 int of_genpd_add_provider_onecell(struct device_node *np,
@@ -438,6 +439,8 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
 struct device *genpd_dev_pm_attach_by_name(struct device *dev,
 					   const char *name);
 #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
+static inline void of_genpd_sync_state(struct device *dev) {}
+
 static inline int of_genpd_add_provider_simple(struct device_node *np,
 					struct generic_pm_domain *genpd)
 {
-- 
2.43.0
Re: [PATCH 07/11] pmdomain: core: Export a common ->sync_state() helper for genpd providers
Posted by Dan Carpenter 7 months, 1 week ago
On Thu, Apr 17, 2025 at 04:25:05PM +0200, Ulf Hansson wrote:
> +void of_genpd_sync_state(struct device *dev)
> +{
> +	struct device_node *np = dev->of_node;
> +	struct generic_pm_domain *genpd;
> +
> +	if (!np)
> +		return;
> +
> +	mutex_lock(&gpd_list_lock);
> +	list_for_each_entry(genpd, &gpd_list, gpd_list_node) {
> +		if (genpd->provider == &np->fwnode) {

Presumably this would be "== of_fwnode_handle(np)) {" as well...

regards,
dan carpenter

> +			genpd_lock(genpd);
> +			genpd_power_off(genpd, false, 0);
> +			genpd_unlock(genpd);
> +		}
> +	}
> +	mutex_unlock(&gpd_list_lock);
> +}
Re: [PATCH 07/11] pmdomain: core: Export a common ->sync_state() helper for genpd providers
Posted by Ulf Hansson 7 months, 1 week ago
On Wed, 7 May 2025 at 18:23, Dan Carpenter <dan.carpenter@linaro.org> wrote:
>
> On Thu, Apr 17, 2025 at 04:25:05PM +0200, Ulf Hansson wrote:
> > +void of_genpd_sync_state(struct device *dev)
> > +{
> > +     struct device_node *np = dev->of_node;
> > +     struct generic_pm_domain *genpd;
> > +
> > +     if (!np)
> > +             return;
> > +
> > +     mutex_lock(&gpd_list_lock);
> > +     list_for_each_entry(genpd, &gpd_list, gpd_list_node) {
> > +             if (genpd->provider == &np->fwnode) {
>
> Presumably this would be "== of_fwnode_handle(np)) {" as well...

Yes, in fact there are a whole bunch of them in genpd. I am making
preparatory patch to change all of them.

>
> regards,
> dan carpenter

Thanks for reviewing!

Kind regards
Uffe
Re: [PATCH 07/11] pmdomain: core: Export a common ->sync_state() helper for genpd providers
Posted by Abel Vesa 7 months, 3 weeks ago
On 25-04-17 16:25:05, Ulf Hansson wrote:
> In some cases the typical platform driver that act as genpd provider, may
> need its own ->sync_state() callback to manage various things. In this
> regards, the provider most likely wants to allow its corresponding genpds
> to be powered-off.
> 
> For this reason, let's introduce a new genpd helper function,
> of_genpd_sync_state() that helps genpd provider drivers to achieve this.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

Reviewed-by: Abel Vesa <abel.vesa@linaro.org>