Commit 6c3b746f authored by Ulf Hansson's avatar Ulf Hansson
Browse files

pmdomain: core: Export a common ->sync_state() helper for genpd providers



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.

Suggested-by: default avatarSaravana Kannan <saravanak@google.com>
Reviewed-by: default avatarAbel Vesa <abel.vesa@linaro.org>
Tested-by: Hiago De Franco <hiago.franco@toradex.com> # Colibri iMX8X
Tested-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> # TI AM62A,Xilinx ZynqMP ZCU106
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Link: https://lore.kernel.org/r/20250701114733.636510-8-ulf.hansson@linaro.org
parent 18a3a510
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -3396,6 +3396,33 @@ int of_genpd_parse_idle_states(struct device_node *dn,
}
EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);

/**
 * of_genpd_sync_state() - A common sync_state function for genpd providers
 * @np: The device node the genpd provider is associated with.
 *
 * The @np that corresponds to a genpd provider may provide one or multiple
 * genpds. This function makes use @np to find the genpds that belongs to the
 * provider. For each genpd we try a power-off.
 */
void of_genpd_sync_state(struct device_node *np)
{
	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 == of_fwnode_handle(np)) {
			genpd_lock(genpd);
			genpd_power_off(genpd, false, 0);
			genpd_unlock(genpd);
		}
	}
	mutex_unlock(&gpd_list_lock);
}
EXPORT_SYMBOL_GPL(of_genpd_sync_state);

static int genpd_provider_probe(struct device *dev)
{
	return 0;
+3 −0
Original line number Diff line number Diff line
@@ -431,6 +431,7 @@ int of_genpd_remove_subdomain(const struct of_phandle_args *parent_spec,
struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
int of_genpd_parse_idle_states(struct device_node *dn,
			       struct genpd_power_state **states, int *n);
void of_genpd_sync_state(struct device_node *np);

int genpd_dev_pm_attach(struct device *dev);
struct device *genpd_dev_pm_attach_by_id(struct device *dev,
@@ -476,6 +477,8 @@ static inline int of_genpd_parse_idle_states(struct device_node *dn,
	return -ENODEV;
}

static inline void of_genpd_sync_state(struct device_node *np) {}

static inline int genpd_dev_pm_attach(struct device *dev)
{
	return 0;