Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1487213 > unrolled thread

[RFC PATCH 0/3] PM / Domains: Add support for devices that require multiple domains

Started byJon Hunter <jonathanh@nvidia.com>
First post2016-09-20 12:30 +0200
Last post2016-09-20 12:30 +0200
Articles 3 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [RFC PATCH 0/3] PM / Domains: Add support for devices that require multiple domains Jon Hunter <jonathanh@nvidia.com> - 2016-09-20 12:30 +0200
    [RFC PATCH 3/3] dt-bindings: Add support for devices with multiple PM domains Jon Hunter <jonathanh@nvidia.com> - 2016-09-20 12:30 +0200
    [RFC PATCH 1/3] PM / Domains: Add helper functions for finding and attaching PM domains Jon Hunter <jonathanh@nvidia.com> - 2016-09-20 12:30 +0200

#1487213 — [RFC PATCH 0/3] PM / Domains: Add support for devices that require multiple domains

FromJon Hunter <jonathanh@nvidia.com>
Date2016-09-20 12:30 +0200
Subject[RFC PATCH 0/3] PM / Domains: Add support for devices that require multiple domains
Message-ID<sjqtk-1J4-11@gated-at.bofh.it>
The Tegra124/210 XUSB subsystem (that consists of both host and device
controllers) is partitioned across 3 PM domains which are:
- XUSBA: Superspeed logic (for USB 3.0)
- XUSBB: Device controller
- XUSBC: Host controller

These power domains are not nested and can be powered-up and down
independently of one another. In practice different scenarios require
different combinations of the power domains, for example:
- Superspeed host: XUSBA and XUSBC
- Superspeed device: XUSBA and XUSBB

Although it could be possible to logically nest both the XUSBB and XUSBC
domains under the XUSBA, superspeed may not always be used/required and
so this would keep it on unnecessarily.

Given that Tegra uses device-tree for describing the hardware, it would
be ideal that the device-tree 'power-domains' property for generic PM
domains could be extended to allow more than one PM domain to be
specified. For example, define the following the Tegra210 xHCI device ...

	usb@70090000 {
		compatible = "nvidia,tegra210-xusb";
		...
		power-domains = <&pd_xusbhost>, <&pd_xusbss>;
	};

This RFC extends the generic PM domain framework to allow a device to
define more than one PM domain in the device-tree 'power-domains'
property.

Jon Hunter (3):
  PM / Domains: Add helper functions for finding and attaching PM
    domains
  PM / Domains: Add support for devices with multiple domains
  dt-bindings: Add support for devices with multiple PM domains

 .../devicetree/bindings/power/power_domain.txt     |   5 +-
 drivers/base/power/domain.c                        | 205 +++++++++++++++------
 2 files changed, 155 insertions(+), 55 deletions(-)

-- 
2.1.4

[toc] | [next] | [standalone]


#1487216 — [RFC PATCH 3/3] dt-bindings: Add support for devices with multiple PM domains

FromJon Hunter <jonathanh@nvidia.com>
Date2016-09-20 12:30 +0200
Subject[RFC PATCH 3/3] dt-bindings: Add support for devices with multiple PM domains
Message-ID<sjqtk-1J4-19@gated-at.bofh.it>
In reply to#1487213
Now that the generic PM domain framework supports devices that require
multiple PM domains, update the device-tree binding for generic PM
domains to state that one or more PM domain is permitted for a device.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 Documentation/devicetree/bindings/power/power_domain.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
index 025b5e7df61c..12131159b605 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -20,8 +20,9 @@ Required properties:
    as specified by device tree binding documentation of particular provider.
 
 Optional properties:
- - power-domains : A phandle and PM domain specifier as defined by bindings of
-                   the power controller specified by phandle.
+ - power-domains : An array of one or more PM domain specifiers (defined by the
+		   bindings of the PM domain provider) for each PM domain that
+		   is required by the device.
    Some power domains might be powered from another power domain (or have
    other hardware specific dependencies). For representing such dependency
    a standard PM domain consumer binding is used. When provided, all domains
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1487217 — [RFC PATCH 1/3] PM / Domains: Add helper functions for finding and attaching PM domains

FromJon Hunter <jonathanh@nvidia.com>
Date2016-09-20 12:30 +0200
Subject[RFC PATCH 1/3] PM / Domains: Add helper functions for finding and attaching PM domains
Message-ID<sjqtk-1J4-33@gated-at.bofh.it>
In reply to#1487213
In preparation for supporting devices that require more than one PM
domain, move the code for finding and attaching PM domains into local
helper functions.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/base/power/domain.c | 121 ++++++++++++++++++++++++++------------------
 1 file changed, 73 insertions(+), 48 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index b0cf46dcae73..382735949591 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1779,6 +1779,41 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_genpd_remove_last);
 
+static struct generic_pm_domain *genpd_dev_pm_lookup(struct device *dev,
+						     unsigned int index)
+{
+	struct of_phandle_args pd_args;
+	struct generic_pm_domain *pd;
+	int ret;
+
+	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
+					 "#power-domain-cells", index, &pd_args);
+	if (ret < 0) {
+		if (ret != -ENOENT)
+			return ERR_PTR(ret);
+
+		/*
+		 * Try legacy Samsung-specific bindings
+		 * (for backwards compatibility of DT ABI)
+		 */
+		pd_args.args_count = 0;
+		pd_args.np = of_parse_phandle(dev->of_node,
+					      "samsung,power-domain", 0);
+		if (!pd_args.np)
+			return ERR_PTR(-ENOENT);
+	}
+
+	pd = genpd_get_from_provider(&pd_args);
+	of_node_put(pd_args.np);
+	if (IS_ERR(pd)) {
+		dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
+			__func__, PTR_ERR(pd));
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return pd;
+}
+
 /**
  * genpd_dev_pm_detach - Detach a device from its PM domain.
  * @dev: Device to detach.
@@ -1829,6 +1864,40 @@ static void genpd_dev_pm_sync(struct device *dev)
 	genpd_queue_power_off_work(pd);
 }
 
+static int genpd_dev_pm_attach_device(struct device *dev,
+				      struct generic_pm_domain *pd)
+{
+	unsigned int i;
+	int ret;
+
+	dev_dbg(dev, "adding to PM domain %s\n", pd->name);
+
+	for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
+		ret = genpd_add_device(pd, dev, NULL);
+		if (ret != -EAGAIN)
+			break;
+
+		mdelay(i);
+		cond_resched();
+	}
+
+	if (ret < 0) {
+		dev_err(dev, "failed to add to PM domain %s: %d",
+			pd->name, ret);
+		goto out;
+	}
+
+	dev->pm_domain->detach = genpd_dev_pm_detach;
+	dev->pm_domain->sync = genpd_dev_pm_sync;
+
+	mutex_lock(&pd->lock);
+	ret = genpd_poweron(pd, 0);
+	mutex_unlock(&pd->lock);
+out:
+	return ret ? -EPROBE_DEFER : 0;
+
+}
+
 /**
  * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
  * @dev: Device to attach.
@@ -1846,9 +1915,7 @@ static void genpd_dev_pm_sync(struct device *dev)
  */
 int genpd_dev_pm_attach(struct device *dev)
 {
-	struct of_phandle_args pd_args;
 	struct generic_pm_domain *pd;
-	unsigned int i;
 	int ret;
 
 	if (!dev->of_node)
@@ -1857,59 +1924,17 @@ int genpd_dev_pm_attach(struct device *dev)
 	if (dev->pm_domain)
 		return -EEXIST;
 
-	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
-					"#power-domain-cells", 0, &pd_args);
-	if (ret < 0) {
-		if (ret != -ENOENT)
-			return ret;
-
-		/*
-		 * Try legacy Samsung-specific bindings
-		 * (for backwards compatibility of DT ABI)
-		 */
-		pd_args.args_count = 0;
-		pd_args.np = of_parse_phandle(dev->of_node,
-						"samsung,power-domain", 0);
-		if (!pd_args.np)
-			return -ENOENT;
-	}
-
 	mutex_lock(&gpd_list_lock);
-	pd = genpd_get_from_provider(&pd_args);
-	of_node_put(pd_args.np);
+	pd = genpd_dev_pm_lookup(dev, 0);
 	if (IS_ERR(pd)) {
 		mutex_unlock(&gpd_list_lock);
-		dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
-			__func__, PTR_ERR(pd));
 		return -EPROBE_DEFER;
 	}
 
-	dev_dbg(dev, "adding to PM domain %s\n", pd->name);
-
-	for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
-		ret = genpd_add_device(pd, dev, NULL);
-		if (ret != -EAGAIN)
-			break;
-
-		mdelay(i);
-		cond_resched();
-	}
-	mutex_unlock(&gpd_list_lock);
-
-	if (ret < 0) {
-		dev_err(dev, "failed to add to PM domain %s: %d",
-			pd->name, ret);
-		goto out;
-	}
-
-	dev->pm_domain->detach = genpd_dev_pm_detach;
-	dev->pm_domain->sync = genpd_dev_pm_sync;
+	ret = genpd_dev_pm_attach_device(dev, pd);
+	mutex_lock(&gpd_list_lock);
 
-	mutex_lock(&pd->lock);
-	ret = genpd_poweron(pd, 0);
-	mutex_unlock(&pd->lock);
-out:
-	return ret ? -EPROBE_DEFER : 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
-- 
2.1.4

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web