[RFC PATCH 1/2] PM: domains: Honour PD_FLAG_ATTACH_POWER_ON for genpd
From: Beleswar Padhi
Date: Tue Oct 27 2026 - 10:17:22 EST
dev_pm_domain_attach() takes PD_FLAG_ATTACH_POWER_ON to let the caller
decide whether the PM domain is powered on during attach. But, only the
ACPI path honours it today. genpd_dev_pm_attach() takes no flags and
always powers on the domain, so a DT based device cannot be attached to
its PM domain without powering it on.
Add a power_on argument to genpd_dev_pm_attach() and pass it on to
__genpd_dev_pm_attach(), which already supports it for the multiple PM
domains case.
Signed-off-by: Beleswar Padhi <b-padhi@xxxxxx>
---
drivers/base/power/common.c | 5 +++--
drivers/pmdomain/core.c | 5 +++--
include/linux/pm_domain.h | 4 ++--
3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
index 9bef9248a7052..3263659c58dc8 100644
--- a/drivers/base/power/common.c
+++ b/drivers/base/power/common.c
@@ -102,14 +102,15 @@ EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
*/
int dev_pm_domain_attach(struct device *dev, u32 flags)
{
+ bool power_on = !!(flags & PD_FLAG_ATTACH_POWER_ON);
int ret;
if (dev->pm_domain)
return 0;
- ret = acpi_dev_pm_attach(dev, !!(flags & PD_FLAG_ATTACH_POWER_ON));
+ ret = acpi_dev_pm_attach(dev, power_on);
if (!ret)
- ret = genpd_dev_pm_attach(dev);
+ ret = genpd_dev_pm_attach(dev, power_on);
if (dev->pm_domain)
dev->power.detach_power_off = !!(flags & PD_FLAG_DETACH_POWER_OFF);
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 964e44c2f78f1..785c27491aad5 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -3553,6 +3553,7 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
/**
* genpd_dev_pm_attach - Attach a device to its PM domain using DT.
* @dev: Device to attach.
+ * @power_on: Whether to power on the PM domain during attach.
*
* Parse device's OF node to find a PM domain specifier. If such is found,
* attaches the device to retrieved pm_domain ops.
@@ -3563,7 +3564,7 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
* found or turned on, then return -EPROBE_DEFER to ensure that the device is
* not probed and to re-try again later.
*/
-int genpd_dev_pm_attach(struct device *dev)
+int genpd_dev_pm_attach(struct device *dev, bool power_on)
{
if (!dev->of_node)
return 0;
@@ -3576,7 +3577,7 @@ int genpd_dev_pm_attach(struct device *dev)
"#power-domain-cells") != 1)
return 0;
- return __genpd_dev_pm_attach(dev, dev, 0, 1, true);
+ return __genpd_dev_pm_attach(dev, dev, 0, 1, power_on);
}
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 14e0e346c610a..010fbfffee39d 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -481,7 +481,7 @@ int of_genpd_add_child_ids(struct device_node *np,
int of_genpd_remove_child_ids(struct device_node *np,
struct genpd_onecell_data *data);
-int genpd_dev_pm_attach(struct device *dev);
+int genpd_dev_pm_attach(struct device *dev, bool power_on);
struct device *genpd_dev_pm_attach_by_id(struct device *dev,
unsigned int index);
struct device *genpd_dev_pm_attach_by_name(struct device *dev,
@@ -527,7 +527,7 @@ static inline int of_genpd_parse_idle_states(struct device_node *dn,
static inline void of_genpd_sync_state(struct device_node *np) {}
-static inline int genpd_dev_pm_attach(struct device *dev)
+static inline int genpd_dev_pm_attach(struct device *dev, bool power_on)
{
return 0;
}
--
2.34.1