* [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state
@ 2026-04-10 10:40 Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 1/9] driver core: Enable suppliers to implement fine grained sync_state support Ulf Hansson
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel
Since the introduction [1] of the common sync_state support for pmdomains
(genpd), we have encountered a lot of various interesting problems. In most
cases the new behaviour of genpd triggered some weird platform specific bugs.
That said, in LPC in Tokyo me and Saravana hosted a session to walk through the
remaining limitations that we have found for genpd's sync state support. In
particular, we discussed the problems we have for the so-called onecell power
domain providers, where a single provider typically provides multiple
independent power domains, all with their own set of consumers.
Note that, onecell power domain providers are very common. It's being used by
many SoCs/platforms/technologies. To name a few:
SCMI, Qualcomm, NXP, Mediatek, Renesas, TI, etc.
Anyway, in these cases, the generic sync_state mechanism with fw_devlink isn't
fine grained enough, as we end up waiting for all consumers for all power
domains before the ->sync_callback gets called for the supplier/provider. In
other words, we may end up keeping unused power domains powered-on, for no good
reasons.
The series intends to fix this problem. Please have a look at the commit
messages for more details and help review/test!
Kind regards
Ulf Hansson
[1]
https://lore.kernel.org/all/20250701114733.636510-1-ulf.hansson@linaro.org/
Ulf Hansson (9):
driver core: Enable suppliers to implement fine grained sync_state
support
driver core: Add dev_set_drv_queue_sync_state()
pmdomain: core: Move genpd_get_from_provider()
pmdomain: core: Add initial fine grained sync_state support
pmdomain: core: Extend fine grained sync_state to more onecell
providers
pmdomain: core: Export a common function for ->queue_sync_state()
pmdomain: renesas: rcar-gen4-sysc: Drop GENPD_FLAG_NO_STAY_ON
pmdomain: renesas: rcar-sysc: Drop GENPD_FLAG_NO_STAY_ON
pmdomain: renesas: rmobile-sysc: Drop GENPD_FLAG_NO_STAY_ON
drivers/base/core.c | 7 +-
drivers/pmdomain/core.c | 205 ++++++++++++++++++----
drivers/pmdomain/renesas/rcar-gen4-sysc.c | 1 -
drivers/pmdomain/renesas/rcar-sysc.c | 1 -
drivers/pmdomain/renesas/rmobile-sysc.c | 3 +-
include/linux/device.h | 12 ++
include/linux/device/driver.h | 7 +
include/linux/pm_domain.h | 3 +
8 files changed, 197 insertions(+), 42 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/9] driver core: Enable suppliers to implement fine grained sync_state support
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 2/9] driver core: Add dev_set_drv_queue_sync_state() Ulf Hansson
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
The common sync_state support isn't fine grained enough for some types of
suppliers, like power domains for example. Especially when a supplier
provides multiple independent power domains, each with their own set of
consumers. In these cases we need to wait for all consumers for all the
provided power domains before invoking the supplier's ->sync_state().
To allow a more fine grained sync_state support to be implemented on per
supplier's driver basis, let's add a new optional callback. As soon as
there is an update worth to consider in regards to managing sync_state for
a supplier device, __device_links_queue_sync_state() invokes the callback.
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/base/core.c | 7 ++++++-
include/linux/device/driver.h | 7 +++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 09b98f02f559..4085a011d8ca 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1106,7 +1106,9 @@ int device_links_check_suppliers(struct device *dev)
* Queues a device for a sync_state() callback when the device links write lock
* isn't held. This allows the sync_state() execution flow to use device links
* APIs. The caller must ensure this function is called with
- * device_links_write_lock() held.
+ * device_links_write_lock() held. Note, if the optional queue_sync_state()
+ * callback has been assigned too, it gets called for every update to allowing a
+ * more fine grained support to be implemented on per supplier basis.
*
* This function does a get_device() to make sure the device is not freed while
* on this list.
@@ -1126,6 +1128,9 @@ static void __device_links_queue_sync_state(struct device *dev,
if (dev->state_synced)
return;
+ if (dev->driver && dev->driver->queue_sync_state)
+ dev->driver->queue_sync_state(dev);
+
list_for_each_entry(link, &dev->links.consumers, s_node) {
if (!device_link_test(link, DL_FLAG_MANAGED))
continue;
diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
index bbc67ec513ed..bc9ae1cbe03c 100644
--- a/include/linux/device/driver.h
+++ b/include/linux/device/driver.h
@@ -68,6 +68,12 @@ enum probe_type {
* be called at late_initcall_sync level. If the device has
* consumers that are never bound to a driver, this function
* will never get called until they do.
+ * @queue_sync_state: Similar to the ->sync_state() callback, but called to
+ * allow syncing device state to software state in a more fine
+ * grained way. It is called when there is an updated state that
+ * may be worth to consider for any of the consumers linked to
+ * this device. If implemented, the ->sync_state() callback is
+ * required too.
* @remove: Called when the device is removed from the system to
* unbind a device from this driver.
* @shutdown: Called at shut-down time to quiesce the device.
@@ -110,6 +116,7 @@ struct device_driver {
int (*probe) (struct device *dev);
void (*sync_state)(struct device *dev);
+ void (*queue_sync_state)(struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/9] driver core: Add dev_set_drv_queue_sync_state()
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 1/9] driver core: Enable suppliers to implement fine grained sync_state support Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 3/9] pmdomain: core: Move genpd_get_from_provider() Ulf Hansson
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
Similar to the dev_set_drv_sync_state() helper, let's add another one to
allow subsystem level code to set the ->queue_sync_state() callback for a
driver that has not already set it.
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
include/linux/device.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/linux/device.h b/include/linux/device.h
index e65d564f01cd..f812e70bdf22 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -994,6 +994,18 @@ static inline int dev_set_drv_sync_state(struct device *dev,
return 0;
}
+static inline int dev_set_drv_queue_sync_state(struct device *dev,
+ void (*fn)(struct device *dev))
+{
+ if (!dev || !dev->driver)
+ return 0;
+ if (dev->driver->queue_sync_state && dev->driver->queue_sync_state != fn)
+ return -EBUSY;
+ if (!dev->driver->queue_sync_state)
+ dev->driver->queue_sync_state = fn;
+ return 0;
+}
+
static inline void dev_set_removable(struct device *dev,
enum device_removable removable)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/9] pmdomain: core: Move genpd_get_from_provider()
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 1/9] driver core: Enable suppliers to implement fine grained sync_state support Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 2/9] driver core: Add dev_set_drv_queue_sync_state() Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 4/9] pmdomain: core: Add initial fine grained sync_state support Ulf Hansson
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
To prepare for subsequent changes and to avoid an unnecessary function
declaration, let's move genpd_get_from_provider() a bit earlier in the
code.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/pmdomain/core.c | 70 ++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 35 deletions(-)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 4d32fc676aaf..ad57846f02a3 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2664,6 +2664,41 @@ static bool genpd_present(const struct generic_pm_domain *genpd)
return ret;
}
+/**
+ * genpd_get_from_provider() - Look-up PM domain
+ * @genpdspec: OF phandle args to use for look-up
+ *
+ * Looks for a PM domain provider under the node specified by @genpdspec and if
+ * found, uses xlate function of the provider to map phandle args to a PM
+ * domain.
+ *
+ * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR()
+ * on failure.
+ */
+static struct generic_pm_domain *genpd_get_from_provider(
+ const struct of_phandle_args *genpdspec)
+{
+ struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
+ struct of_genpd_provider *provider;
+
+ if (!genpdspec)
+ return ERR_PTR(-EINVAL);
+
+ mutex_lock(&of_genpd_mutex);
+
+ /* Check if we have such a provider in our array */
+ list_for_each_entry(provider, &of_genpd_providers, link) {
+ if (provider->node == genpdspec->np)
+ genpd = provider->xlate(genpdspec, provider->data);
+ if (!IS_ERR(genpd))
+ break;
+ }
+
+ mutex_unlock(&of_genpd_mutex);
+
+ return genpd;
+}
+
static void genpd_sync_state(struct device *dev)
{
return of_genpd_sync_state(dev->of_node);
@@ -2889,41 +2924,6 @@ void of_genpd_del_provider(struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_genpd_del_provider);
-/**
- * genpd_get_from_provider() - Look-up PM domain
- * @genpdspec: OF phandle args to use for look-up
- *
- * Looks for a PM domain provider under the node specified by @genpdspec and if
- * found, uses xlate function of the provider to map phandle args to a PM
- * domain.
- *
- * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR()
- * on failure.
- */
-static struct generic_pm_domain *genpd_get_from_provider(
- const struct of_phandle_args *genpdspec)
-{
- struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
- struct of_genpd_provider *provider;
-
- if (!genpdspec)
- return ERR_PTR(-EINVAL);
-
- mutex_lock(&of_genpd_mutex);
-
- /* Check if we have such a provider in our array */
- list_for_each_entry(provider, &of_genpd_providers, link) {
- if (provider->node == genpdspec->np)
- genpd = provider->xlate(genpdspec, provider->data);
- if (!IS_ERR(genpd))
- break;
- }
-
- mutex_unlock(&of_genpd_mutex);
-
- return genpd;
-}
-
/**
* of_genpd_add_device() - Add a device to an I/O PM domain
* @genpdspec: OF phandle args to use for look-up PM domain
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 4/9] pmdomain: core: Add initial fine grained sync_state support
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
` (2 preceding siblings ...)
2026-04-10 10:40 ` [PATCH v2 3/9] pmdomain: core: Move genpd_get_from_provider() Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 5/9] pmdomain: core: Extend fine grained sync_state to more onecell providers Ulf Hansson
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
A onecell (#power-domain-cells = <1 or 2>; in DT) power domain provider
typically provides multiple independent power domains, each with their own
corresponding consumers. In these cases we have to wait for all consumers
for all the provided power domains before the ->sync_state() callback gets
called for the supplier.
In a first step to improve this, let's implement support for fine grained
sync_state support a per genpd basis by using the ->queue_sync_state()
callback. To take step by step, let's initially limit the improvement to
the internal genpd provider driver and to its corresponding genpd devices
for onecell providers.
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/pmdomain/core.c | 125 ++++++++++++++++++++++++++++++++++++++
include/linux/pm_domain.h | 1 +
2 files changed, 126 insertions(+)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index ad57846f02a3..783d6f981708 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2699,6 +2699,120 @@ static struct generic_pm_domain *genpd_get_from_provider(
return genpd;
}
+static bool genpd_should_wait_for_consumer(struct device_node *np)
+{
+ struct generic_pm_domain *genpd;
+ bool should_wait = false;
+
+ 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);
+
+ /* Clear the previous state before reevaluating. */
+ genpd->wait_for_consumer = false;
+
+ /*
+ * Unless there is at least one genpd for the provider
+ * that is being kept powered-on, we don't have to care
+ * about waiting for consumers.
+ */
+ if (genpd->stay_on)
+ should_wait = true;
+
+ genpd_unlock(genpd);
+ }
+ }
+ mutex_unlock(&gpd_list_lock);
+
+ return should_wait;
+}
+
+static void genpd_parse_for_consumer(struct device_node *sup,
+ struct device_node *con)
+{
+ struct generic_pm_domain *genpd;
+ int i;
+
+ for (i = 0; ; i++) {
+ struct of_phandle_args pd_args;
+
+ if (of_parse_phandle_with_args(con, "power-domains",
+ "#power-domain-cells",
+ i, &pd_args))
+ break;
+
+ /*
+ * The phandle must correspond to the supplier's genpd provider
+ * to be relevant else let's move to the next index.
+ */
+ if (sup != pd_args.np) {
+ of_node_put(pd_args.np);
+ continue;
+ }
+
+ mutex_lock(&gpd_list_lock);
+ genpd = genpd_get_from_provider(&pd_args);
+ if (!IS_ERR(genpd)) {
+ genpd_lock(genpd);
+ genpd->wait_for_consumer = true;
+ genpd_unlock(genpd);
+ }
+ mutex_unlock(&gpd_list_lock);
+
+ of_node_put(pd_args.np);
+ }
+}
+
+static void _genpd_queue_sync_state(struct device_node *np)
+{
+ struct generic_pm_domain *genpd;
+
+ 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);
+ if (genpd->stay_on && !genpd->wait_for_consumer) {
+ genpd->stay_on = false;
+ genpd_queue_power_off_work(genpd);
+ }
+ genpd_unlock(genpd);
+ }
+ }
+ mutex_unlock(&gpd_list_lock);
+}
+
+static void genpd_queue_sync_state(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct device_link *link;
+
+ if (!genpd_should_wait_for_consumer(np))
+ return;
+
+ list_for_each_entry(link, &dev->links.consumers, s_node) {
+ struct device *consumer = link->consumer;
+
+ if (!device_link_test(link, DL_FLAG_MANAGED))
+ continue;
+
+ if (link->status == DL_STATE_ACTIVE)
+ continue;
+
+ if (!consumer->of_node)
+ continue;
+
+ /*
+ * A consumer device has not been probed yet. Let's parse its
+ * device node for the power-domains property, to find out the
+ * genpds it may belong to and then prevent sync state for them.
+ */
+ genpd_parse_for_consumer(np, consumer->of_node);
+ }
+
+ _genpd_queue_sync_state(np);
+}
+
static void genpd_sync_state(struct device *dev)
{
return of_genpd_sync_state(dev->of_node);
@@ -3531,6 +3645,16 @@ static int genpd_provider_probe(struct device *dev)
return 0;
}
+static void genpd_provider_queue_sync_state(struct device *dev)
+{
+ struct generic_pm_domain *genpd = container_of(dev, struct generic_pm_domain, dev);
+
+ if (genpd->sync_state != GENPD_SYNC_STATE_ONECELL)
+ return;
+
+ genpd_queue_sync_state(dev);
+}
+
static void genpd_provider_sync_state(struct device *dev)
{
struct generic_pm_domain *genpd = container_of(dev, struct generic_pm_domain, dev);
@@ -3559,6 +3683,7 @@ static struct device_driver genpd_provider_drv = {
.name = "genpd_provider",
.bus = &genpd_provider_bus_type,
.probe = genpd_provider_probe,
+ .queue_sync_state = genpd_provider_queue_sync_state,
.sync_state = genpd_provider_sync_state,
.suppress_bind_attrs = true,
};
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index b299dc0128d6..7aa49721cde5 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -215,6 +215,7 @@ struct generic_pm_domain {
cpumask_var_t cpus; /* A cpumask of the attached CPUs */
bool synced_poweroff; /* A consumer needs a synced poweroff */
bool stay_on; /* Stay powered-on during boot. */
+ bool wait_for_consumer; /* Consumers awaits to be probed. */
enum genpd_sync_state sync_state; /* How sync_state is managed. */
int (*power_off)(struct generic_pm_domain *domain);
int (*power_on)(struct generic_pm_domain *domain);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 5/9] pmdomain: core: Extend fine grained sync_state to more onecell providers
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
` (3 preceding siblings ...)
2026-04-10 10:40 ` [PATCH v2 4/9] pmdomain: core: Add initial fine grained sync_state support Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 6/9] pmdomain: core: Export a common function for ->queue_sync_state() Ulf Hansson
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
A onecell power domain provider driver that we can assign a common
->sync_state() callback for, should be able to benefit from the improved
fine grained sync_state support in genpd. Therefore, let's also assign the
->queue_sync_state() callback for these types of provider drivers.
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/pmdomain/core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 783d6f981708..f11dc2110737 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2918,10 +2918,12 @@ int of_genpd_add_provider_onecell(struct device_node *np,
fwnode = of_fwnode_handle(np);
dev = get_dev_from_fwnode(fwnode);
- if (!dev)
+ if (!dev) {
sync_state = true;
- else
+ } else if (!dev_has_sync_state(dev)) {
dev_set_drv_sync_state(dev, genpd_sync_state);
+ dev_set_drv_queue_sync_state(dev, genpd_queue_sync_state);
+ }
put_device(dev);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 6/9] pmdomain: core: Export a common function for ->queue_sync_state()
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
` (4 preceding siblings ...)
2026-04-10 10:40 ` [PATCH v2 5/9] pmdomain: core: Extend fine grained sync_state to more onecell providers Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 7/9] pmdomain: renesas: rcar-gen4-sysc: Drop GENPD_FLAG_NO_STAY_ON Ulf Hansson
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
Along with of_genpd_sync_state() that genpd provider drivers may use to
manage sync_state, let's add and export of_genpd_queue_sync_state() for
those that may need it. It's expected that the genpd provider driver
assigns it's own ->queue_sync_state() callback and invoke the new helper
from there.
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/pmdomain/core.c | 14 +++++++++-----
include/linux/pm_domain.h | 2 ++
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index f11dc2110737..49e60cb67b3e 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2764,7 +2764,7 @@ static void genpd_parse_for_consumer(struct device_node *sup,
}
}
-static void _genpd_queue_sync_state(struct device_node *np)
+static void genpd_queue_sync_state(struct device_node *np)
{
struct generic_pm_domain *genpd;
@@ -2782,11 +2782,14 @@ static void _genpd_queue_sync_state(struct device_node *np)
mutex_unlock(&gpd_list_lock);
}
-static void genpd_queue_sync_state(struct device *dev)
+void of_genpd_queue_sync_state(struct device *dev)
{
struct device_node *np = dev->of_node;
struct device_link *link;
+ if (!np)
+ return;
+
if (!genpd_should_wait_for_consumer(np))
return;
@@ -2810,8 +2813,9 @@ static void genpd_queue_sync_state(struct device *dev)
genpd_parse_for_consumer(np, consumer->of_node);
}
- _genpd_queue_sync_state(np);
+ genpd_queue_sync_state(np);
}
+EXPORT_SYMBOL_GPL(of_genpd_queue_sync_state);
static void genpd_sync_state(struct device *dev)
{
@@ -2922,7 +2926,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
sync_state = true;
} else if (!dev_has_sync_state(dev)) {
dev_set_drv_sync_state(dev, genpd_sync_state);
- dev_set_drv_queue_sync_state(dev, genpd_queue_sync_state);
+ dev_set_drv_queue_sync_state(dev, of_genpd_queue_sync_state);
}
put_device(dev);
@@ -3654,7 +3658,7 @@ static void genpd_provider_queue_sync_state(struct device *dev)
if (genpd->sync_state != GENPD_SYNC_STATE_ONECELL)
return;
- genpd_queue_sync_state(dev);
+ of_genpd_queue_sync_state(dev);
}
static void genpd_provider_sync_state(struct device *dev)
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 7aa49721cde5..d428dd805c46 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -467,6 +467,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_queue_sync_state(struct device *dev);
void of_genpd_sync_state(struct device_node *np);
int genpd_dev_pm_attach(struct device *dev);
@@ -513,6 +514,7 @@ static inline int of_genpd_parse_idle_states(struct device_node *dn,
return -ENODEV;
}
+static inline void of_genpd_queue_sync_state(struct device *dev) {}
static inline void of_genpd_sync_state(struct device_node *np) {}
static inline int genpd_dev_pm_attach(struct device *dev)
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 7/9] pmdomain: renesas: rcar-gen4-sysc: Drop GENPD_FLAG_NO_STAY_ON
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
` (5 preceding siblings ...)
2026-04-10 10:40 ` [PATCH v2 6/9] pmdomain: core: Export a common function for ->queue_sync_state() Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 8/9] pmdomain: renesas: rcar-sysc: " Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 9/9] pmdomain: renesas: rmobile-sysc: " Ulf Hansson
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
Due to the new fine grained sync_state support for onecell genpd provider
drivers, we should no longer need use the legacy behaviour. Therefore,
let's drop GENPD_FLAG_NO_STAY_ON.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/pmdomain/renesas/rcar-gen4-sysc.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/pmdomain/renesas/rcar-gen4-sysc.c b/drivers/pmdomain/renesas/rcar-gen4-sysc.c
index 0c6c639a91d0..81b154da725f 100644
--- a/drivers/pmdomain/renesas/rcar-gen4-sysc.c
+++ b/drivers/pmdomain/renesas/rcar-gen4-sysc.c
@@ -251,7 +251,6 @@ static int __init rcar_gen4_sysc_pd_setup(struct rcar_gen4_sysc_pd *pd)
genpd->detach_dev = cpg_mssr_detach_dev;
}
- genpd->flags |= GENPD_FLAG_NO_STAY_ON;
genpd->power_off = rcar_gen4_sysc_pd_power_off;
genpd->power_on = rcar_gen4_sysc_pd_power_on;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 8/9] pmdomain: renesas: rcar-sysc: Drop GENPD_FLAG_NO_STAY_ON
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
` (6 preceding siblings ...)
2026-04-10 10:40 ` [PATCH v2 7/9] pmdomain: renesas: rcar-gen4-sysc: Drop GENPD_FLAG_NO_STAY_ON Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 9/9] pmdomain: renesas: rmobile-sysc: " Ulf Hansson
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
Due to the new fine grained sync_state support for onecell genpd provider
drivers, we should no longer need use the legacy behaviour. Therefore,
let's drop GENPD_FLAG_NO_STAY_ON.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/pmdomain/renesas/rcar-sysc.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/pmdomain/renesas/rcar-sysc.c b/drivers/pmdomain/renesas/rcar-sysc.c
index bd7bb9cbd9da..e4608c657629 100644
--- a/drivers/pmdomain/renesas/rcar-sysc.c
+++ b/drivers/pmdomain/renesas/rcar-sysc.c
@@ -241,7 +241,6 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
}
}
- genpd->flags |= GENPD_FLAG_NO_STAY_ON;
genpd->power_off = rcar_sysc_pd_power_off;
genpd->power_on = rcar_sysc_pd_power_on;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 9/9] pmdomain: renesas: rmobile-sysc: Drop GENPD_FLAG_NO_STAY_ON
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
` (7 preceding siblings ...)
2026-04-10 10:40 ` [PATCH v2 8/9] pmdomain: renesas: rcar-sysc: " Ulf Hansson
@ 2026-04-10 10:40 ` Ulf Hansson
8 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-04-10 10:40 UTC (permalink / raw)
To: Saravana Kannan, Rafael J . Wysocki, Greg Kroah-Hartman, linux-pm
Cc: Sudeep Holla, Cristian Marussi, Kevin Hilman, Stephen Boyd,
Marek Szyprowski, Bjorn Andersson, Abel Vesa, Peng Fan,
Tomi Valkeinen, Maulik Shah, Konrad Dybcio, Thierry Reding,
Jonathan Hunter, Geert Uytterhoeven, Dmitry Baryshkov,
Ulf Hansson, linux-arm-kernel, linux-kernel, Geert Uytterhoeven
Rmobile-sysc is not a onecell provider and didn't really needed
the GENPD_FLAG_NO_STAY_ON flag in the first place. Let's drop it.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/pmdomain/renesas/rmobile-sysc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/pmdomain/renesas/rmobile-sysc.c b/drivers/pmdomain/renesas/rmobile-sysc.c
index 93103ff33d6e..e36f5d763c91 100644
--- a/drivers/pmdomain/renesas/rmobile-sysc.c
+++ b/drivers/pmdomain/renesas/rmobile-sysc.c
@@ -100,8 +100,7 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
struct generic_pm_domain *genpd = &rmobile_pd->genpd;
struct dev_power_governor *gov = rmobile_pd->gov;
- genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP |
- GENPD_FLAG_NO_STAY_ON;
+ genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
genpd->attach_dev = cpg_mstp_attach_dev;
genpd->detach_dev = cpg_mstp_detach_dev;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-04-10 10:41 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-10 10:40 [PATCH v2 0/9] driver core / pmdomain: Add support for fined grained sync_state Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 1/9] driver core: Enable suppliers to implement fine grained sync_state support Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 2/9] driver core: Add dev_set_drv_queue_sync_state() Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 3/9] pmdomain: core: Move genpd_get_from_provider() Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 4/9] pmdomain: core: Add initial fine grained sync_state support Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 5/9] pmdomain: core: Extend fine grained sync_state to more onecell providers Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 6/9] pmdomain: core: Export a common function for ->queue_sync_state() Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 7/9] pmdomain: renesas: rcar-gen4-sysc: Drop GENPD_FLAG_NO_STAY_ON Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 8/9] pmdomain: renesas: rcar-sysc: " Ulf Hansson
2026-04-10 10:40 ` [PATCH v2 9/9] pmdomain: renesas: rmobile-sysc: " Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox