linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: "Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>,
	Kevin Hilman <khilman-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Subject: [RFC PATCH 2/3] PM / Domains: Add support for devices with multiple domains
Date: Tue, 20 Sep 2016 11:28:06 +0100	[thread overview]
Message-ID: <1474367287-10402-3-git-send-email-jonathanh@nvidia.com> (raw)
In-Reply-To: <1474367287-10402-1-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Some devices may require more than one PM domain to operate and this is
not currently by the PM domain framework. Furthermore, the current Linux
'device' structure only allows devices to be associated with a single PM
domain and so cannot easily be associated with more than one. To allow
devices to be associated with more than one PM domain, if multiple
domains are defined for a given device (eg. via device-tree), then:
1. Create a new PM domain for this device. The name of the new PM domain
   created matches the device name for which it was created for.
2. Register the new PM domain as a sub-domain for all PM domains
   required by the device.
3. Attach the device to the new PM domain.

By default the newly created PM domain is assumed to be in the 'off'
state to ensure that any parent PM domains will be turned on if not
already on when the new PM domain is turned on.

When a device associated with more than one PM domain is detached,
wait for any power-off work to complete, then remove the PM domain that
was created for the device by calling pm_genpd_remove() (this also
removes it as a child to any other PM domains) and free the memory
for the PM domain.

For devices using device-tree, devices that require multiple PM domains
are detected by seeing if the 'power-domains' property has more than one
entry defined.

Signed-off-by: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---

Here is an example output from pm_genpd_summary following this change
for the Tegra210 XHCI device:

domain                          status          slaves
    /device                                             runtime status
----------------------------------------------------------------------
70090000.usb                    on
    /devices/platform/70090000.usb                      unsupported
xusbc                           on              70090000.usb
xusbb                           off-0
xusba                           on              70090000.usb

I am not sure if this is confusing to have a device and domain with the
same name. So let me know if you have any thoughts!


 drivers/base/power/domain.c | 102 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 88 insertions(+), 14 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 382735949591..ee39824c03b3 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1826,7 +1826,7 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
 {
 	struct generic_pm_domain *pd;
 	unsigned int i;
-	int ret = 0;
+	int count, ret = 0;
 
 	pd = genpd_lookup_dev(dev);
 	if (!pd)
@@ -1851,6 +1851,19 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
 
 	/* Check if PM domain can be powered off after removing this device. */
 	genpd_queue_power_off_work(pd);
+
+	count = of_count_phandle_with_args(dev->of_node, "power-domains",
+					   "#power-domain-cells");
+	if (count > 1) {
+		cancel_work_sync(&pd->power_off_work);
+
+		ret = pm_genpd_remove(pd);
+		if (ret < 0)
+			dev_err(dev, "failed to remove PM domain %s: %d\n",
+				pd->name, ret);
+
+		kfree(pd);
+	}
 }
 
 static void genpd_dev_pm_sync(struct device *dev)
@@ -1898,6 +1911,73 @@ static int genpd_dev_pm_attach_device(struct device *dev,
 
 }
 
+static int genpd_dev_pm_attach_one(struct device *dev)
+{
+	struct generic_pm_domain *pd;
+	int ret;
+
+	mutex_lock(&gpd_list_lock);
+	pd = genpd_dev_pm_lookup(dev, 0);
+	if (IS_ERR(pd)) {
+		mutex_unlock(&gpd_list_lock);
+		return PTR_ERR(pd);
+	}
+
+	ret = genpd_dev_pm_attach_device(dev, pd);
+	mutex_unlock(&gpd_list_lock);
+
+	return ret;
+}
+
+static int genpd_dev_pm_attach_many(struct device *dev, unsigned int count)
+{
+	struct generic_pm_domain *pd, *parent;
+	unsigned int i;
+	int ret;
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+
+	pd->name = dev_name(dev);
+
+	ret = pm_genpd_init(pd, NULL, true);
+	if (ret < 0)
+		goto err_free;
+
+	mutex_lock(&gpd_list_lock);
+	for (i = 0; i < count; i++) {
+		parent = genpd_dev_pm_lookup(dev, i);
+		if (IS_ERR(parent)) {
+			ret = PTR_ERR(parent);
+			goto err_remove;
+		}
+
+		ret = genpd_add_subdomain(parent, pd);
+		if (ret < 0)
+			goto err_remove;
+
+	}
+
+	ret = genpd_dev_pm_attach_device(dev, pd);
+	if (ret < 0)
+		goto err_remove;
+
+	mutex_unlock(&gpd_list_lock);
+
+	return ret;
+
+err_remove:
+	WARN_ON(genpd_remove(pd));
+
+	mutex_unlock(&gpd_list_lock);
+
+err_free:
+	kfree(pd);
+
+	return ret;
+}
+
 /**
  * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
  * @dev: Device to attach.
@@ -1915,8 +1995,7 @@ static int genpd_dev_pm_attach_device(struct device *dev,
  */
 int genpd_dev_pm_attach(struct device *dev)
 {
-	struct generic_pm_domain *pd;
-	int ret;
+	int count;
 
 	if (!dev->of_node)
 		return -ENODEV;
@@ -1924,17 +2003,12 @@ int genpd_dev_pm_attach(struct device *dev)
 	if (dev->pm_domain)
 		return -EEXIST;
 
-	mutex_lock(&gpd_list_lock);
-	pd = genpd_dev_pm_lookup(dev, 0);
-	if (IS_ERR(pd)) {
-		mutex_unlock(&gpd_list_lock);
-		return -EPROBE_DEFER;
-	}
-
-	ret = genpd_dev_pm_attach_device(dev, pd);
-	mutex_lock(&gpd_list_lock);
-
-	return ret;
+	count = of_count_phandle_with_args(dev->of_node, "power-domains",
+					   "#power-domain-cells");
+	if (count > 1)
+		return genpd_dev_pm_attach_many(dev, count);
+	else
+		return genpd_dev_pm_attach_one(dev);
 }
 EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
-- 
2.1.4

  parent reply	other threads:[~2016-09-20 10:28 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-20 10:28 [RFC PATCH 0/3] PM / Domains: Add support for devices that require multiple domains Jon Hunter
2016-09-20 10:28 ` [RFC PATCH 1/3] PM / Domains: Add helper functions for finding and attaching PM domains Jon Hunter
     [not found] ` <1474367287-10402-1-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-09-20 10:28   ` Jon Hunter [this message]
2016-09-20 17:54     ` [RFC PATCH 2/3] PM / Domains: Add support for devices with multiple domains Jon Hunter
2016-09-21  8:53     ` Geert Uytterhoeven
2016-09-21 10:01       ` Jon Hunter
     [not found]       ` <CAMuHMdVc+EjkbcpPKyzbCfDjp65gF3xP3bhkjh6SKLt6KDTtXg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-09-21 14:37         ` Jon Hunter
     [not found]           ` <658004af-e4f4-8b0c-cdc1-43661d331d70-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-09-21 14:57             ` Geert Uytterhoeven
2016-09-23 12:57               ` Jon Hunter
     [not found]                 ` <1c217cf4-8682-8e6d-6958-419923e995cd-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-09-23 14:27                   ` Geert Uytterhoeven
2016-09-30  8:05                     ` Jon Hunter
2016-10-07  9:14     ` Kevin Hilman
     [not found]       ` <7hlgy0frlb.fsf-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2016-10-10 11:24         ` Jon Hunter
2016-09-20 10:28 ` [RFC PATCH 3/3] dt-bindings: Add support for devices with multiple PM domains Jon Hunter
2016-10-06  6:04 ` [RFC PATCH 0/3] PM / Domains: Add support for devices that require multiple domains Rajendra Nayak
2016-10-06  8:25   ` Jon Hunter
2016-10-06  8:43     ` Rajendra Nayak
2016-10-31 10:44       ` Jon Hunter
2016-11-02  8:56         ` Rajendra Nayak
     [not found]           ` <5819AA42.5060603-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-16 13:11             ` Ulf Hansson
     [not found]               ` <CAPDyKFpdRzDotofr+0F6gfuWg4hHikEfmxS2aM2D+hmq_JpHRA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-11-17  2:31                 ` Rajendra Nayak
2016-11-17 15:39                   ` Stanimir Varbanov
     [not found]                     ` <4bafcd71-edc9-9ddd-d8c4-093e4d9c58db-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-11-22 13:05                       ` Ulf Hansson
2016-11-23  3:48                         ` Rajendra Nayak
2016-10-06 12:22 ` Ulf Hansson
2016-10-10 11:18   ` Jon Hunter
     [not found]     ` <90faea7d-65b6-590a-83f1-24fcdffa0569-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-10-10 14:04       ` Ulf Hansson
2016-10-11  9:15         ` Jon Hunter
     [not found]           ` <fd7c8f40-2a9f-b71c-bd11-43ee657441ae-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-11-03 14:20             ` Jon Hunter
2016-11-16 10:48               ` Jon Hunter
     [not found]                 ` <d961715d-820a-dd63-e3a9-c908ce465582-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-11-16 12:53                   ` Rafael J. Wysocki
2016-11-22 11:12                     ` Jon Hunter
     [not found]                       ` <d9a4c1cd-6682-663d-e30d-cc85f665cf64-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-11-22 13:31                         ` Ulf Hansson
2016-11-22 14:28                           ` Jon Hunter
2016-11-22 18:26                       ` Kevin Hilman
2016-11-22 18:41                         ` Jon Hunter
2016-11-24  2:30                           ` Stephen Boyd
     [not found]                             ` <20161124023014.GK6095-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-29 11:33                               ` Marek Szyprowski
     [not found]                                 ` <52af1977-8ca3-40d1-43bb-920c5b933f94-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2016-12-15 11:38                                   ` Jon Hunter
2016-11-22 21:55                         ` Rafael J. Wysocki
     [not found]                           ` <CAJZ5v0gUO8TqxbyLh37mfvoTLY1y1Uj91i9T6zcx5A9SmmcReA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-11-23  9:29                             ` Jon Hunter
     [not found]                               ` <82802459-8292-efb7-ac23-733de8687d51-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-11-23 13:15                                 ` Rafael J. Wysocki
2017-02-28 15:18 ` Jon Hunter
2017-02-28 15:29   ` Geert Uytterhoeven
     [not found]     ` <CAMuHMdUAN+PHr_GSvyMzA8N6LgzPEXhQyG_rSwFUOvc9_v7JiA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-13  9:37       ` Jon Hunter
     [not found]         ` <f4b3a93e-e29f-6fc6-6e7f-8c51081cbe15-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2017-03-13 11:45           ` Ulf Hansson
     [not found]             ` <CAPDyKFp20tDickB9mF1ZSRUvYBEsfATysENeMzGV9O8KXH2wig-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-13 14:09               ` Jon Hunter
2017-03-13 14:19                 ` Geert Uytterhoeven
2017-03-13 14:27                   ` Jon Hunter
     [not found]                     ` <161ee6b9-7a76-c7b4-3cb4-06259fef4898-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2017-03-13 14:38                       ` Geert Uytterhoeven
2017-03-13 14:51                         ` Jon Hunter
     [not found]                 ` <3e88692d-613b-9c25-2554-7d399c45637a-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2017-03-13 14:42                   ` Ulf Hansson
     [not found]                     ` <CAPDyKFp6wWZghMuCV5iL=zA=u+m22ibtzB95ktzOPJjfRLi1eg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-15  8:57                       ` Jon Hunter
2017-03-15  3:47                   ` Nayak, Rajendra
2017-03-15  9:03                     ` Jon Hunter
2017-03-01  6:19   ` Rajendra Nayak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1474367287-10402-3-git-send-email-jonathanh@nvidia.com \
    --to=jonathanh-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
    --cc=khilman-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org \
    --cc=ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).