On Mon, Mar 2, 2020 at 12:59 PM Daniel Baluta daniel.baluta@oss.nxp.com wrote:
From: Daniel Baluta daniel.baluta@nxp.com
This patch introduces helpers support for multi PM domains.
API consists of:
- dev_multi_pm_attach - powers up all PM domains associated with a given
device. Because we can attach one PM domain per device, we create virtual devices (children of initial device) and associate PM domains one per virtual device.
- dev_multi_pm_detach - detaches all virtual devices from PM domains
attached with.
Signed-off-by: Daniel Baluta daniel.baluta@nxp.com
drivers/base/power/common.c | 93 +++++++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 19 ++++++++ 2 files changed, 112 insertions(+)
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index bbddb267c2e6..a90cc6b476e4 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c @@ -228,3 +228,96 @@ void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd) device_pm_check_callbacks(dev); } EXPORT_SYMBOL_GPL(dev_pm_domain_set);
+/**
- dev_multi_pm_attach - power up device associated power domains
- @dev: The device used to lookup the PM domains
- Parse device's OF node to find all PM domains specifiers. For each
power
- domain found, create a virtual device and associate it with the
- current power domain.
- This function should typically be invoked by a driver during the
- probe phase, in the case its device requires power management through
- multiple PM domains.
- Returns a pointer to @dev_multi_pm_domain_data if successfully
attached PM
- domains, NULL if 0 or 1 PM domains specified, else an ERR_PTR() in
case of
- failures.
- */
+struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) +{
struct dev_multi_pm_domain_data *mpd, *retp;
int num_domains;
int i;
num_domains = of_count_phandle_with_args(dev->of_node,
"power-domains",
"#power-domain-cells");
if (num_domains < 2)
Hi Daniel,
Just out of curiosity, should it be an error when num_domains is 1? Is it an error because the expectation is that the caller would use dev_pm_domain_attach() in that case?
+ return NULL;
mpd = devm_kzalloc(dev, GFP_KERNEL, sizeof(*mpd));
if (!mpd)
return ERR_PTR(-ENOMEM);
mpd->dev = dev;
mpd->num_domains = num_domains;
mpd->virt_devs = devm_kmalloc_array(dev, mpd->num_domains,
sizeof(*mpd->virt_devs),
GFP_KERNEL);
if (!mpd->virt_devs)
return ERR_PTR(-ENOMEM);
mpd->links = devm_kmalloc_array(dev, mpd->num_domains,
sizeof(*mpd->links), GFP_KERNEL);
if (!mpd->links)
return ERR_PTR(-ENOMEM);
for (i = 0; i < mpd->num_domains; i++) {
mpd->virt_devs[i] = dev_pm_domain_attach_by_id(dev, i);
if (IS_ERR(mpd->virt_devs[i])) {
retp = (struct dev_multi_pm_domain_data *)
mpd->virt_devs[i];
Should retp be PTR_ERR(mpd->virt_devs[i]) here? Thanks, Ranjani