linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
@ 2025-05-23 13:39 Ulf Hansson
  2025-05-23 13:39 ` [PATCH v2 01/21] pmdomain: core: Use of_fwnode_handle() Ulf Hansson
                   ` (23 more replies)
  0 siblings, 24 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:39 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

Changes in v2:
	- Well, quite a lot as I discovered various problems when doing
	additional testing of corner-case. I suggest re-review from scratch,
	even if I decided to keep some reviewed-by tags.
	- Added patches to allow some drivers that needs to align or opt-out
	from the new common behaviour in genpd.

If a PM domain (genpd) is powered-on during boot, there is probably a good
reason for it. Therefore it's known to be a bad idea to allow such genpd to be
powered-off before all of its consumer devices have been probed. This series
intends to fix this problem.

We have been discussing these issues at LKML and at various Linux-conferences
in the past. I have therefore tried to include the people I can recall being
involved, but I may have forgotten some (my apologies), feel free to loop them
in.

I have tested this with QEMU with a bunch of local test-drivers and DT nodes.
Let me know if you want me to share this code too.

Please help review and test!
Finally, a big thanks to Saravana for all the support!

Kind regards
Ulf Hansson


Saravana Kannan (1):
  driver core: Add dev_set_drv_sync_state()

Ulf Hansson (20):
  pmdomain: core: Use of_fwnode_handle()
  pmdomain: core: Add a bus and a driver for genpd providers
  pmdomain: core: Add the genpd->dev to the genpd provider bus
  pmdomain: core: Export a common ->sync_state() helper for genpd
    providers
  pmdomain: core: Prepare to add the common ->sync_state() support
  soc/tegra: pmc: Opt-out from genpd's common ->sync_state() support
  cpuidle: psci: Opt-out from genpd's common ->sync_state() support
  cpuidle: riscv-sbi: Opt-out from genpd's common ->sync_state() support
  pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
  pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
  firmware/pmdomain: xilinx: Move ->sync_state() support to firmware
    driver
  firmware: xilinx: Don't share zynqmp_pm_init_finalize()
  firmware: xilinx: Use of_genpd_sync_state()
  driver core: Export get_dev_from_fwnode()
  pmdomain: core: Add common ->sync_state() support for genpd providers
  pmdomain: core: Default to use of_genpd_sync_state() for genpd
    providers
  pmdomain: core: Leave powered-on genpds on until late_initcall_sync
  pmdomain: core: Leave powered-on genpds on until sync_state
  cpuidle: psci: Drop redundant sync_state support
  cpuidle: riscv-sbi: Drop redundant sync_state support

 drivers/base/core.c                         |   8 +-
 drivers/cpuidle/cpuidle-psci-domain.c       |  14 --
 drivers/cpuidle/cpuidle-riscv-sbi.c         |  14 --
 drivers/firmware/xilinx/zynqmp.c            |  18 +-
 drivers/pmdomain/core.c                     | 239 ++++++++++++++++++--
 drivers/pmdomain/qcom/rpmhpd.c              |   2 +
 drivers/pmdomain/qcom/rpmpd.c               |   2 +
 drivers/pmdomain/xilinx/zynqmp-pm-domains.c |  16 --
 drivers/soc/tegra/pmc.c                     |  26 ++-
 include/linux/device.h                      |  13 ++
 include/linux/firmware/xlnx-zynqmp.h        |   6 -
 include/linux/pm_domain.h                   |  17 ++
 12 files changed, 294 insertions(+), 81 deletions(-)

-- 
2.43.0



^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 01/21] pmdomain: core: Use of_fwnode_handle()
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
@ 2025-05-23 13:39 ` Ulf Hansson
  2025-06-11  6:07   ` Dhruva Gole
  2025-05-23 13:39 ` [PATCH v2 02/21] pmdomain: core: Add a bus and a driver for genpd providers Ulf Hansson
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:39 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

Let's avoid accessing the np->fwnode directly and use the common helper
of_fwnode_handle() instead.

Suggested-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index ff5c7f2b69ce..9a66b728fbbf 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2557,7 +2557,7 @@ static int genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
 	cp->node = of_node_get(np);
 	cp->data = data;
 	cp->xlate = xlate;
-	fwnode_dev_initialized(&np->fwnode, true);
+	fwnode_dev_initialized(of_fwnode_handle(np), true);
 
 	mutex_lock(&of_genpd_mutex);
 	list_add(&cp->link, &of_genpd_providers);
@@ -2727,7 +2727,7 @@ void of_genpd_del_provider(struct device_node *np)
 			 * so that the PM domain can be safely removed.
 			 */
 			list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
-				if (gpd->provider == &np->fwnode) {
+				if (gpd->provider == of_fwnode_handle(np)) {
 					gpd->has_provider = false;
 
 					if (gpd->opp_table) {
@@ -2737,7 +2737,7 @@ void of_genpd_del_provider(struct device_node *np)
 				}
 			}
 
-			fwnode_dev_initialized(&cp->node->fwnode, false);
+			fwnode_dev_initialized(of_fwnode_handle(cp->node), false);
 			list_del(&cp->link);
 			of_node_put(cp->node);
 			kfree(cp);
@@ -2916,7 +2916,7 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
 
 	mutex_lock(&gpd_list_lock);
 	list_for_each_entry_safe(gpd, tmp, &gpd_list, gpd_list_node) {
-		if (gpd->provider == &np->fwnode) {
+		if (gpd->provider == of_fwnode_handle(np)) {
 			ret = genpd_remove(gpd);
 			genpd = ret ? ERR_PTR(ret) : gpd;
 			break;
@@ -3269,7 +3269,7 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
 
 	genpd_state->power_on_latency_ns = 1000LL * exit_latency;
 	genpd_state->power_off_latency_ns = 1000LL * entry_latency;
-	genpd_state->fwnode = &state_node->fwnode;
+	genpd_state->fwnode = of_fwnode_handle(state_node);
 
 	return 0;
 }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 02/21] pmdomain: core: Add a bus and a driver for genpd providers
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
  2025-05-23 13:39 ` [PATCH v2 01/21] pmdomain: core: Use of_fwnode_handle() Ulf Hansson
@ 2025-05-23 13:39 ` Ulf Hansson
  2025-06-03  0:23   ` Saravana Kannan
  2025-05-23 13:40 ` [PATCH v2 03/21] pmdomain: core: Add the genpd->dev to the genpd provider bus Ulf Hansson
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:39 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

When we create a genpd via pm_genpd_init() we are initializing a
corresponding struct device for it, but we don't add the device to any
bus_type. It has not really been needed as the device is used as cookie to
help us manage OPP tables.

However, to prepare to make better use of the device let's add a new genpd
provider bus_type and a corresponding genpd provider driver. Subsequent
changes will make use of this.

Suggested-by: Saravana Kannan <saravanak@google.com>
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c | 89 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 9a66b728fbbf..da515350c65b 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -27,6 +27,11 @@
 /* Provides a unique ID for each genpd device */
 static DEFINE_IDA(genpd_ida);
 
+/* The parent for genpd_provider devices. */
+static struct device genpd_provider_bus = {
+	.init_name = "genpd_provider",
+};
+
 #define GENPD_RETRY_MAX_MS	250		/* Approximate */
 
 #define GENPD_DEV_CALLBACK(genpd, type, callback, dev)		\
@@ -44,6 +49,14 @@ static DEFINE_IDA(genpd_ida);
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
+#define to_genpd_provider_drv(d) container_of(d, struct genpd_provider_drv, drv)
+
+struct genpd_provider_drv {
+	struct device_driver drv;
+	int (*probe)(struct device *dev);
+	void (*remove)(struct device *dev);
+};
+
 struct genpd_lock_ops {
 	void (*lock)(struct generic_pm_domain *genpd);
 	void (*lock_nested)(struct generic_pm_domain *genpd, int depth);
@@ -2225,6 +2238,26 @@ static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
 	return 0;
 }
 
+static int genpd_provider_bus_probe(struct device *dev)
+{
+	struct genpd_provider_drv *drv = to_genpd_provider_drv(dev->driver);
+
+	return drv->probe(dev);
+}
+
+static void genpd_provider_bus_remove(struct device *dev)
+{
+	struct genpd_provider_drv *drv = to_genpd_provider_drv(dev->driver);
+
+	drv->remove(dev);
+}
+
+static const struct bus_type genpd_provider_bus_type = {
+	.name		= "genpd_provider",
+	.probe		= genpd_provider_bus_probe,
+	.remove		= genpd_provider_bus_remove,
+};
+
 static void genpd_provider_release(struct device *dev)
 {
 	/* nothing to be done here */
@@ -2262,6 +2295,8 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
 	genpd->gd = gd;
 	device_initialize(&genpd->dev);
 	genpd->dev.release = genpd_provider_release;
+	genpd->dev.bus = &genpd_provider_bus_type;
+	genpd->dev.parent = &genpd_provider_bus;
 
 	if (!genpd_is_dev_name_fw(genpd)) {
 		dev_set_name(&genpd->dev, "%s", genpd->name);
@@ -3355,9 +3390,61 @@ int of_genpd_parse_idle_states(struct device_node *dn,
 }
 EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
 
+static int genpd_provider_probe(struct device *dev)
+{
+	return 0;
+}
+
+static void genpd_provider_remove(struct device *dev)
+{
+}
+
+static void genpd_provider_sync_state(struct device *dev)
+{
+}
+
+static struct genpd_provider_drv genpd_provider_drv = {
+	.drv = {
+		.name = "genpd_provider",
+		.bus = &genpd_provider_bus_type,
+		.sync_state = genpd_provider_sync_state,
+		.suppress_bind_attrs = true,
+	},
+	.probe = genpd_provider_probe,
+	.remove = genpd_provider_remove,
+};
+
 static int __init genpd_bus_init(void)
 {
-	return bus_register(&genpd_bus_type);
+	int ret;
+
+	ret = device_register(&genpd_provider_bus);
+	if (ret) {
+		put_device(&genpd_provider_bus);
+		return ret;
+	}
+
+	ret = bus_register(&genpd_provider_bus_type);
+	if (ret)
+		goto err_dev;
+
+	ret = bus_register(&genpd_bus_type);
+	if (ret)
+		goto err_prov_bus;
+
+	ret = driver_register(&genpd_provider_drv.drv);
+	if (ret)
+		goto err_bus;
+
+	return 0;
+
+err_bus:
+	bus_unregister(&genpd_bus_type);
+err_prov_bus:
+	bus_unregister(&genpd_provider_bus_type);
+err_dev:
+	device_unregister(&genpd_provider_bus);
+	return ret;
 }
 core_initcall(genpd_bus_init);
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 03/21] pmdomain: core: Add the genpd->dev to the genpd provider bus
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
  2025-05-23 13:39 ` [PATCH v2 01/21] pmdomain: core: Use of_fwnode_handle() Ulf Hansson
  2025-05-23 13:39 ` [PATCH v2 02/21] pmdomain: core: Add a bus and a driver for genpd providers Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 04/21] pmdomain: core: Export a common ->sync_state() helper for genpd providers Ulf Hansson
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

To take the next step for a more common handling of the genpd providers,
let's add the genpd->dev to the genpd provider bus when registering a genpd
OF provider.

Beyond this, the corresponding genpd provider driver's ->probe(),
->remove() and ->sync_state() callbacks starts to be invoked. However,
let's leave those callbacks as empty functions for now. Instead, subsequent
changes will implement them.

Suggested-by: Saravana Kannan <saravanak@google.com>
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index da515350c65b..8d5dca22e35e 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2637,11 +2637,17 @@ int of_genpd_add_provider_simple(struct device_node *np,
 
 	genpd->dev.of_node = np;
 
+	ret = device_add(&genpd->dev);
+	if (ret)
+		return ret;
+
 	/* Parse genpd OPP table */
 	if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
 		ret = dev_pm_opp_of_add_table(&genpd->dev);
-		if (ret)
-			return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n");
+		if (ret) {
+			dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n");
+			goto err_del;
+		}
 
 		/*
 		 * Save table for faster processing while setting performance
@@ -2652,19 +2658,22 @@ int of_genpd_add_provider_simple(struct device_node *np,
 	}
 
 	ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
-	if (ret) {
-		if (genpd->opp_table) {
-			dev_pm_opp_put_opp_table(genpd->opp_table);
-			dev_pm_opp_of_remove_table(&genpd->dev);
-		}
-
-		return ret;
-	}
+	if (ret)
+		goto err_opp;
 
 	genpd->provider = &np->fwnode;
 	genpd->has_provider = true;
 
 	return 0;
+
+err_opp:
+	if (genpd->opp_table) {
+		dev_pm_opp_put_opp_table(genpd->opp_table);
+		dev_pm_opp_of_remove_table(&genpd->dev);
+	}
+err_del:
+	device_del(&genpd->dev);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple);
 
@@ -2696,12 +2705,17 @@ int of_genpd_add_provider_onecell(struct device_node *np,
 
 		genpd->dev.of_node = np;
 
+		ret = device_add(&genpd->dev);
+		if (ret)
+			goto error;
+
 		/* Parse genpd OPP table */
 		if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) {
 			ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i);
 			if (ret) {
 				dev_err_probe(&genpd->dev, ret,
 					      "Failed to add OPP table for index %d\n", i);
+				device_del(&genpd->dev);
 				goto error;
 			}
 
@@ -2737,6 +2751,8 @@ int of_genpd_add_provider_onecell(struct device_node *np,
 			dev_pm_opp_put_opp_table(genpd->opp_table);
 			dev_pm_opp_of_remove_table(&genpd->dev);
 		}
+
+		device_del(&genpd->dev);
 	}
 
 	return ret;
@@ -2769,6 +2785,8 @@ void of_genpd_del_provider(struct device_node *np)
 						dev_pm_opp_put_opp_table(gpd->opp_table);
 						dev_pm_opp_of_remove_table(&gpd->dev);
 					}
+
+					device_del(&gpd->dev);
 				}
 			}
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 04/21] pmdomain: core: Export a common ->sync_state() helper for genpd providers
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (2 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 03/21] pmdomain: core: Add the genpd->dev to the genpd provider bus Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 05/21] pmdomain: core: Prepare to add the common ->sync_state() support Ulf Hansson
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

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: Saravana Kannan <saravanak@google.com>
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Changed the in-parameter from a struct device* to a stuct device_node*

---
 drivers/pmdomain/core.c   | 27 +++++++++++++++++++++++++++
 include/linux/pm_domain.h |  3 +++
 2 files changed, 30 insertions(+)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 8d5dca22e35e..4047af5a275d 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -3408,6 +3408,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;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 0b18160901a2..3578196e6626 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -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;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 05/21] pmdomain: core: Prepare to add the common ->sync_state() support
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (3 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 04/21] pmdomain: core: Export a common ->sync_state() helper for genpd providers Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 06/21] soc/tegra: pmc: Opt-out from genpd's " Ulf Hansson
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

Before we can implement the common ->sync_state() support in genpd, we need
to allow a few specific genpd providers to opt out from the new behaviour.

Let's introduce GENPD_FLAG_NO_SYNC_STATE as a new genpd config option, to
allow providers to opt out.

Suggested-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 include/linux/pm_domain.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 3578196e6626..9329554b9c4a 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -104,6 +104,11 @@ struct dev_pm_domain_list {
  * GENPD_FLAG_DEV_NAME_FW:	Instructs genpd to generate an unique device name
  *				using ida. It is used by genpd providers which
  *				get their genpd-names directly from FW.
+ *
+ * GENPD_FLAG_NO_SYNC_STATE:	The ->sync_state() support is implemented in a
+ *				genpd provider specific way, likely through a
+ *				parent device node. This flag makes genpd to
+ *				skip its internal support for this.
  */
 #define GENPD_FLAG_PM_CLK	 (1U << 0)
 #define GENPD_FLAG_IRQ_SAFE	 (1U << 1)
@@ -114,6 +119,7 @@ struct dev_pm_domain_list {
 #define GENPD_FLAG_MIN_RESIDENCY (1U << 6)
 #define GENPD_FLAG_OPP_TABLE_FW	 (1U << 7)
 #define GENPD_FLAG_DEV_NAME_FW	 (1U << 8)
+#define GENPD_FLAG_NO_SYNC_STATE (1U << 9)
 
 enum gpd_status {
 	GENPD_STATE_ON = 0,	/* PM domain is on */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 06/21] soc/tegra: pmc: Opt-out from genpd's common ->sync_state() support
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (4 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 05/21] pmdomain: core: Prepare to add the common ->sync_state() support Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 07/21] cpuidle: psci: " Ulf Hansson
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

Tegra implements its own specific ->sync_state() callback for the genpd
providers. Let's set the GENPD_FLAG_NO_SYNC_STATE to inform genpd about it.

Moreover, let's call of_genpd_sync_state() to make sure genpd tries to
power off unused PM domains.

Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/soc/tegra/pmc.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 51b9d852bb6a..ef486387ccd9 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -418,7 +418,6 @@ struct tegra_pmc_soc {
  * @irq: chip implementation for the IRQ domain
  * @clk_nb: pclk clock changes handler
  * @core_domain_state_synced: flag marking the core domain's state as synced
- * @core_domain_registered: flag marking the core domain as registered
  * @wake_type_level_map: Bitmap indicating level type for non-dual edge wakes
  * @wake_type_dual_edge_map: Bitmap indicating if a wake is dual-edge or not
  * @wake_sw_status_map: Bitmap to hold raw status of wakes without mask
@@ -462,7 +461,6 @@ struct tegra_pmc {
 	struct notifier_block clk_nb;
 
 	bool core_domain_state_synced;
-	bool core_domain_registered;
 
 	unsigned long *wake_type_level_map;
 	unsigned long *wake_type_dual_edge_map;
@@ -1297,6 +1295,7 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 
 	pg->id = id;
 	pg->genpd.name = np->name;
+	pg->genpd.flags = GENPD_FLAG_NO_SYNC_STATE;
 	pg->genpd.power_off = tegra_genpd_power_off;
 	pg->genpd.power_on = tegra_genpd_power_on;
 	pg->pmc = pmc;
@@ -1406,6 +1405,7 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
 		return -ENOMEM;
 
 	genpd->name = "core";
+	genpd->flags = GENPD_FLAG_NO_SYNC_STATE;
 	genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state;
 
 	err = devm_pm_opp_set_regulators(pmc->dev, rname);
@@ -1425,8 +1425,6 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
 		goto remove_genpd;
 	}
 
-	pmc->core_domain_registered = true;
-
 	return 0;
 
 remove_genpd:
@@ -4262,8 +4260,25 @@ static const struct of_device_id tegra_pmc_match[] = {
 
 static void tegra_pmc_sync_state(struct device *dev)
 {
+	struct device_node *np, *child;
 	int err;
 
+	np = of_get_child_by_name(dev->of_node, "powergates");
+	if (!np)
+		return;
+
+	for_each_child_of_node(np, child)
+		of_genpd_sync_state(child);
+
+	of_node_put(np);
+
+	np = of_get_child_by_name(dev->of_node, "core-domain");
+	if (!np)
+		return;
+
+	of_genpd_sync_state(np);
+	of_node_put(np);
+
 	/*
 	 * Newer device-trees have power domains, but we need to prepare all
 	 * device drivers with runtime PM and OPP support first, otherwise
@@ -4277,9 +4292,6 @@ static void tegra_pmc_sync_state(struct device *dev)
 	 * no dependencies that will block the state syncing. We shouldn't
 	 * mark the domain as synced in this case.
 	 */
-	if (!pmc->core_domain_registered)
-		return;
-
 	pmc->core_domain_state_synced = true;
 
 	/* this is a no-op if core regulator isn't used */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 07/21] cpuidle: psci: Opt-out from genpd's common ->sync_state() support
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (5 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 06/21] soc/tegra: pmc: Opt-out from genpd's " Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 08/21] cpuidle: riscv-sbi: " Ulf Hansson
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

The cpuidle-psci-domain implements its own specific ->sync_state()
callback. Let's set the GENPD_FLAG_NO_SYNC_STATE to inform genpd about it.

Moreover, let's call of_genpd_sync_state() to make sure genpd tries to
power off unused PM domains.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/cpuidle/cpuidle-psci-domain.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
index 2041f59116ce..b880ce2df8b5 100644
--- a/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -63,7 +63,8 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
 	if (!pd_provider)
 		goto free_pd;
 
-	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;
+	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN |
+		     GENPD_FLAG_NO_SYNC_STATE;
 
 	/*
 	 * Allow power off when OSI has been successfully enabled.
@@ -128,11 +129,16 @@ static void psci_pd_remove(void)
 
 static void psci_cpuidle_domain_sync_state(struct device *dev)
 {
+	struct psci_pd_provider *pd_provider;
+
 	/*
 	 * All devices have now been attached/probed to the PM domain topology,
 	 * hence it's fine to allow domain states to be picked.
 	 */
 	psci_pd_allow_domain_state = true;
+
+	list_for_each_entry(pd_provider, &psci_pd_providers, link)
+		of_genpd_sync_state(pd_provider->node);
 }
 
 static const struct of_device_id psci_of_match[] = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 08/21] cpuidle: riscv-sbi: Opt-out from genpd's common ->sync_state() support
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (6 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 07/21] cpuidle: psci: " Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-08-10 21:12   ` patchwork-bot+linux-riscv
  2025-05-23 13:40 ` [PATCH v2 09/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state() Ulf Hansson
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel, Anup Patel, linux-riscv

The riscv-sbi-domain implements its own specific ->sync_state() callback.
Let's set the GENPD_FLAG_NO_SYNC_STATE to inform genpd about it.

Moreover, let's call of_genpd_sync_state() to make sure genpd tries to
power off unused PM domains.

Cc: Anup Patel <anup@brainfault.org>
Cc: linux-riscv@lists.infradead.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/cpuidle/cpuidle-riscv-sbi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
index 0fe1ece9fbdc..83d58d00872f 100644
--- a/drivers/cpuidle/cpuidle-riscv-sbi.c
+++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
@@ -347,11 +347,16 @@ static int sbi_cpuidle_init_cpu(struct device *dev, int cpu)
 
 static void sbi_cpuidle_domain_sync_state(struct device *dev)
 {
+	struct sbi_pd_provider *pd_provider;
+
 	/*
 	 * All devices have now been attached/probed to the PM domain
 	 * topology, hence it's fine to allow domain states to be picked.
 	 */
 	sbi_cpuidle_pd_allow_domain_state = true;
+
+	list_for_each_entry(pd_provider, &sbi_pd_providers, link)
+		of_genpd_sync_state(pd_provider->node);
 }
 
 #ifdef CONFIG_DT_IDLE_GENPD
@@ -396,7 +401,8 @@ static int sbi_pd_init(struct device_node *np)
 	if (!pd_provider)
 		goto free_pd;
 
-	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;
+	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN |
+		     GENPD_FLAG_NO_SYNC_STATE;
 
 	/* Allow power off when OSI is available. */
 	if (sbi_cpuidle_use_osi)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 09/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (7 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 08/21] cpuidle: riscv-sbi: " Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 19:42   ` Konrad Dybcio
  2025-05-23 13:40 ` [PATCH v2 10/21] " Ulf Hansson
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

To make sure genpd tries to power off unused PM domains, let's call
of_genpd_sync_state() from our own ->sync_state() callback.

Cc: Bjorn Andersson <andersson@kernel.org>
Cc: Konrad Dybcio <konradybcio@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/qcom/rpmpd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c
index 0be6b3026e3a..833c46944600 100644
--- a/drivers/pmdomain/qcom/rpmpd.c
+++ b/drivers/pmdomain/qcom/rpmpd.c
@@ -1144,6 +1144,8 @@ static void rpmpd_sync_state(struct device *dev)
 	unsigned int i;
 	int ret;
 
+	of_genpd_sync_state(dev->of_node);
+
 	mutex_lock(&rpmpd_lock);
 	for (i = 0; i < desc->num_pds; i++) {
 		pd = rpmpds[i];
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 10/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (8 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 09/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state() Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 11/21] firmware/pmdomain: xilinx: Move ->sync_state() support to firmware driver Ulf Hansson
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

To make sure genpd tries to power off unused PM domains, let's call
of_genpd_sync_state() from our own ->sync_state() callback.

Cc: Bjorn Andersson <andersson@kernel.org>
Cc: Konrad Dybcio <konradybcio@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/qcom/rpmhpd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
index 078323b85b56..d9ad6a94b3ab 100644
--- a/drivers/pmdomain/qcom/rpmhpd.c
+++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -1027,6 +1027,8 @@ static void rpmhpd_sync_state(struct device *dev)
 	unsigned int i;
 	int ret;
 
+	of_genpd_sync_state(dev->of_node);
+
 	mutex_lock(&rpmhpd_lock);
 	for (i = 0; i < desc->num_pds; i++) {
 		pd = rpmhpds[i];
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 11/21] firmware/pmdomain: xilinx: Move ->sync_state() support to firmware driver
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (9 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 10/21] " Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 12/21] firmware: xilinx: Don't share zynqmp_pm_init_finalize() Ulf Hansson
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel, Michael Tretter

Rather than having the genpd provider to add device_links for each device
that gets attached, to implement the ->sync_state() support, let's rely on
fw_devlink to do this for us.

In this way, we can simplify the code by moving the ->sync_state() callback
into the firmware driver, so let's do that.

Cc: Michael Tretter <m.tretter@pengutronix.de>
Cc: Michal Simek <michal.simek@amd.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/firmware/xilinx/zynqmp.c            | 10 ++++++++++
 drivers/pmdomain/xilinx/zynqmp-pm-domains.c | 16 ----------------
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 7356e860e65c..a91a0191c689 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -2100,6 +2100,15 @@ static void zynqmp_firmware_remove(struct platform_device *pdev)
 	platform_device_unregister(em_dev);
 }
 
+static void zynqmp_firmware_sync_state(struct device *dev)
+{
+	if (!of_device_is_compatible(dev->of_node, "xlnx,zynqmp-firmware"))
+		return;
+
+	if (zynqmp_pm_init_finalize())
+		dev_warn(dev, "failed to release power management to firmware\n");
+}
+
 static const struct of_device_id zynqmp_firmware_of_match[] = {
 	{.compatible = "xlnx,zynqmp-firmware"},
 	{.compatible = "xlnx,versal-firmware"},
@@ -2112,6 +2121,7 @@ static struct platform_driver zynqmp_firmware_driver = {
 		.name = "zynqmp_firmware",
 		.of_match_table = zynqmp_firmware_of_match,
 		.dev_groups = zynqmp_firmware_groups,
+		.sync_state = zynqmp_firmware_sync_state,
 	},
 	.probe = zynqmp_firmware_probe,
 	.remove = zynqmp_firmware_remove,
diff --git a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
index d579220a4500..b5aedd6e33ad 100644
--- a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
+++ b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
@@ -153,14 +153,8 @@ static int zynqmp_gpd_attach_dev(struct generic_pm_domain *domain,
 				 struct device *dev)
 {
 	struct zynqmp_pm_domain *pd = to_zynqmp_pm_domain(domain);
-	struct device_link *link;
 	int ret;
 
-	link = device_link_add(dev, &domain->dev, DL_FLAG_SYNC_STATE_ONLY);
-	if (!link)
-		dev_dbg(&domain->dev, "failed to create device link for %s\n",
-			dev_name(dev));
-
 	/* If this is not the first device to attach there is nothing to do */
 	if (domain->device_count)
 		return 0;
@@ -298,19 +292,9 @@ static void zynqmp_gpd_remove(struct platform_device *pdev)
 	of_genpd_del_provider(pdev->dev.parent->of_node);
 }
 
-static void zynqmp_gpd_sync_state(struct device *dev)
-{
-	int ret;
-
-	ret = zynqmp_pm_init_finalize();
-	if (ret)
-		dev_warn(dev, "failed to release power management to firmware\n");
-}
-
 static struct platform_driver zynqmp_power_domain_driver = {
 	.driver	= {
 		.name = "zynqmp_power_controller",
-		.sync_state = zynqmp_gpd_sync_state,
 	},
 	.probe = zynqmp_gpd_probe,
 	.remove = zynqmp_gpd_remove,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 12/21] firmware: xilinx: Don't share zynqmp_pm_init_finalize()
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (10 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 11/21] firmware/pmdomain: xilinx: Move ->sync_state() support to firmware driver Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 13/21] firmware: xilinx: Use of_genpd_sync_state() Ulf Hansson
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

As there no longer any users outside the zynqmp firmware driver of
zynqmp_pm_init_finalize(), let's turn into a local static function.

Cc: Michal Simek <michal.simek@amd.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/firmware/xilinx/zynqmp.c     | 3 +--
 include/linux/firmware/xlnx-zynqmp.h | 6 ------
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index a91a0191c689..87ddbb7d11c2 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1299,11 +1299,10 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write);
  * This API function is to be used for notify the power management controller
  * about the completed power management initialization.
  */
-int zynqmp_pm_init_finalize(void)
+static int zynqmp_pm_init_finalize(void)
 {
 	return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, NULL, 0);
 }
-EXPORT_SYMBOL_GPL(zynqmp_pm_init_finalize);
 
 /**
  * zynqmp_pm_set_suspend_mode()	- Set system suspend mode
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 6d4dbc196b93..ae48d619c4e0 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -585,7 +585,6 @@ int zynqmp_pm_reset_assert(const u32 reset,
 int zynqmp_pm_reset_get_status(const u32 reset, u32 *status);
 unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode);
 int zynqmp_pm_bootmode_write(u32 ps_mode);
-int zynqmp_pm_init_finalize(void);
 int zynqmp_pm_set_suspend_mode(u32 mode);
 int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
 			   const u32 qos, const enum zynqmp_pm_request_ack ack);
@@ -746,11 +745,6 @@ static inline int zynqmp_pm_bootmode_write(u32 ps_mode)
 	return -ENODEV;
 }
 
-static inline int zynqmp_pm_init_finalize(void)
-{
-	return -ENODEV;
-}
-
 static inline int zynqmp_pm_set_suspend_mode(u32 mode)
 {
 	return -ENODEV;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 13/21] firmware: xilinx: Use of_genpd_sync_state()
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (11 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 12/21] firmware: xilinx: Don't share zynqmp_pm_init_finalize() Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 14/21] driver core: Export get_dev_from_fwnode() Ulf Hansson
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

To make sure genpd tries to power off unused PM domains, let's call
of_genpd_sync_state() from our own ->sync_state() callback.

Cc: Michal Simek <michal.simek@amd.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/firmware/xilinx/zynqmp.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 87ddbb7d11c2..02da3e48bc8f 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/hashtable.h>
@@ -2101,9 +2102,13 @@ static void zynqmp_firmware_remove(struct platform_device *pdev)
 
 static void zynqmp_firmware_sync_state(struct device *dev)
 {
-	if (!of_device_is_compatible(dev->of_node, "xlnx,zynqmp-firmware"))
+	struct device_node *np = dev->of_node;
+
+	if (!of_device_is_compatible(np, "xlnx,zynqmp-firmware"))
 		return;
 
+	of_genpd_sync_state(np);
+
 	if (zynqmp_pm_init_finalize())
 		dev_warn(dev, "failed to release power management to firmware\n");
 }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 14/21] driver core: Export get_dev_from_fwnode()
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (12 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 13/21] firmware: xilinx: Use of_genpd_sync_state() Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 15/21] pmdomain: core: Add common ->sync_state() support for genpd providers Ulf Hansson
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

It has turned out get_dev_from_fwnode() is useful at a few other places
outside of the driver core, as in gpiolib.c for example. Therefore let's
make it available as a common helper function.

Suggested-by: Saravana Kannan <saravanak@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/core.c    | 8 ++++++--
 include/linux/device.h | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index d2f9d3a59d6b..51512ab8a6e9 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1881,8 +1881,6 @@ static void fw_devlink_unblock_consumers(struct device *dev)
 	device_links_write_unlock();
 }
 
-#define get_dev_from_fwnode(fwnode)	get_device((fwnode)->dev)
-
 static bool fwnode_init_without_drv(struct fwnode_handle *fwnode)
 {
 	struct device *dev;
@@ -5255,6 +5253,12 @@ void device_set_node(struct device *dev, struct fwnode_handle *fwnode)
 }
 EXPORT_SYMBOL_GPL(device_set_node);
 
+struct device *get_dev_from_fwnode(struct fwnode_handle *fwnode)
+{
+	return get_device((fwnode)->dev);
+}
+EXPORT_SYMBOL_GPL(get_dev_from_fwnode);
+
 int device_match_name(struct device *dev, const void *name)
 {
 	return sysfs_streq(dev_name(dev), name);
diff --git a/include/linux/device.h b/include/linux/device.h
index 79e49fe494b7..f6ca813eebbe 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1086,6 +1086,7 @@ void device_set_node(struct device *dev, struct fwnode_handle *fwnode);
 int device_add_of_node(struct device *dev, struct device_node *of_node);
 void device_remove_of_node(struct device *dev);
 void device_set_of_node_from_dev(struct device *dev, const struct device *dev2);
+struct device *get_dev_from_fwnode(struct fwnode_handle *fwnode);
 
 static inline struct device_node *dev_of_node(struct device *dev)
 {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 15/21] pmdomain: core: Add common ->sync_state() support for genpd providers
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (13 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 14/21] driver core: Export get_dev_from_fwnode() Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 16/21] driver core: Add dev_set_drv_sync_state() Ulf Hansson
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

If the genpd provider's fwnode doesn't have an associated struct device
with it, we can make use of the generic genpd->dev and it corresponding
driver internally in genpd to manage ->sync_state().

More precisely, while adding a genpd OF provider let's check if the fwnode
has a device and if not, make the preparation to handle ->sync_state()
internally through the genpd_provider_driver and the genpd_provider_bus.

Note that, genpd providers may opt out from this behaviour by setting the
GENPD_FLAG_NO_SYNC_STATE config options for the genpds in question.

Suggested-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c   | 52 +++++++++++++++++++++++++++++++++++++--
 include/linux/pm_domain.h |  7 ++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 4047af5a275d..c094ccbba151 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -189,6 +189,7 @@ static const struct genpd_lock_ops genpd_raw_spin_ops = {
 #define genpd_is_rpm_always_on(genpd)	(genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
 #define genpd_is_opp_table_fw(genpd)	(genpd->flags & GENPD_FLAG_OPP_TABLE_FW)
 #define genpd_is_dev_name_fw(genpd)	(genpd->flags & GENPD_FLAG_DEV_NAME_FW)
+#define genpd_is_no_sync_state(genpd)	(genpd->flags & GENPD_FLAG_NO_SYNC_STATE)
 
 static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
 		const struct generic_pm_domain *genpd)
@@ -2374,6 +2375,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
 	INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
 	atomic_set(&genpd->sd_count, 0);
 	genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON;
+	genpd->sync_state = GENPD_SYNC_STATE_OFF;
 	genpd->device_count = 0;
 	genpd->provider = NULL;
 	genpd->device_id = -ENXIO;
@@ -2627,6 +2629,8 @@ static bool genpd_present(const struct generic_pm_domain *genpd)
 int of_genpd_add_provider_simple(struct device_node *np,
 				 struct generic_pm_domain *genpd)
 {
+	struct fwnode_handle *fwnode;
+	struct device *dev;
 	int ret;
 
 	if (!np || !genpd)
@@ -2637,6 +2641,15 @@ int of_genpd_add_provider_simple(struct device_node *np,
 
 	genpd->dev.of_node = np;
 
+	fwnode = of_fwnode_handle(np);
+	dev = get_dev_from_fwnode(fwnode);
+	if (!dev && !genpd_is_no_sync_state(genpd)) {
+		genpd->sync_state = GENPD_SYNC_STATE_SIMPLE;
+		device_set_node(&genpd->dev, fwnode);
+	}
+
+	put_device(dev);
+
 	ret = device_add(&genpd->dev);
 	if (ret)
 		return ret;
@@ -2661,7 +2674,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
 	if (ret)
 		goto err_opp;
 
-	genpd->provider = &np->fwnode;
+	genpd->provider = fwnode;
 	genpd->has_provider = true;
 
 	return 0;
@@ -2686,8 +2699,11 @@ int of_genpd_add_provider_onecell(struct device_node *np,
 				  struct genpd_onecell_data *data)
 {
 	struct generic_pm_domain *genpd;
+	struct fwnode_handle *fwnode;
+	struct device *dev;
 	unsigned int i;
 	int ret = -EINVAL;
+	bool sync_state = false;
 
 	if (!np || !data)
 		return -EINVAL;
@@ -2695,6 +2711,13 @@ int of_genpd_add_provider_onecell(struct device_node *np,
 	if (!data->xlate)
 		data->xlate = genpd_xlate_onecell;
 
+	fwnode = of_fwnode_handle(np);
+	dev = get_dev_from_fwnode(fwnode);
+	if (!dev)
+		sync_state = true;
+
+	put_device(dev);
+
 	for (i = 0; i < data->num_domains; i++) {
 		genpd = data->domains[i];
 
@@ -2705,6 +2728,12 @@ int of_genpd_add_provider_onecell(struct device_node *np,
 
 		genpd->dev.of_node = np;
 
+		if (sync_state && !genpd_is_no_sync_state(genpd)) {
+			genpd->sync_state = GENPD_SYNC_STATE_ONECELL;
+			device_set_node(&genpd->dev, fwnode);
+			sync_state = false;
+		}
+
 		ret = device_add(&genpd->dev);
 		if (ret)
 			goto error;
@@ -2727,7 +2756,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
 			WARN_ON(IS_ERR(genpd->opp_table));
 		}
 
-		genpd->provider = &np->fwnode;
+		genpd->provider = fwnode;
 		genpd->has_provider = true;
 	}
 
@@ -3446,6 +3475,25 @@ static void genpd_provider_remove(struct device *dev)
 
 static void genpd_provider_sync_state(struct device *dev)
 {
+	struct generic_pm_domain *genpd = container_of(dev, struct generic_pm_domain, dev);
+
+	switch (genpd->sync_state) {
+	case GENPD_SYNC_STATE_OFF:
+		break;
+
+	case GENPD_SYNC_STATE_ONECELL:
+		of_genpd_sync_state(dev->of_node);
+		break;
+
+	case GENPD_SYNC_STATE_SIMPLE:
+		genpd_lock(genpd);
+		genpd_power_off(genpd, false, 0);
+		genpd_unlock(genpd);
+		break;
+
+	default:
+		break;
+	}
 }
 
 static struct genpd_provider_drv genpd_provider_drv = {
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 9329554b9c4a..d68e07dadc99 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -133,6 +133,12 @@ enum genpd_notication {
 	GENPD_NOTIFY_ON,
 };
 
+enum genpd_sync_state {
+	GENPD_SYNC_STATE_OFF = 0,
+	GENPD_SYNC_STATE_SIMPLE,
+	GENPD_SYNC_STATE_ONECELL,
+};
+
 struct dev_power_governor {
 	bool (*power_down_ok)(struct dev_pm_domain *domain);
 	bool (*suspend_ok)(struct device *dev);
@@ -193,6 +199,7 @@ struct generic_pm_domain {
 	unsigned int performance_state;	/* Aggregated max performance state */
 	cpumask_var_t cpus;		/* A cpumask of the attached CPUs */
 	bool synced_poweroff;		/* A consumer needs a synced poweroff */
+	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);
 	struct raw_notifier_head power_notifiers; /* Power on/off notifiers */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 16/21] driver core: Add dev_set_drv_sync_state()
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (14 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 15/21] pmdomain: core: Add common ->sync_state() support for genpd providers Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 17/21] pmdomain: core: Default to use of_genpd_sync_state() for genpd providers Ulf Hansson
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

From: Saravana Kannan <saravanak@google.com>

This can be used by frameworks to set the sync_state() helper functions
for drivers that don't already have them set.

Signed-off-by: Saravana Kannan <saravanak@google.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
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 f6ca813eebbe..fd4300e17b17 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -955,6 +955,18 @@ static inline bool dev_has_sync_state(struct device *dev)
 	return false;
 }
 
+static inline int dev_set_drv_sync_state(struct device *dev,
+					 void (*fn)(struct device *dev))
+{
+	if (!dev || !dev->driver)
+		return 0;
+	if (dev->driver->sync_state && dev->driver->sync_state != fn)
+		return -EBUSY;
+	if (!dev->driver->sync_state)
+		dev->driver->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] 36+ messages in thread

* [PATCH v2 17/21] pmdomain: core: Default to use of_genpd_sync_state() for genpd providers
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (15 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 16/21] driver core: Add dev_set_drv_sync_state() Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 18/21] pmdomain: core: Leave powered-on genpds on until late_initcall_sync Ulf Hansson
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

Unless the typical platform driver that act as genpd provider, has its own
->sync_state() callback implemented let's default to use
of_genpd_sync_state().

More precisely, while adding a genpd OF provider let's assign the
->sync_state() callback, in case the fwnode has a device and its driver
doesn't have the ->sync_state() set already. In this way the typical
platform driver doesn't need to assign ->sync_state(), unless it has some
additional things to manage beyond genpds.

Suggested-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index c094ccbba151..b39d06d3ad26 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2621,6 +2621,11 @@ static bool genpd_present(const struct generic_pm_domain *genpd)
 	return ret;
 }
 
+static void genpd_sync_state(struct device *dev)
+{
+	return of_genpd_sync_state(dev->of_node);
+}
+
 /**
  * of_genpd_add_provider_simple() - Register a simple PM domain provider
  * @np: Device node pointer associated with the PM domain provider.
@@ -2646,6 +2651,8 @@ int of_genpd_add_provider_simple(struct device_node *np,
 	if (!dev && !genpd_is_no_sync_state(genpd)) {
 		genpd->sync_state = GENPD_SYNC_STATE_SIMPLE;
 		device_set_node(&genpd->dev, fwnode);
+	} else {
+		dev_set_drv_sync_state(dev, genpd_sync_state);
 	}
 
 	put_device(dev);
@@ -2715,6 +2722,8 @@ int of_genpd_add_provider_onecell(struct device_node *np,
 	dev = get_dev_from_fwnode(fwnode);
 	if (!dev)
 		sync_state = true;
+	else
+		dev_set_drv_sync_state(dev, genpd_sync_state);
 
 	put_device(dev);
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 18/21] pmdomain: core: Leave powered-on genpds on until late_initcall_sync
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (16 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 17/21] pmdomain: core: Default to use of_genpd_sync_state() for genpd providers Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 19/21] pmdomain: core: Leave powered-on genpds on until sync_state Ulf Hansson
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

Powering-off a genpd that was on during boot, before all of its consumer
devices have been probed, is certainly prone to problems.

As a step to improve this situation, let's prevent these genpds from being
powered-off until genpd_power_off_unused() gets called, which is a
late_initcall_sync().

Note that, this still doesn't guarantee that all the consumer devices has
been probed before we allow to power-off the genpds. Yet, this should be a
step in the right direction.

Suggested-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c   | 10 ++++++++--
 include/linux/pm_domain.h |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index b39d06d3ad26..5d2ed4edffd7 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -934,11 +934,12 @@ static void genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
 	 * The domain is already in the "power off" state.
 	 * System suspend is in progress.
 	 * The domain is configured as always on.
+	 * The domain was on at boot and still need to stay on.
 	 * The domain has a subdomain being powered on.
 	 */
 	if (!genpd_status_on(genpd) || genpd->prepared_count > 0 ||
 	    genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd) ||
-	    atomic_read(&genpd->sd_count) > 0)
+	    genpd->stay_on || atomic_read(&genpd->sd_count) > 0)
 		return;
 
 	/*
@@ -1349,8 +1350,12 @@ static int __init genpd_power_off_unused(void)
 	pr_info("genpd: Disabling unused power domains\n");
 	mutex_lock(&gpd_list_lock);
 
-	list_for_each_entry(genpd, &gpd_list, gpd_list_node)
+	list_for_each_entry(genpd, &gpd_list, gpd_list_node) {
+		genpd_lock(genpd);
+		genpd->stay_on = false;
+		genpd_unlock(genpd);
 		genpd_queue_power_off_work(genpd);
+	}
 
 	mutex_unlock(&gpd_list_lock);
 
@@ -2375,6 +2380,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
 	INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
 	atomic_set(&genpd->sd_count, 0);
 	genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON;
+	genpd->stay_on = !is_off;
 	genpd->sync_state = GENPD_SYNC_STATE_OFF;
 	genpd->device_count = 0;
 	genpd->provider = NULL;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index d68e07dadc99..99556589f45e 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -199,6 +199,7 @@ struct generic_pm_domain {
 	unsigned int performance_state;	/* Aggregated max performance state */
 	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. */
 	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] 36+ messages in thread

* [PATCH v2 19/21] pmdomain: core: Leave powered-on genpds on until sync_state
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (17 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 18/21] pmdomain: core: Leave powered-on genpds on until late_initcall_sync Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 20/21] cpuidle: psci: Drop redundant sync_state support Ulf Hansson
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

Powering-off a genpd that was on during boot, before all of its consumer
devices have been probed, is certainly prone to problems.

For OF based platforms we can rely on using the sync_state mechanism that
the fw_devlink provides, to understand when all consumers for a genpd
provider have been probed. Let's therefore prevent these genpds from being
powered-off until the ->sync_state() callback gets called.

Note that, for non-OF based platform we will keep relying on the
late_initcall_sync, which seems to be the best we can do for now.

Suggested-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/pmdomain/core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 5d2ed4edffd7..6da25e2c81d2 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -1327,6 +1327,7 @@ static int genpd_runtime_resume(struct device *dev)
 	return ret;
 }
 
+#ifndef CONFIG_PM_GENERIC_DOMAINS_OF
 static bool pd_ignore_unused;
 static int __init pd_ignore_unused_setup(char *__unused)
 {
@@ -1362,6 +1363,7 @@ static int __init genpd_power_off_unused(void)
 	return 0;
 }
 late_initcall_sync(genpd_power_off_unused);
+#endif
 
 #ifdef CONFIG_PM_SLEEP
 
@@ -3471,6 +3473,7 @@ void of_genpd_sync_state(struct device_node *np)
 	list_for_each_entry(genpd, &gpd_list, gpd_list_node) {
 		if (genpd->provider == of_fwnode_handle(np)) {
 			genpd_lock(genpd);
+			genpd->stay_on = false;
 			genpd_power_off(genpd, false, 0);
 			genpd_unlock(genpd);
 		}
@@ -3502,6 +3505,7 @@ static void genpd_provider_sync_state(struct device *dev)
 
 	case GENPD_SYNC_STATE_SIMPLE:
 		genpd_lock(genpd);
+		genpd->stay_on = false;
 		genpd_power_off(genpd, false, 0);
 		genpd_unlock(genpd);
 		break;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 20/21] cpuidle: psci: Drop redundant sync_state support
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (18 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 19/21] pmdomain: core: Leave powered-on genpds on until sync_state Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-05-23 13:40 ` [PATCH v2 21/21] cpuidle: riscv-sbi: " Ulf Hansson
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel

The recent updates to the genpd core, can entirely manage the sync_state
support for the cpuidle-psci-domain. More precisely, genpd prevents our
->power_off() callback from being invoked, until all of our consumers are
ready for it.

Let's therefore drop the sync_state support for the cpuidle-psci-domain as
it has become redundant.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/cpuidle/cpuidle-psci-domain.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
index b880ce2df8b5..37c41209eaf9 100644
--- a/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -28,7 +28,6 @@ struct psci_pd_provider {
 };
 
 static LIST_HEAD(psci_pd_providers);
-static bool psci_pd_allow_domain_state;
 
 static int psci_pd_power_off(struct generic_pm_domain *pd)
 {
@@ -38,9 +37,6 @@ static int psci_pd_power_off(struct generic_pm_domain *pd)
 	if (!state->data)
 		return 0;
 
-	if (!psci_pd_allow_domain_state)
-		return -EBUSY;
-
 	/* OSI mode is enabled, set the corresponding domain state. */
 	pd_state = state->data;
 	psci_set_domain_state(pd, pd->state_idx, *pd_state);
@@ -63,8 +59,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
 	if (!pd_provider)
 		goto free_pd;
 
-	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN |
-		     GENPD_FLAG_NO_SYNC_STATE;
+	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;
 
 	/*
 	 * Allow power off when OSI has been successfully enabled.
@@ -127,20 +122,6 @@ static void psci_pd_remove(void)
 	}
 }
 
-static void psci_cpuidle_domain_sync_state(struct device *dev)
-{
-	struct psci_pd_provider *pd_provider;
-
-	/*
-	 * All devices have now been attached/probed to the PM domain topology,
-	 * hence it's fine to allow domain states to be picked.
-	 */
-	psci_pd_allow_domain_state = true;
-
-	list_for_each_entry(pd_provider, &psci_pd_providers, link)
-		of_genpd_sync_state(pd_provider->node);
-}
-
 static const struct of_device_id psci_of_match[] = {
 	{ .compatible = "arm,psci-1.0" },
 	{}
@@ -201,7 +182,6 @@ static struct platform_driver psci_cpuidle_domain_driver = {
 	.driver = {
 		.name = "psci-cpuidle-domain",
 		.of_match_table = psci_of_match,
-		.sync_state = psci_cpuidle_domain_sync_state,
 	},
 };
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 21/21] cpuidle: riscv-sbi: Drop redundant sync_state support
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (19 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 20/21] cpuidle: psci: Drop redundant sync_state support Ulf Hansson
@ 2025-05-23 13:40 ` Ulf Hansson
  2025-06-03 14:20 ` [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Hiago De Franco
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-23 13:40 UTC (permalink / raw)
  To: Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, Ulf Hansson, linux-arm-kernel,
	linux-kernel, Anup Patel, linux-riscv

The recent updates to the genpd core, can entirely manage the sync_state
support for the cpuidle-riscv-sbi-domain. More precisely, genpd prevents
our ->power_off() callback from being invoked, until all of our consumers
are ready for it.

Let's therefore drop the sync_state support for the
cpuidle-riscv-sbi-domain as it has become redundant.

Cc: Anup Patel <anup@brainfault.org>
Cc: linux-riscv@lists.infradead.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/cpuidle/cpuidle-riscv-sbi.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
index 83d58d00872f..a360bc4d20b7 100644
--- a/drivers/cpuidle/cpuidle-riscv-sbi.c
+++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
@@ -44,7 +44,6 @@ static DEFINE_PER_CPU_READ_MOSTLY(struct sbi_cpuidle_data, sbi_cpuidle_data);
 static DEFINE_PER_CPU(struct sbi_domain_state, domain_state);
 static bool sbi_cpuidle_use_osi;
 static bool sbi_cpuidle_use_cpuhp;
-static bool sbi_cpuidle_pd_allow_domain_state;
 
 static inline void sbi_set_domain_state(u32 state)
 {
@@ -345,20 +344,6 @@ static int sbi_cpuidle_init_cpu(struct device *dev, int cpu)
 	return ret;
 }
 
-static void sbi_cpuidle_domain_sync_state(struct device *dev)
-{
-	struct sbi_pd_provider *pd_provider;
-
-	/*
-	 * All devices have now been attached/probed to the PM domain
-	 * topology, hence it's fine to allow domain states to be picked.
-	 */
-	sbi_cpuidle_pd_allow_domain_state = true;
-
-	list_for_each_entry(pd_provider, &sbi_pd_providers, link)
-		of_genpd_sync_state(pd_provider->node);
-}
-
 #ifdef CONFIG_DT_IDLE_GENPD
 
 static int sbi_cpuidle_pd_power_off(struct generic_pm_domain *pd)
@@ -369,9 +354,6 @@ static int sbi_cpuidle_pd_power_off(struct generic_pm_domain *pd)
 	if (!state->data)
 		return 0;
 
-	if (!sbi_cpuidle_pd_allow_domain_state)
-		return -EBUSY;
-
 	/* OSI mode is enabled, set the corresponding domain state. */
 	pd_state = state->data;
 	sbi_set_domain_state(*pd_state);
@@ -401,8 +383,7 @@ static int sbi_pd_init(struct device_node *np)
 	if (!pd_provider)
 		goto free_pd;
 
-	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN |
-		     GENPD_FLAG_NO_SYNC_STATE;
+	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;
 
 	/* Allow power off when OSI is available. */
 	if (sbi_cpuidle_use_osi)
@@ -570,7 +551,6 @@ static struct platform_driver sbi_cpuidle_driver = {
 	.probe = sbi_cpuidle_probe,
 	.driver = {
 		.name = "sbi-cpuidle",
-		.sync_state = sbi_cpuidle_domain_sync_state,
 	},
 };
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 09/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
  2025-05-23 13:40 ` [PATCH v2 09/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state() Ulf Hansson
@ 2025-05-23 19:42   ` Konrad Dybcio
  2025-05-26 10:12     ` Ulf Hansson
  0 siblings, 1 reply; 36+ messages in thread
From: Konrad Dybcio @ 2025-05-23 19:42 UTC (permalink / raw)
  To: Ulf Hansson, Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Tomi Valkeinen,
	Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, linux-arm-kernel, linux-kernel

On 5/23/25 3:40 PM, Ulf Hansson wrote:
> To make sure genpd tries to power off unused PM domains, let's call
> of_genpd_sync_state() from our own ->sync_state() callback.
> 
> Cc: Bjorn Andersson <andersson@kernel.org>
> Cc: Konrad Dybcio <konradybcio@kernel.org>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---

note: the subject is wrong - this driver is rpmpd, the other
one is rpm*h*pd (patch 10 has the correct subject)

Konrad


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 09/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
  2025-05-23 19:42   ` Konrad Dybcio
@ 2025-05-26 10:12     ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-05-26 10:12 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Saravana Kannan, Stephen Boyd, linux-pm, Rafael J . Wysocki,
	Greg Kroah-Hartman, Michael Grzeschik, Bjorn Andersson, Abel Vesa,
	Peng Fan, Tomi Valkeinen, Johan Hovold, Maulik Shah, Michal Simek,
	Konrad Dybcio, Thierry Reding, Jonathan Hunter, linux-arm-kernel,
	linux-kernel

Hi Konrad,

On Fri, 23 May 2025 at 21:42, Konrad Dybcio
<konrad.dybcio@oss.qualcomm.com> wrote:
>
> On 5/23/25 3:40 PM, Ulf Hansson wrote:
> > To make sure genpd tries to power off unused PM domains, let's call
> > of_genpd_sync_state() from our own ->sync_state() callback.
> >
> > Cc: Bjorn Andersson <andersson@kernel.org>
> > Cc: Konrad Dybcio <konradybcio@kernel.org>
> > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> > ---
>
> note: the subject is wrong - this driver is rpmpd, the other
> one is rpm*h*pd (patch 10 has the correct subject)

Thanks for spotting this!

BTW, would it be possible for you to run some tests on QC HW for this?
Any help would be greatly appreciated.

Kind regards
Uffe


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 02/21] pmdomain: core: Add a bus and a driver for genpd providers
  2025-05-23 13:39 ` [PATCH v2 02/21] pmdomain: core: Add a bus and a driver for genpd providers Ulf Hansson
@ 2025-06-03  0:23   ` Saravana Kannan
  2025-06-03 10:28     ` Ulf Hansson
  0 siblings, 1 reply; 36+ messages in thread
From: Saravana Kannan @ 2025-06-03  0:23 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Stephen Boyd, linux-pm, Rafael J . Wysocki, Greg Kroah-Hartman,
	Michael Grzeschik, Bjorn Andersson, Abel Vesa, Peng Fan,
	Tomi Valkeinen, Johan Hovold, Maulik Shah, Michal Simek,
	Konrad Dybcio, Thierry Reding, Jonathan Hunter, linux-arm-kernel,
	linux-kernel

On Fri, May 23, 2025 at 6:40 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> When we create a genpd via pm_genpd_init() we are initializing a
> corresponding struct device for it, but we don't add the device to any
> bus_type. It has not really been needed as the device is used as cookie to
> help us manage OPP tables.
>
> However, to prepare to make better use of the device let's add a new genpd
> provider bus_type and a corresponding genpd provider driver. Subsequent
> changes will make use of this.
>
> Suggested-by: Saravana Kannan <saravanak@google.com>
> Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/pmdomain/core.c | 89 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 88 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> index 9a66b728fbbf..da515350c65b 100644
> --- a/drivers/pmdomain/core.c
> +++ b/drivers/pmdomain/core.c
> @@ -27,6 +27,11 @@
>  /* Provides a unique ID for each genpd device */
>  static DEFINE_IDA(genpd_ida);
>
> +/* The parent for genpd_provider devices. */
> +static struct device genpd_provider_bus = {
> +       .init_name = "genpd_provider",
> +};
> +
>  #define GENPD_RETRY_MAX_MS     250             /* Approximate */
>
>  #define GENPD_DEV_CALLBACK(genpd, type, callback, dev)         \
> @@ -44,6 +49,14 @@ static DEFINE_IDA(genpd_ida);
>  static LIST_HEAD(gpd_list);
>  static DEFINE_MUTEX(gpd_list_lock);
>
> +#define to_genpd_provider_drv(d) container_of(d, struct genpd_provider_drv, drv)
> +
> +struct genpd_provider_drv {
> +       struct device_driver drv;
> +       int (*probe)(struct device *dev);
> +       void (*remove)(struct device *dev);
> +};
> +
>  struct genpd_lock_ops {
>         void (*lock)(struct generic_pm_domain *genpd);
>         void (*lock_nested)(struct generic_pm_domain *genpd, int depth);
> @@ -2225,6 +2238,26 @@ static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
>         return 0;
>  }
>
> +static int genpd_provider_bus_probe(struct device *dev)
> +{
> +       struct genpd_provider_drv *drv = to_genpd_provider_drv(dev->driver);
> +
> +       return drv->probe(dev);
> +}
> +
> +static void genpd_provider_bus_remove(struct device *dev)
> +{
> +       struct genpd_provider_drv *drv = to_genpd_provider_drv(dev->driver);
> +
> +       drv->remove(dev);
> +}

Not sure if I'm missing some corner case you found out, but you don't
need these stubs just to call the drv ops. Driver core does it anyway
if the bus probe/remove functions are missing.

> +
> +static const struct bus_type genpd_provider_bus_type = {
> +       .name           = "genpd_provider",
> +       .probe          = genpd_provider_bus_probe,
> +       .remove         = genpd_provider_bus_remove,
> +};
> +
>  static void genpd_provider_release(struct device *dev)
>  {
>         /* nothing to be done here */
> @@ -2262,6 +2295,8 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
>         genpd->gd = gd;
>         device_initialize(&genpd->dev);
>         genpd->dev.release = genpd_provider_release;
> +       genpd->dev.bus = &genpd_provider_bus_type;
> +       genpd->dev.parent = &genpd_provider_bus;
>
>         if (!genpd_is_dev_name_fw(genpd)) {
>                 dev_set_name(&genpd->dev, "%s", genpd->name);
> @@ -3355,9 +3390,61 @@ int of_genpd_parse_idle_states(struct device_node *dn,
>  }
>  EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
>
> +static int genpd_provider_probe(struct device *dev)
> +{
> +       return 0;
> +}
> +
> +static void genpd_provider_remove(struct device *dev)
> +{
> +}

Same might apply here.

-Saravana

> +
> +static void genpd_provider_sync_state(struct device *dev)
> +{
> +}
> +
> +static struct genpd_provider_drv genpd_provider_drv = {
> +       .drv = {
> +               .name = "genpd_provider",
> +               .bus = &genpd_provider_bus_type,
> +               .sync_state = genpd_provider_sync_state,
> +               .suppress_bind_attrs = true,
> +       },
> +       .probe = genpd_provider_probe,
> +       .remove = genpd_provider_remove,
> +};
> +
>  static int __init genpd_bus_init(void)
>  {
> -       return bus_register(&genpd_bus_type);
> +       int ret;
> +
> +       ret = device_register(&genpd_provider_bus);
> +       if (ret) {
> +               put_device(&genpd_provider_bus);
> +               return ret;
> +       }
> +
> +       ret = bus_register(&genpd_provider_bus_type);
> +       if (ret)
> +               goto err_dev;
> +
> +       ret = bus_register(&genpd_bus_type);
> +       if (ret)
> +               goto err_prov_bus;
> +
> +       ret = driver_register(&genpd_provider_drv.drv);
> +       if (ret)
> +               goto err_bus;
> +
> +       return 0;
> +
> +err_bus:
> +       bus_unregister(&genpd_bus_type);
> +err_prov_bus:
> +       bus_unregister(&genpd_provider_bus_type);
> +err_dev:
> +       device_unregister(&genpd_provider_bus);
> +       return ret;
>  }
>  core_initcall(genpd_bus_init);
>
> --
> 2.43.0
>


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 02/21] pmdomain: core: Add a bus and a driver for genpd providers
  2025-06-03  0:23   ` Saravana Kannan
@ 2025-06-03 10:28     ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2025-06-03 10:28 UTC (permalink / raw)
  To: Saravana Kannan
  Cc: Stephen Boyd, linux-pm, Rafael J . Wysocki, Greg Kroah-Hartman,
	Michael Grzeschik, Bjorn Andersson, Abel Vesa, Peng Fan,
	Tomi Valkeinen, Johan Hovold, Maulik Shah, Michal Simek,
	Konrad Dybcio, Thierry Reding, Jonathan Hunter, linux-arm-kernel,
	linux-kernel

On Tue, 3 Jun 2025 at 02:23, Saravana Kannan <saravanak@google.com> wrote:
>
> On Fri, May 23, 2025 at 6:40 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >
> > When we create a genpd via pm_genpd_init() we are initializing a
> > corresponding struct device for it, but we don't add the device to any
> > bus_type. It has not really been needed as the device is used as cookie to
> > help us manage OPP tables.
> >
> > However, to prepare to make better use of the device let's add a new genpd
> > provider bus_type and a corresponding genpd provider driver. Subsequent
> > changes will make use of this.
> >
> > Suggested-by: Saravana Kannan <saravanak@google.com>
> > Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
> > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> > ---
> >  drivers/pmdomain/core.c | 89 ++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 88 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> > index 9a66b728fbbf..da515350c65b 100644
> > --- a/drivers/pmdomain/core.c
> > +++ b/drivers/pmdomain/core.c
> > @@ -27,6 +27,11 @@
> >  /* Provides a unique ID for each genpd device */
> >  static DEFINE_IDA(genpd_ida);
> >
> > +/* The parent for genpd_provider devices. */
> > +static struct device genpd_provider_bus = {
> > +       .init_name = "genpd_provider",
> > +};
> > +
> >  #define GENPD_RETRY_MAX_MS     250             /* Approximate */
> >
> >  #define GENPD_DEV_CALLBACK(genpd, type, callback, dev)         \
> > @@ -44,6 +49,14 @@ static DEFINE_IDA(genpd_ida);
> >  static LIST_HEAD(gpd_list);
> >  static DEFINE_MUTEX(gpd_list_lock);
> >
> > +#define to_genpd_provider_drv(d) container_of(d, struct genpd_provider_drv, drv)
> > +
> > +struct genpd_provider_drv {
> > +       struct device_driver drv;
> > +       int (*probe)(struct device *dev);
> > +       void (*remove)(struct device *dev);
> > +};
> > +
> >  struct genpd_lock_ops {
> >         void (*lock)(struct generic_pm_domain *genpd);
> >         void (*lock_nested)(struct generic_pm_domain *genpd, int depth);
> > @@ -2225,6 +2238,26 @@ static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
> >         return 0;
> >  }
> >
> > +static int genpd_provider_bus_probe(struct device *dev)
> > +{
> > +       struct genpd_provider_drv *drv = to_genpd_provider_drv(dev->driver);
> > +
> > +       return drv->probe(dev);
> > +}
> > +
> > +static void genpd_provider_bus_remove(struct device *dev)
> > +{
> > +       struct genpd_provider_drv *drv = to_genpd_provider_drv(dev->driver);
> > +
> > +       drv->remove(dev);
> > +}
>
> Not sure if I'm missing some corner case you found out, but you don't
> need these stubs just to call the drv ops. Driver core does it anyway
> if the bus probe/remove functions are missing.

Right, they are probably just leftovers used for debug-prints during
development.

Thanks for spotting this!

>
> > +
> > +static const struct bus_type genpd_provider_bus_type = {
> > +       .name           = "genpd_provider",
> > +       .probe          = genpd_provider_bus_probe,
> > +       .remove         = genpd_provider_bus_remove,
> > +};
> > +
> >  static void genpd_provider_release(struct device *dev)
> >  {
> >         /* nothing to be done here */
> > @@ -2262,6 +2295,8 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
> >         genpd->gd = gd;
> >         device_initialize(&genpd->dev);
> >         genpd->dev.release = genpd_provider_release;
> > +       genpd->dev.bus = &genpd_provider_bus_type;
> > +       genpd->dev.parent = &genpd_provider_bus;
> >
> >         if (!genpd_is_dev_name_fw(genpd)) {
> >                 dev_set_name(&genpd->dev, "%s", genpd->name);
> > @@ -3355,9 +3390,61 @@ int of_genpd_parse_idle_states(struct device_node *dn,
> >  }
> >  EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
> >
> > +static int genpd_provider_probe(struct device *dev)
> > +{
> > +       return 0;
> > +}
> > +
> > +static void genpd_provider_remove(struct device *dev)
> > +{
> > +}
>
> Same might apply here.

Let me check and see if/what can be dropped.

I think you told me that I needed the ->probe() function to keep
fw_devlink happy, but maybe I got that wrong.

[...]

Kind regards
Uffe


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (20 preceding siblings ...)
  2025-05-23 13:40 ` [PATCH v2 21/21] cpuidle: riscv-sbi: " Ulf Hansson
@ 2025-06-03 14:20 ` Hiago De Franco
  2025-06-12  6:09 ` Tomi Valkeinen
       [not found] ` <fd4cfe7a-e29b-4237-b82f-48354deead3b@ideasonboard.com>
  23 siblings, 0 replies; 36+ messages in thread
From: Hiago De Franco @ 2025-06-03 14:20 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Saravana Kannan, Stephen Boyd, linux-pm, Rafael J . Wysocki,
	Greg Kroah-Hartman, Michael Grzeschik, Bjorn Andersson, Abel Vesa,
	Peng Fan, Tomi Valkeinen, Johan Hovold, Maulik Shah, Michal Simek,
	Konrad Dybcio, Thierry Reding, Jonathan Hunter, linux-arm-kernel,
	linux-kernel

Hi Ulf,

On Fri, May 23, 2025 at 03:39:57PM +0200, Ulf Hansson wrote:
> Changes in v2:
> 	- Well, quite a lot as I discovered various problems when doing
> 	additional testing of corner-case. I suggest re-review from scratch,
> 	even if I decided to keep some reviewed-by tags.
> 	- Added patches to allow some drivers that needs to align or opt-out
> 	from the new common behaviour in genpd.
> 
> If a PM domain (genpd) is powered-on during boot, there is probably a good
> reason for it. Therefore it's known to be a bad idea to allow such genpd to be
> powered-off before all of its consumer devices have been probed. This series
> intends to fix this problem.
> 
> We have been discussing these issues at LKML and at various Linux-conferences
> in the past. I have therefore tried to include the people I can recall being
> involved, but I may have forgotten some (my apologies), feel free to loop them
> in.
> 
> I have tested this with QEMU with a bunch of local test-drivers and DT nodes.
> Let me know if you want me to share this code too.
> 
> Please help review and test!
> Finally, a big thanks to Saravana for all the support!
> 
> Kind regards
> Ulf Hansson
> 
> 
> Saravana Kannan (1):
>   driver core: Add dev_set_drv_sync_state()
> 
> Ulf Hansson (20):
>   pmdomain: core: Use of_fwnode_handle()
>   pmdomain: core: Add a bus and a driver for genpd providers
>   pmdomain: core: Add the genpd->dev to the genpd provider bus
>   pmdomain: core: Export a common ->sync_state() helper for genpd
>     providers
>   pmdomain: core: Prepare to add the common ->sync_state() support
>   soc/tegra: pmc: Opt-out from genpd's common ->sync_state() support
>   cpuidle: psci: Opt-out from genpd's common ->sync_state() support
>   cpuidle: riscv-sbi: Opt-out from genpd's common ->sync_state() support
>   pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
>   pmdomain: qcom: rpmhpd: Use of_genpd_sync_state()
>   firmware/pmdomain: xilinx: Move ->sync_state() support to firmware
>     driver
>   firmware: xilinx: Don't share zynqmp_pm_init_finalize()
>   firmware: xilinx: Use of_genpd_sync_state()
>   driver core: Export get_dev_from_fwnode()
>   pmdomain: core: Add common ->sync_state() support for genpd providers
>   pmdomain: core: Default to use of_genpd_sync_state() for genpd
>     providers
>   pmdomain: core: Leave powered-on genpds on until late_initcall_sync
>   pmdomain: core: Leave powered-on genpds on until sync_state
>   cpuidle: psci: Drop redundant sync_state support
>   cpuidle: riscv-sbi: Drop redundant sync_state support
> 
>  drivers/base/core.c                         |   8 +-
>  drivers/cpuidle/cpuidle-psci-domain.c       |  14 --
>  drivers/cpuidle/cpuidle-riscv-sbi.c         |  14 --
>  drivers/firmware/xilinx/zynqmp.c            |  18 +-
>  drivers/pmdomain/core.c                     | 239 ++++++++++++++++++--
>  drivers/pmdomain/qcom/rpmhpd.c              |   2 +
>  drivers/pmdomain/qcom/rpmpd.c               |   2 +
>  drivers/pmdomain/xilinx/zynqmp-pm-domains.c |  16 --
>  drivers/soc/tegra/pmc.c                     |  26 ++-
>  include/linux/device.h                      |  13 ++
>  include/linux/firmware/xlnx-zynqmp.h        |   6 -
>  include/linux/pm_domain.h                   |  17 ++
>  12 files changed, 294 insertions(+), 81 deletions(-)
> 
> -- 
> 2.43.0
>

Tested-by: Hiago De Franco <hiago.franco@toradex.com> # Colibri iMX8X

Best Regards,
Hiago.


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 01/21] pmdomain: core: Use of_fwnode_handle()
  2025-05-23 13:39 ` [PATCH v2 01/21] pmdomain: core: Use of_fwnode_handle() Ulf Hansson
@ 2025-06-11  6:07   ` Dhruva Gole
  0 siblings, 0 replies; 36+ messages in thread
From: Dhruva Gole @ 2025-06-11  6:07 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Saravana Kannan, Stephen Boyd, linux-pm, Rafael J . Wysocki,
	Greg Kroah-Hartman, Michael Grzeschik, Bjorn Andersson, Abel Vesa,
	Peng Fan, Tomi Valkeinen, Johan Hovold, Maulik Shah, Michal Simek,
	Konrad Dybcio, Thierry Reding, Jonathan Hunter, linux-arm-kernel,
	linux-kernel

On May 23, 2025 at 15:39:58 +0200, Ulf Hansson wrote:
> Let's avoid accessing the np->fwnode directly and use the common helper
> of_fwnode_handle() instead.
> 
> Suggested-by: Saravana Kannan <saravanak@google.com>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---

Reviewed-by: Dhruva Gole <d-gole@ti.com>

-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
  2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
                   ` (21 preceding siblings ...)
  2025-06-03 14:20 ` [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Hiago De Franco
@ 2025-06-12  6:09 ` Tomi Valkeinen
       [not found] ` <fd4cfe7a-e29b-4237-b82f-48354deead3b@ideasonboard.com>
  23 siblings, 0 replies; 36+ messages in thread
From: Tomi Valkeinen @ 2025-06-12  6:09 UTC (permalink / raw)
  To: Ulf Hansson, Saravana Kannan, Stephen Boyd, linux-pm
  Cc: Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Johan Hovold, Maulik Shah,
	Michal Simek, Konrad Dybcio, Thierry Reding, Jonathan Hunter,
	linux-arm-kernel, linux-kernel


On 23/05/2025 16:39, Ulf Hansson wrote:
> Changes in v2:
> 	- Well, quite a lot as I discovered various problems when doing
> 	additional testing of corner-case. I suggest re-review from scratch,
> 	even if I decided to keep some reviewed-by tags.
> 	- Added patches to allow some drivers that needs to align or opt-out
> 	from the new common behaviour in genpd.
> 
> If a PM domain (genpd) is powered-on during boot, there is probably a good
> reason for it. Therefore it's known to be a bad idea to allow such genpd to be
> powered-off before all of its consumer devices have been probed. This series
> intends to fix this problem.
> 
> We have been discussing these issues at LKML and at various Linux-conferences
> in the past. I have therefore tried to include the people I can recall being
> involved, but I may have forgotten some (my apologies), feel free to loop them
> in.
> 
> I have tested this with QEMU with a bunch of local test-drivers and DT nodes.
> Let me know if you want me to share this code too.
> 
> Please help review and test!
> Finally, a big thanks to Saravana for all the support!

For TI AM62A and Xilinx ZynqMP ZCU106:

Tested-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

 Tomi



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
       [not found] ` <fd4cfe7a-e29b-4237-b82f-48354deead3b@ideasonboard.com>
@ 2025-06-19 11:40   ` Ulf Hansson
  2025-06-23 14:20     ` Ulf Hansson
  0 siblings, 1 reply; 36+ messages in thread
From: Ulf Hansson @ 2025-06-19 11:40 UTC (permalink / raw)
  To: Tomi Valkeinen, Geert Uytterhoeven
  Cc: Saravana Kannan, Stephen Boyd, linux-pm, Rafael J . Wysocki,
	Greg Kroah-Hartman, Michael Grzeschik, Bjorn Andersson, Abel Vesa,
	Peng Fan, Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, linux-arm-kernel, linux-kernel

On Fri, 13 Jun 2025 at 12:33, Tomi Valkeinen
<tomi.valkeinen@ideasonboard.com> wrote:
>
> Hi Ulf,
>
> On 23/05/2025 16:39, Ulf Hansson wrote:
> > Changes in v2:
> >       - Well, quite a lot as I discovered various problems when doing
> >       additional testing of corner-case. I suggest re-review from scratch,
> >       even if I decided to keep some reviewed-by tags.
> >       - Added patches to allow some drivers that needs to align or opt-out
> >       from the new common behaviour in genpd.
> >
> > If a PM domain (genpd) is powered-on during boot, there is probably a good
> > reason for it. Therefore it's known to be a bad idea to allow such genpd to be
> > powered-off before all of its consumer devices have been probed. This series
> > intends to fix this problem.
> >
> > We have been discussing these issues at LKML and at various Linux-conferences
> > in the past. I have therefore tried to include the people I can recall being
> > involved, but I may have forgotten some (my apologies), feel free to loop them
> > in.
> >
> > I have tested this with QEMU with a bunch of local test-drivers and DT nodes.
> > Let me know if you want me to share this code too.
> >
> > Please help review and test!
>
> I tested this Renesas white-hawk board, and it hangs at boot. With
> earlycon, I captured with/without boot logs, attached.
>
> The hang case doesn't look very healthy with all these: "kobject:
> '(null)' ((____ptrval____)): is not initialized, yet kobject_get() is
> being called."

Tomi, thanks a lot for helping out with testing!

rcar_gen4_sysc_pd_init() calls pm_genpd_init() and
of_genpd_add_provider_onecell().

rcar_gen4_sysc_pd_init() is an early_initcall, which I guess is the
reason for these problems, as the genpd_provider_bus has not been
registered that early (it's done at core_initcall)

Do you think it would be possible to move rcar_gen4_sysc_pd_init() to
a postcore/arch_initcall?

Kind regards
Uffe


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
  2025-06-19 11:40   ` Ulf Hansson
@ 2025-06-23 14:20     ` Ulf Hansson
  2025-06-23 15:06       ` Geert Uytterhoeven
  0 siblings, 1 reply; 36+ messages in thread
From: Ulf Hansson @ 2025-06-23 14:20 UTC (permalink / raw)
  To: Tomi Valkeinen, Geert Uytterhoeven
  Cc: Saravana Kannan, Stephen Boyd, linux-pm, Rafael J . Wysocki,
	Greg Kroah-Hartman, Michael Grzeschik, Bjorn Andersson, Abel Vesa,
	Peng Fan, Johan Hovold, Maulik Shah, Michal Simek, Konrad Dybcio,
	Thierry Reding, Jonathan Hunter, linux-arm-kernel, linux-kernel

On Thu, 19 Jun 2025 at 13:40, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> On Fri, 13 Jun 2025 at 12:33, Tomi Valkeinen
> <tomi.valkeinen@ideasonboard.com> wrote:
> >
> > Hi Ulf,
> >
> > On 23/05/2025 16:39, Ulf Hansson wrote:
> > > Changes in v2:
> > >       - Well, quite a lot as I discovered various problems when doing
> > >       additional testing of corner-case. I suggest re-review from scratch,
> > >       even if I decided to keep some reviewed-by tags.
> > >       - Added patches to allow some drivers that needs to align or opt-out
> > >       from the new common behaviour in genpd.
> > >
> > > If a PM domain (genpd) is powered-on during boot, there is probably a good
> > > reason for it. Therefore it's known to be a bad idea to allow such genpd to be
> > > powered-off before all of its consumer devices have been probed. This series
> > > intends to fix this problem.
> > >
> > > We have been discussing these issues at LKML and at various Linux-conferences
> > > in the past. I have therefore tried to include the people I can recall being
> > > involved, but I may have forgotten some (my apologies), feel free to loop them
> > > in.
> > >
> > > I have tested this with QEMU with a bunch of local test-drivers and DT nodes.
> > > Let me know if you want me to share this code too.
> > >
> > > Please help review and test!
> >
> > I tested this Renesas white-hawk board, and it hangs at boot. With
> > earlycon, I captured with/without boot logs, attached.
> >
> > The hang case doesn't look very healthy with all these: "kobject:
> > '(null)' ((____ptrval____)): is not initialized, yet kobject_get() is
> > being called."
>
> Tomi, thanks a lot for helping out with testing!
>
> rcar_gen4_sysc_pd_init() calls pm_genpd_init() and
> of_genpd_add_provider_onecell().
>
> rcar_gen4_sysc_pd_init() is an early_initcall, which I guess is the
> reason for these problems, as the genpd_provider_bus has not been
> registered that early (it's done at core_initcall)
>
> Do you think it would be possible to move rcar_gen4_sysc_pd_init() to
> a postcore/arch_initcall?

I did some investigation around this and found that both
drivers/pmdomain/renesas/rcar-gen4-sysc.c and
drivers/pmdomain/renesas/rcar-sysc.c are registering their genpd
providers at the early_initcall() level.

I was trying to find (by browsing renesas DTSes and looking into
drivers) if there is any consumers that actually relies on this, but
so far the earliest consumer I have found is the
drivers/irqchip/irq-renesas-irqc.c, but that's at postcore_initcall().
Of course, it's difficult to say if my analysis is complete as there
are a lot of platform variants and I didn't check them all.

Maybe we should just give it a try and move both two drivers above to
postcore_initcall and see if it works (assuming the irq-renesas-irqc
supports -EPROBE_DEFER correctly too).

If this doesn't work, I think we need to find a way to allow deferring
the call to device_add() in of_genpd_provider_add*() for genpd
provider's devices.

Kind regards
Uffe


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
  2025-06-23 14:20     ` Ulf Hansson
@ 2025-06-23 15:06       ` Geert Uytterhoeven
  2025-06-24 12:10         ` Geert Uytterhoeven
  2025-06-24 15:29         ` Ulf Hansson
  0 siblings, 2 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2025-06-23 15:06 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Tomi Valkeinen, Saravana Kannan, Stephen Boyd, linux-pm,
	Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Johan Hovold, Maulik Shah,
	Michal Simek, Konrad Dybcio, Thierry Reding, Jonathan Hunter,
	linux-arm-kernel, linux-kernel, Linux-Renesas

Hi Ulf,

On Mon, 23 Jun 2025 at 16:21, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On Thu, 19 Jun 2025 at 13:40, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > On Fri, 13 Jun 2025 at 12:33, Tomi Valkeinen
> > <tomi.valkeinen@ideasonboard.com> wrote:
> > > On 23/05/2025 16:39, Ulf Hansson wrote:
> > > > Changes in v2:
> > > >       - Well, quite a lot as I discovered various problems when doing
> > > >       additional testing of corner-case. I suggest re-review from scratch,
> > > >       even if I decided to keep some reviewed-by tags.
> > > >       - Added patches to allow some drivers that needs to align or opt-out
> > > >       from the new common behaviour in genpd.
> > > >
> > > > If a PM domain (genpd) is powered-on during boot, there is probably a good
> > > > reason for it. Therefore it's known to be a bad idea to allow such genpd to be
> > > > powered-off before all of its consumer devices have been probed. This series
> > > > intends to fix this problem.
> > > >
> > > > We have been discussing these issues at LKML and at various Linux-conferences
> > > > in the past. I have therefore tried to include the people I can recall being
> > > > involved, but I may have forgotten some (my apologies), feel free to loop them
> > > > in.
> > > >
> > > > I have tested this with QEMU with a bunch of local test-drivers and DT nodes.
> > > > Let me know if you want me to share this code too.
> > > >
> > > > Please help review and test!
> > >
> > > I tested this Renesas white-hawk board, and it hangs at boot. With
> > > earlycon, I captured with/without boot logs, attached.
> > >
> > > The hang case doesn't look very healthy with all these: "kobject:
> > > '(null)' ((____ptrval____)): is not initialized, yet kobject_get() is
> > > being called."
> >
> > Tomi, thanks a lot for helping out with testing!
> >
> > rcar_gen4_sysc_pd_init() calls pm_genpd_init() and
> > of_genpd_add_provider_onecell().
> >
> > rcar_gen4_sysc_pd_init() is an early_initcall, which I guess is the
> > reason for these problems, as the genpd_provider_bus has not been
> > registered that early (it's done at core_initcall)
> >
> > Do you think it would be possible to move rcar_gen4_sysc_pd_init() to
> > a postcore/arch_initcall?
>
> I did some investigation around this and found that both
> drivers/pmdomain/renesas/rcar-gen4-sysc.c and
> drivers/pmdomain/renesas/rcar-sysc.c are registering their genpd
> providers at the early_initcall() level.
>
> I was trying to find (by browsing renesas DTSes and looking into
> drivers) if there is any consumers that actually relies on this, but
> so far the earliest consumer I have found is the
> drivers/irqchip/irq-renesas-irqc.c, but that's at postcore_initcall().
> Of course, it's difficult to say if my analysis is complete as there
> are a lot of platform variants and I didn't check them all.
>
> Maybe we should just give it a try and move both two drivers above to
> postcore_initcall and see if it works (assuming the irq-renesas-irqc
> supports -EPROBE_DEFER correctly too).
>
> If this doesn't work, I think we need to find a way to allow deferring
> the call to device_add() in of_genpd_provider_add*() for genpd
> provider's devices.

Commit dcc09fd143bb97c2 ("soc: renesas: rcar-sysc: Add DT support for
SYSC PM domains") explains:

   "Initialization is done from an early_initcall(), to make sure the PM
    Domains are initialized before secondary CPU bringup."

but that matters only for arm32 systems (R-Car Gen1 and Gen2).
Arm64 systems (R-Car Gen3 and Gen4) use PSCI for CPU PM Domain control.

While changing rcar-sysc.c to use a postcore_initcall indeed moves PM
Domain initialization after secondary CPU bringup, the second CPU core
on R-Car M2-W is still brought up fine.

For R-Car H1, there is a regression:

    smp: Bringing up secondary CPUs ...
    CPU1: failed to boot: -19
    CPU2: failed to boot: -19
    CPU3: failed to boot: -19
    smp: Brought up 1 node, 1 CPU
    SMP: Total of 1 processors activated (500.00 BogoMIPS).

CPU bringup/teardown in userspace using
/sys/devices/system/cpu/cpu*/online still works.
R-Car H1 was never converted to use "enable-method" in DT, and relies
on calling into the rcar-sysc driver directly (see [1]).  However,
that does not use any actual calls into the genpd core, so probably it
can be made to work by splitting rcar_sysc_pd_init() in two parts: an
early_initcall() that allocates all domain structures and populates the
internal hierarchy, and a postcore_initcall() that registers everything
with the genpd core.

As expected, there is no impact on R-Car H3 ES2.0.
I will test on R-Car V4M tomorrow, but expect no issues.

FTR, drivers/pmdomain/renesas/rmobile-sysc.c uses core_initcall().
Changing that to postcore_initcall does not seem to make a difference
(on R-Mobile A1).

[1] https://elixir.bootlin.com/linux/v6.15.3/source/drivers/pmdomain/renesas/rcar-sysc.c#L439

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
  2025-06-23 15:06       ` Geert Uytterhoeven
@ 2025-06-24 12:10         ` Geert Uytterhoeven
  2025-06-24 15:29         ` Ulf Hansson
  1 sibling, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2025-06-24 12:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Tomi Valkeinen, Saravana Kannan, Stephen Boyd, linux-pm,
	Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Johan Hovold, Maulik Shah,
	Michal Simek, Konrad Dybcio, Thierry Reding, Jonathan Hunter,
	linux-arm-kernel, linux-kernel, Linux-Renesas

On Mon, 23 Jun 2025 at 17:06, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Mon, 23 Jun 2025 at 16:21, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > On Thu, 19 Jun 2025 at 13:40, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > rcar_gen4_sysc_pd_init() is an early_initcall, which I guess is the
> > > reason for these problems, as the genpd_provider_bus has not been
> > > registered that early (it's done at core_initcall)
> > >
> > > Do you think it would be possible to move rcar_gen4_sysc_pd_init() to
> > > a postcore/arch_initcall?
> >
> > I did some investigation around this and found that both
> > drivers/pmdomain/renesas/rcar-gen4-sysc.c and
> > drivers/pmdomain/renesas/rcar-sysc.c are registering their genpd
> > providers at the early_initcall() level.
> >
> > I was trying to find (by browsing renesas DTSes and looking into
> > drivers) if there is any consumers that actually relies on this, but
> > so far the earliest consumer I have found is the
> > drivers/irqchip/irq-renesas-irqc.c, but that's at postcore_initcall().
> > Of course, it's difficult to say if my analysis is complete as there
> > are a lot of platform variants and I didn't check them all.
> >
> > Maybe we should just give it a try and move both two drivers above to
> > postcore_initcall and see if it works (assuming the irq-renesas-irqc
> > supports -EPROBE_DEFER correctly too).
> >
> > If this doesn't work, I think we need to find a way to allow deferring
> > the call to device_add() in of_genpd_provider_add*() for genpd
> > provider's devices.
>
> Commit dcc09fd143bb97c2 ("soc: renesas: rcar-sysc: Add DT support for
> SYSC PM domains") explains:
>
>    "Initialization is done from an early_initcall(), to make sure the PM
>     Domains are initialized before secondary CPU bringup."
>
> but that matters only for arm32 systems (R-Car Gen1 and Gen2).
> Arm64 systems (R-Car Gen3 and Gen4) use PSCI for CPU PM Domain control.

[...]

> As expected, there is no impact on R-Car H3 ES2.0.
> I will test on R-Car V4M tomorrow, but expect no issues.

R-Car V4M is fine, too.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
  2025-06-23 15:06       ` Geert Uytterhoeven
  2025-06-24 12:10         ` Geert Uytterhoeven
@ 2025-06-24 15:29         ` Ulf Hansson
  2025-06-30  9:31           ` Geert Uytterhoeven
  1 sibling, 1 reply; 36+ messages in thread
From: Ulf Hansson @ 2025-06-24 15:29 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Tomi Valkeinen, Saravana Kannan, Stephen Boyd, linux-pm,
	Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Johan Hovold, Maulik Shah,
	Michal Simek, Konrad Dybcio, Thierry Reding, Jonathan Hunter,
	linux-arm-kernel, linux-kernel, Linux-Renesas

On Mon, 23 Jun 2025 at 17:06, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Ulf,
>
> On Mon, 23 Jun 2025 at 16:21, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > On Thu, 19 Jun 2025 at 13:40, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > On Fri, 13 Jun 2025 at 12:33, Tomi Valkeinen
> > > <tomi.valkeinen@ideasonboard.com> wrote:
> > > > On 23/05/2025 16:39, Ulf Hansson wrote:
> > > > > Changes in v2:
> > > > >       - Well, quite a lot as I discovered various problems when doing
> > > > >       additional testing of corner-case. I suggest re-review from scratch,
> > > > >       even if I decided to keep some reviewed-by tags.
> > > > >       - Added patches to allow some drivers that needs to align or opt-out
> > > > >       from the new common behaviour in genpd.
> > > > >
> > > > > If a PM domain (genpd) is powered-on during boot, there is probably a good
> > > > > reason for it. Therefore it's known to be a bad idea to allow such genpd to be
> > > > > powered-off before all of its consumer devices have been probed. This series
> > > > > intends to fix this problem.
> > > > >
> > > > > We have been discussing these issues at LKML and at various Linux-conferences
> > > > > in the past. I have therefore tried to include the people I can recall being
> > > > > involved, but I may have forgotten some (my apologies), feel free to loop them
> > > > > in.
> > > > >
> > > > > I have tested this with QEMU with a bunch of local test-drivers and DT nodes.
> > > > > Let me know if you want me to share this code too.
> > > > >
> > > > > Please help review and test!
> > > >
> > > > I tested this Renesas white-hawk board, and it hangs at boot. With
> > > > earlycon, I captured with/without boot logs, attached.
> > > >
> > > > The hang case doesn't look very healthy with all these: "kobject:
> > > > '(null)' ((____ptrval____)): is not initialized, yet kobject_get() is
> > > > being called."
> > >
> > > Tomi, thanks a lot for helping out with testing!
> > >
> > > rcar_gen4_sysc_pd_init() calls pm_genpd_init() and
> > > of_genpd_add_provider_onecell().
> > >
> > > rcar_gen4_sysc_pd_init() is an early_initcall, which I guess is the
> > > reason for these problems, as the genpd_provider_bus has not been
> > > registered that early (it's done at core_initcall)
> > >
> > > Do you think it would be possible to move rcar_gen4_sysc_pd_init() to
> > > a postcore/arch_initcall?
> >
> > I did some investigation around this and found that both
> > drivers/pmdomain/renesas/rcar-gen4-sysc.c and
> > drivers/pmdomain/renesas/rcar-sysc.c are registering their genpd
> > providers at the early_initcall() level.
> >
> > I was trying to find (by browsing renesas DTSes and looking into
> > drivers) if there is any consumers that actually relies on this, but
> > so far the earliest consumer I have found is the
> > drivers/irqchip/irq-renesas-irqc.c, but that's at postcore_initcall().
> > Of course, it's difficult to say if my analysis is complete as there
> > are a lot of platform variants and I didn't check them all.
> >
> > Maybe we should just give it a try and move both two drivers above to
> > postcore_initcall and see if it works (assuming the irq-renesas-irqc
> > supports -EPROBE_DEFER correctly too).
> >
> > If this doesn't work, I think we need to find a way to allow deferring
> > the call to device_add() in of_genpd_provider_add*() for genpd
> > provider's devices.
>
> Commit dcc09fd143bb97c2 ("soc: renesas: rcar-sysc: Add DT support for
> SYSC PM domains") explains:
>
>    "Initialization is done from an early_initcall(), to make sure the PM
>     Domains are initialized before secondary CPU bringup."
>
> but that matters only for arm32 systems (R-Car Gen1 and Gen2).
> Arm64 systems (R-Car Gen3 and Gen4) use PSCI for CPU PM Domain control.

Geert, thanks a lot for providing these details and helping out, much
appreciated!

>
> While changing rcar-sysc.c to use a postcore_initcall indeed moves PM
> Domain initialization after secondary CPU bringup, the second CPU core
> on R-Car M2-W is still brought up fine.
>
> For R-Car H1, there is a regression:
>
>     smp: Bringing up secondary CPUs ...
>     CPU1: failed to boot: -19
>     CPU2: failed to boot: -19
>     CPU3: failed to boot: -19
>     smp: Brought up 1 node, 1 CPU
>     SMP: Total of 1 processors activated (500.00 BogoMIPS).
>
> CPU bringup/teardown in userspace using
> /sys/devices/system/cpu/cpu*/online still works.
> R-Car H1 was never converted to use "enable-method" in DT, and relies
> on calling into the rcar-sysc driver directly (see [1]).  However,
> that does not use any actual calls into the genpd core, so probably it
> can be made to work by splitting rcar_sysc_pd_init() in two parts: an
> early_initcall() that allocates all domain structures and populates the
> internal hierarchy, and a postcore_initcall() that registers everything
> with the genpd core.

Yes, that seems like a viable option.

Unless you prefer to have a stab at it, I intend to look into it and
make the patch(es) part of a new version of the $subject series. Of
course I am still relying on your help with testing/review.

>
> As expected, there is no impact on R-Car H3 ES2.0.
> I will test on R-Car V4M tomorrow, but expect no issues.
>
> FTR, drivers/pmdomain/renesas/rmobile-sysc.c uses core_initcall().
> Changing that to postcore_initcall does not seem to make a difference
> (on R-Mobile A1).

Okay, it sure looks like we should be able to take care of this
problem for the Renesas platforms. That's great!

That said, it seems like we should also add some internal check in
genpd to see whether the genpd_provider_bus has been registered,
before we try to add devices to it. Then, perhaps log a warning and
return -EPROBE_DEFER if we hit  that case.

>
> [1] https://elixir.bootlin.com/linux/v6.15.3/source/drivers/pmdomain/renesas/rcar-sysc.c#L439
>

Kind regards
Uffe


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd
  2025-06-24 15:29         ` Ulf Hansson
@ 2025-06-30  9:31           ` Geert Uytterhoeven
  0 siblings, 0 replies; 36+ messages in thread
From: Geert Uytterhoeven @ 2025-06-30  9:31 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Tomi Valkeinen, Saravana Kannan, Stephen Boyd, linux-pm,
	Rafael J . Wysocki, Greg Kroah-Hartman, Michael Grzeschik,
	Bjorn Andersson, Abel Vesa, Peng Fan, Johan Hovold, Maulik Shah,
	Michal Simek, Konrad Dybcio, Thierry Reding, Jonathan Hunter,
	linux-arm-kernel, linux-kernel, Linux-Renesas

Hi Ulf,

On Tue, 24 Jun 2025 at 17:30, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On Mon, 23 Jun 2025 at 17:06, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > On Mon, 23 Jun 2025 at 16:21, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > On Thu, 19 Jun 2025 at 13:40, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > > Do you think it would be possible to move rcar_gen4_sysc_pd_init() to
> > > > a postcore/arch_initcall?
> > >
> > > I did some investigation around this and found that both
> > > drivers/pmdomain/renesas/rcar-gen4-sysc.c and
> > > drivers/pmdomain/renesas/rcar-sysc.c are registering their genpd
> > > providers at the early_initcall() level.
> > >
> > > I was trying to find (by browsing renesas DTSes and looking into
> > > drivers) if there is any consumers that actually relies on this, but
> > > so far the earliest consumer I have found is the
> > > drivers/irqchip/irq-renesas-irqc.c, but that's at postcore_initcall().
> > > Of course, it's difficult to say if my analysis is complete as there
> > > are a lot of platform variants and I didn't check them all.
> > >
> > > Maybe we should just give it a try and move both two drivers above to
> > > postcore_initcall and see if it works (assuming the irq-renesas-irqc
> > > supports -EPROBE_DEFER correctly too).
> > >
> > > If this doesn't work, I think we need to find a way to allow deferring
> > > the call to device_add() in of_genpd_provider_add*() for genpd
> > > provider's devices.
> >
> > Commit dcc09fd143bb97c2 ("soc: renesas: rcar-sysc: Add DT support for
> > SYSC PM domains") explains:
> >
> >    "Initialization is done from an early_initcall(), to make sure the PM
> >     Domains are initialized before secondary CPU bringup."
> >
> > but that matters only for arm32 systems (R-Car Gen1 and Gen2).
> > Arm64 systems (R-Car Gen3 and Gen4) use PSCI for CPU PM Domain control.
>
> Geert, thanks a lot for providing these details and helping out, much
> appreciated!
>
> > While changing rcar-sysc.c to use a postcore_initcall indeed moves PM
> > Domain initialization after secondary CPU bringup, the second CPU core
> > on R-Car M2-W is still brought up fine.

To rule out relying on anything being enabled by the bootloader,
I offlined the second CPU, and booted the kernel using kexec.
The second CPU still comes up fine.  Which is not that unsurprising,
as rcar-sysc.c ignores domains with the PD_CPU flag...

> > For R-Car H1, there is a regression:
> >
> >     smp: Bringing up secondary CPUs ...
> >     CPU1: failed to boot: -19
> >     CPU2: failed to boot: -19
> >     CPU3: failed to boot: -19
> >     smp: Brought up 1 node, 1 CPU
> >     SMP: Total of 1 processors activated (500.00 BogoMIPS).
> >
> > CPU bringup/teardown in userspace using
> > /sys/devices/system/cpu/cpu*/online still works.
> > R-Car H1 was never converted to use "enable-method" in DT, and relies
> > on calling into the rcar-sysc driver directly (see [1]).  However,
> > that does not use any actual calls into the genpd core, so probably it
> > can be made to work by splitting rcar_sysc_pd_init() in two parts: an
> > early_initcall() that allocates all domain structures and populates the
> > internal hierarchy, and a postcore_initcall() that registers everything
> > with the genpd core.
>
> Yes, that seems like a viable option.

... so it's just R-Car H1 that needs some code to run early.

> Unless you prefer to have a stab at it, I intend to look into it and
> make the patch(es) part of a new version of the $subject series. Of
> course I am still relying on your help with testing/review.

Sure, I will do testing and review.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 08/21] cpuidle: riscv-sbi: Opt-out from genpd's common ->sync_state() support
  2025-05-23 13:40 ` [PATCH v2 08/21] cpuidle: riscv-sbi: " Ulf Hansson
@ 2025-08-10 21:12   ` patchwork-bot+linux-riscv
  0 siblings, 0 replies; 36+ messages in thread
From: patchwork-bot+linux-riscv @ 2025-08-10 21:12 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-riscv, saravanak, sboyd, linux-pm, rafael, gregkh,
	m.grzeschik, andersson, abel.vesa, peng.fan, tomi.valkeinen,
	johan, maulik.shah, michal.simek, konradybcio, thierry.reding,
	jonathanh, linux-arm-kernel, linux-kernel, anup

Hello:

This series was applied to riscv/linux.git (fixes)
by Ulf Hansson <ulf.hansson@linaro.org>:

On Fri, 23 May 2025 15:40:05 +0200 you wrote:
> The riscv-sbi-domain implements its own specific ->sync_state() callback.
> Let's set the GENPD_FLAG_NO_SYNC_STATE to inform genpd about it.
> 
> Moreover, let's call of_genpd_sync_state() to make sure genpd tries to
> power off unused PM domains.
> 
> Cc: Anup Patel <anup@brainfault.org>
> Cc: linux-riscv@lists.infradead.org
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> 
> [...]

Here is the summary with links:
  - [v2,08/21] cpuidle: riscv-sbi: Opt-out from genpd's common ->sync_state() support
    https://git.kernel.org/riscv/c/ee766b017586
  - [v2,21/21] cpuidle: riscv-sbi: Drop redundant sync_state support
    https://git.kernel.org/riscv/c/eb34a0b5fee7

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2025-08-10 21:22 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-23 13:39 [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Ulf Hansson
2025-05-23 13:39 ` [PATCH v2 01/21] pmdomain: core: Use of_fwnode_handle() Ulf Hansson
2025-06-11  6:07   ` Dhruva Gole
2025-05-23 13:39 ` [PATCH v2 02/21] pmdomain: core: Add a bus and a driver for genpd providers Ulf Hansson
2025-06-03  0:23   ` Saravana Kannan
2025-06-03 10:28     ` Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 03/21] pmdomain: core: Add the genpd->dev to the genpd provider bus Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 04/21] pmdomain: core: Export a common ->sync_state() helper for genpd providers Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 05/21] pmdomain: core: Prepare to add the common ->sync_state() support Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 06/21] soc/tegra: pmc: Opt-out from genpd's " Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 07/21] cpuidle: psci: " Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 08/21] cpuidle: riscv-sbi: " Ulf Hansson
2025-08-10 21:12   ` patchwork-bot+linux-riscv
2025-05-23 13:40 ` [PATCH v2 09/21] pmdomain: qcom: rpmhpd: Use of_genpd_sync_state() Ulf Hansson
2025-05-23 19:42   ` Konrad Dybcio
2025-05-26 10:12     ` Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 10/21] " Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 11/21] firmware/pmdomain: xilinx: Move ->sync_state() support to firmware driver Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 12/21] firmware: xilinx: Don't share zynqmp_pm_init_finalize() Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 13/21] firmware: xilinx: Use of_genpd_sync_state() Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 14/21] driver core: Export get_dev_from_fwnode() Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 15/21] pmdomain: core: Add common ->sync_state() support for genpd providers Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 16/21] driver core: Add dev_set_drv_sync_state() Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 17/21] pmdomain: core: Default to use of_genpd_sync_state() for genpd providers Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 18/21] pmdomain: core: Leave powered-on genpds on until late_initcall_sync Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 19/21] pmdomain: core: Leave powered-on genpds on until sync_state Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 20/21] cpuidle: psci: Drop redundant sync_state support Ulf Hansson
2025-05-23 13:40 ` [PATCH v2 21/21] cpuidle: riscv-sbi: " Ulf Hansson
2025-06-03 14:20 ` [PATCH v2 00/21] pmdomain: Add generic ->sync_state() support to genpd Hiago De Franco
2025-06-12  6:09 ` Tomi Valkeinen
     [not found] ` <fd4cfe7a-e29b-4237-b82f-48354deead3b@ideasonboard.com>
2025-06-19 11:40   ` Ulf Hansson
2025-06-23 14:20     ` Ulf Hansson
2025-06-23 15:06       ` Geert Uytterhoeven
2025-06-24 12:10         ` Geert Uytterhoeven
2025-06-24 15:29         ` Ulf Hansson
2025-06-30  9:31           ` Geert Uytterhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).