All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] PM / Domains: Generic OF-based support
@ 2014-08-26 12:07 ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Ulf Hansson

This patchset has a bit of a history and some parts of it has been posted
earlier.

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/262725.html

I intentially didn't increase version number of the patches, since I think it
will cause more confusion than clarity.

A summary of changes since the last patchset (link above):
	- Instead of letting driver core handling the device to power domain
	binding/unbinding, follow the behavior of how the ACPI power domain
	is handled.


This is a summary of what these patches are intended to do:

1)
Add generic power domain OF-based support which also includes APIs to handle
attach/detach of generic power domains to devices.

2)
Adding a common API to attach/detach power domains and include support for the
ACPI and the generic power domain in there.

3)
>From subsystem level code, at probe/remove, convert from invoking the ACPI
specific power domain attach/detach functions to the new common attach/detach
APIs.

4)
Add support for the AMBA bus to attach/detach power domains, using the new
common APIs.

5)
Convert Exynos to use the new generic power domain OF support.

Obviously, there are dependencies througout this patchset, which means if they
get accepted the all need to go together.


Tomasz Figa (2):
  PM / Domains: Add generic OF-based power domain look-up
  ARM: exynos: Move to generic power domain bindings

Ulf Hansson (7):
  ACPI / PM: Let acpi_dev_pm_detach() return an error code
  PM / Domains: Add APIs to attach/detach a power domain for a device
  drivercore / platform: Convert to dev_pm_domain_attach|detach()
  i2c: core: Convert to dev_pm_domain_attach|detach()
  mmc: sdio: Convert to dev_pm_domain_attach|detach()
  spi: core: Convert to dev_pm_domain_attach|detach()
  amba: Add support for attach/detach of power domains

 .../bindings/arm/exynos/power_domain.txt           |  13 +-
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 arch/arm/mach-exynos/pm_domains.c                  |  78 +-----
 drivers/acpi/device_pm.c                           |   4 +
 drivers/amba/bus.c                                 |  10 +-
 drivers/base/platform.c                            |  15 +-
 drivers/base/power/common.c                        |  58 ++++
 drivers/base/power/domain.c                        | 291 +++++++++++++++++++++
 drivers/i2c/i2c-core.c                             |  13 +-
 drivers/mmc/core/sdio_bus.c                        |   4 +-
 drivers/spi/spi.c                                  |  12 +-
 include/linux/acpi.h                               |   7 +-
 include/linux/pm.h                                 |  14 +
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 15 files changed, 514 insertions(+), 106 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt

-- 
1.9.1


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

* [PATCH 0/9] PM / Domains: Generic OF-based support
@ 2014-08-26 12:07 ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset has a bit of a history and some parts of it has been posted
earlier.

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/262725.html

I intentially didn't increase version number of the patches, since I think it
will cause more confusion than clarity.

A summary of changes since the last patchset (link above):
	- Instead of letting driver core handling the device to power domain
	binding/unbinding, follow the behavior of how the ACPI power domain
	is handled.


This is a summary of what these patches are intended to do:

1)
Add generic power domain OF-based support which also includes APIs to handle
attach/detach of generic power domains to devices.

2)
Adding a common API to attach/detach power domains and include support for the
ACPI and the generic power domain in there.

3)
>From subsystem level code, at probe/remove, convert from invoking the ACPI
specific power domain attach/detach functions to the new common attach/detach
APIs.

4)
Add support for the AMBA bus to attach/detach power domains, using the new
common APIs.

5)
Convert Exynos to use the new generic power domain OF support.

Obviously, there are dependencies througout this patchset, which means if they
get accepted the all need to go together.


Tomasz Figa (2):
  PM / Domains: Add generic OF-based power domain look-up
  ARM: exynos: Move to generic power domain bindings

Ulf Hansson (7):
  ACPI / PM: Let acpi_dev_pm_detach() return an error code
  PM / Domains: Add APIs to attach/detach a power domain for a device
  drivercore / platform: Convert to dev_pm_domain_attach|detach()
  i2c: core: Convert to dev_pm_domain_attach|detach()
  mmc: sdio: Convert to dev_pm_domain_attach|detach()
  spi: core: Convert to dev_pm_domain_attach|detach()
  amba: Add support for attach/detach of power domains

 .../bindings/arm/exynos/power_domain.txt           |  13 +-
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 arch/arm/mach-exynos/pm_domains.c                  |  78 +-----
 drivers/acpi/device_pm.c                           |   4 +
 drivers/amba/bus.c                                 |  10 +-
 drivers/base/platform.c                            |  15 +-
 drivers/base/power/common.c                        |  58 ++++
 drivers/base/power/domain.c                        | 291 +++++++++++++++++++++
 drivers/i2c/i2c-core.c                             |  13 +-
 drivers/mmc/core/sdio_bus.c                        |   4 +-
 drivers/spi/spi.c                                  |  12 +-
 include/linux/acpi.h                               |   7 +-
 include/linux/pm.h                                 |  14 +
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 15 files changed, 514 insertions(+), 106 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt

-- 
1.9.1

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

* [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Ulf Hansson

To give callers the option of acting on a errors while removing the
pm_domain ops for the device in the ACPI power domain, let
acpi_dev_pm_detach() return an int to provide the error code.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/acpi/device_pm.c | 4 ++++
 include/linux/acpi.h     | 7 +++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 67075f8..fa78abb 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
  *
  * Callers must ensure proper synchronization of this function with power
  * management callbacks.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
  */
 void acpi_dev_pm_detach(struct device *dev, bool power_off)
 {
@@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
 			acpi_device_wakeup(adev, ACPI_STATE_S0, false);
 			acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
 		}
+		return 0;
 	}
+	return -ENODEV;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
 #endif /* CONFIG_PM */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 5320153..a7bfdf6 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
 struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
 int acpi_dev_pm_attach(struct device *dev, bool power_on);
-void acpi_dev_pm_detach(struct device *dev, bool power_off);
+int acpi_dev_pm_detach(struct device *dev, bool power_off);
 #else
 static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
 {
@@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
 {
 	return -ENODEV;
 }
-static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
+static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
+{
+	return -ENODEV;
+}
 #endif
 
 #ifdef CONFIG_ACPI
-- 
1.9.1


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

* [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

To give callers the option of acting on a errors while removing the
pm_domain ops for the device in the ACPI power domain, let
acpi_dev_pm_detach() return an int to provide the error code.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/acpi/device_pm.c | 4 ++++
 include/linux/acpi.h     | 7 +++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 67075f8..fa78abb 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
  *
  * Callers must ensure proper synchronization of this function with power
  * management callbacks.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
  */
 void acpi_dev_pm_detach(struct device *dev, bool power_off)
 {
@@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
 			acpi_device_wakeup(adev, ACPI_STATE_S0, false);
 			acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
 		}
+		return 0;
 	}
+	return -ENODEV;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
 #endif /* CONFIG_PM */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 5320153..a7bfdf6 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
 struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
 int acpi_dev_pm_attach(struct device *dev, bool power_on);
-void acpi_dev_pm_detach(struct device *dev, bool power_off);
+int acpi_dev_pm_detach(struct device *dev, bool power_off);
 #else
 static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
 {
@@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
 {
 	return -ENODEV;
 }
-static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
+static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
+{
+	return -ENODEV;
+}
 #endif
 
 #ifdef CONFIG_ACPI
-- 
1.9.1

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

* [PATCH 2/9] PM / Domains: Add generic OF-based power domain look-up
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Tomasz Figa, Ulf Hansson

From: Tomasz Figa <t.figa@samsung.com>

This patch introduces generic code to perform power domain look-up using
device tree and automatically bind devices to their power domains.
Generic device tree binding is introduced to specify power domains of
devices in their device tree nodes.

Backwards compatibility with legacy Samsung-specific power domain
bindings is provided, but for now the new code is not compiled when
CONFIG_ARCH_EXYNOS is selected to avoid collision with legacy code. This
will change as soon as Exynos power domain code gets converted to use
the generic framework in further patch.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
[Ulf:Add attach|detach functions]
---
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 drivers/base/power/domain.c                        | 291 +++++++++++++++++++++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 4 files changed, 392 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
new file mode 100644
index 0000000..303d0a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -0,0 +1,51 @@
+* Generic power domains
+
+System on chip designs are often divided into multiple power domains that
+can be used for power gating of selected IP blocks for power saving by
+reduced leakage current.
+
+This device tree binding can be used to bind power domain consumer devices
+with their power domains provided by power domain providers. A power domain
+provider can be represented by any node in the device tree and can provide
+one or more power domains. A consumer node can refer to the provider by
+a phandle and a set of phandle arguments (so called power domain specifier)
+of length specified by #power-domain-cells property in the power domain
+provider node.
+
+==Power domain providers==
+
+Required properties:
+ - #power-domain-cells : Number of cells in a power domain specifier;
+   Typically 0 for nodes representing a single power domain and 1 for nodes
+   providing multiple power domains (e.g. power controllers), but can be
+   any value as specified by device tree binding documentation of particular
+   provider.
+
+Example:
+
+	power: power-controller@12340000 {
+		compatible = "foo,power-controller";
+		reg = <0x12340000 0x1000>;
+		#power-domain-cells = <1>;
+	};
+
+The node above defines a power controller that is a power domain provider
+and expects one cell as its phandle argument.
+
+==Power domain consumers==
+
+Required properties:
+ - power-domains : A phandle and power domain specifier as defined by bindings
+                   of power controller specified by phandle.
+
+Example:
+
+	leaky-device@12350000 {
+		compatible = "foo,i-leak-current";
+		reg = <0x12350000 0x1000>;
+		power-domains = <&power 0>;
+	};
+
+The node above defines a typical power domain consumer device, which is located
+inside power domain with index 0 of power controller represented by node with
+label "power".
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index eee55c1..0fb26e5 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_qos.h>
@@ -2189,3 +2190,293 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
 	list_add(&genpd->gpd_list_node, &gpd_list);
 	mutex_unlock(&gpd_list_lock);
 }
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+/*
+ * Device Tree based power domain providers.
+ *
+ * The code below implements generic device tree based power domain providers
+ * that bind device tree nodes with generic power domains registered in the
+ * system.
+ *
+ * Any driver that registers generic power domains and need to support binding
+ * of devices to these domains is supposed to register a power domain provider,
+ * which maps a power domain specifier retrieved from device tree to a power
+ * domain.
+ *
+ * Two simple mapping functions have been provided for convenience:
+ *  - of_genpd_xlate_simple() for 1:1 device tree node to domain mapping,
+ *  - of_genpd_xlate_onecell() for mapping of multiple domains per node
+ *    by index.
+ */
+
+/**
+ * struct of_genpd_provider - Power domain provider registration structure
+ * @link: Entry in global list of domain providers
+ * @node: Pointer to device tree node of domain provider
+ * @xlate: Provider-specific xlate callback mapping a set of specifier cells
+ *         into a power domain.
+ * @data: context pointer to be passed into @xlate callback
+ */
+struct of_genpd_provider {
+	struct list_head link;
+	struct device_node *node;
+	genpd_xlate_t xlate;
+	void *data;
+};
+
+/* List of registered power domain providers. */
+static LIST_HEAD(of_genpd_providers);
+/* Mutex to protect the list above. */
+static DEFINE_MUTEX(of_genpd_mutex);
+
+/**
+ * of_genpd_xlate_simple() - Xlate function for direct node-domain mapping
+ * @genpdspec: OF phandle args to map into a power domain
+ * @data: xlate function private data - pointer to struct generic_pm_domain
+ *
+ * This is a generic xlate function that can be used to model power domains
+ * that have their own device tree nodes. The private data of xlate function
+ * needs to be a valid pointer to struct generic_pm_domain.
+ */
+struct generic_pm_domain *of_genpd_xlate_simple(
+					struct of_phandle_args *genpdspec,
+					void *data)
+{
+	if (genpdspec->args_count != 0)
+		return ERR_PTR(-EINVAL);
+	return data;
+}
+EXPORT_SYMBOL_GPL(of_genpd_xlate_simple);
+
+/**
+ * of_genpd_xlate_onecell() - Xlate function for providers using single index.
+ * @genpdspec: OF phandle args to map into a power domain
+ * @data: xlate function private data - pointer to struct genpd_onecell_data
+ *
+ * This is a generic xlate function that can be used to model simple power
+ * domain controllers that have one device tree node and provide multiple
+ * power domains. A single cell is used as an index to an array of power
+ * domains specified in genpd_onecell_data struct when registering the
+ * provider.
+ */
+struct generic_pm_domain *of_genpd_xlate_onecell(
+					struct of_phandle_args *genpdspec,
+					void *data)
+{
+	struct genpd_onecell_data *genpd_data = data;
+	unsigned int idx = genpdspec->args[0];
+
+	if (genpdspec->args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	if (idx >= genpd_data->domain_num) {
+		pr_err("%s: invalid domain index %d\n", __func__, idx);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return genpd_data->domains[idx];
+}
+EXPORT_SYMBOL_GPL(of_genpd_xlate_onecell);
+
+/**
+ * of_genpd_add_provider() - Register a domain provider for a node
+ * @np: Device node pointer associated with domain provider.
+ * @xlate: Callback for decoding domain from phandle arguments.
+ * @data: Context pointer for @genpd_src_get callback.
+ */
+int of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
+			  void *data)
+{
+	struct of_genpd_provider *cp;
+
+	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
+	if (!cp)
+		return -ENOMEM;
+
+	cp->node = of_node_get(np);
+	cp->data = data;
+	cp->xlate = xlate;
+
+	mutex_lock(&of_genpd_mutex);
+	list_add(&cp->link, &of_genpd_providers);
+	mutex_unlock(&of_genpd_mutex);
+	pr_debug("Added domain provider from %s\n", np->full_name);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_genpd_add_provider);
+
+/**
+ * of_genpd_del_provider() - Remove a previously registered domain provider
+ * @np: Device node pointer associated with domain provider
+ */
+void of_genpd_del_provider(struct device_node *np)
+{
+	struct of_genpd_provider *cp;
+
+	mutex_lock(&of_genpd_mutex);
+	list_for_each_entry(cp, &of_genpd_providers, link) {
+		if (cp->node == np) {
+			list_del(&cp->link);
+			of_node_put(cp->node);
+			kfree(cp);
+			break;
+		}
+	}
+	mutex_unlock(&of_genpd_mutex);
+}
+EXPORT_SYMBOL_GPL(of_genpd_del_provider);
+
+/**
+ * of_genpd_get_from_provider() - Look-up power domain
+ * @genpdspec: OF phandle args to use for look-up
+ *
+ * Looks for domain provider under node specified by @genpdspec and if found
+ * uses xlate function of the provider to map phandle args to a power domain.
+ *
+ * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR()
+ * on failure.
+ */
+static struct generic_pm_domain *of_genpd_get_from_provider(
+					struct of_phandle_args *genpdspec)
+{
+	struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
+	struct of_genpd_provider *provider;
+
+	mutex_lock(&of_genpd_mutex);
+
+	/* Check if we have such a provider in our array */
+	list_for_each_entry(provider, &of_genpd_providers, link) {
+		if (provider->node == genpdspec->np)
+			genpd = provider->xlate(genpdspec, provider->data);
+		if (!IS_ERR(genpd))
+			break;
+	}
+
+	mutex_unlock(&of_genpd_mutex);
+
+	return genpd;
+}
+
+/**
+ * genpd_dev_pm_attach - Attach a device to it's power domain using DT.
+ * @dev: Device to attach.
+ *
+ * Parse device's OF node to find a power domain specifier. If such is found,
+ * attaches the device to retrieved pm_domain ops.
+ *
+ * Both generic and legacy Samsung-specific DT bindings are supported to
+ * keep backwards compatibility with existing DTBs.
+ *
+ * Returns 0 on successfully attached power domain or negative error code.
+ */
+int genpd_dev_pm_attach(struct device *dev)
+{
+	struct of_phandle_args pd_args;
+	struct generic_pm_domain *pd;
+	int ret;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	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;
+	}
+
+	pd = of_genpd_get_from_provider(&pd_args);
+	if (IS_ERR(pd)) {
+		dev_dbg(dev, "%s() failed to find power domain: %ld\n",
+			__func__, PTR_ERR(pd));
+		of_node_put(dev->of_node);
+		return PTR_ERR(pd);
+	}
+
+	dev_dbg(dev, "adding to power domain %s\n", pd->name);
+
+	while (1) {
+		ret = pm_genpd_add_device(pd, dev);
+		if (ret != -EAGAIN)
+			break;
+		cond_resched();
+	}
+
+	if (ret < 0) {
+		dev_err(dev, "failed to add to power domain %s: %d",
+			pd->name, ret);
+		of_node_put(dev->of_node);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
+
+/**
+ * genpd_dev_pm_detach - Detach a device from it's power domain.
+ * @dev: Device to attach.
+ *
+ * Try to locate a corresponding generic power domain, which the device
+ * then previously were attached to. If found the device is detached from
+ * the power domain.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
+ */
+int genpd_dev_pm_detach(struct device *dev)
+{
+	struct generic_pm_domain *pd = NULL, *gpd;
+	int ret = 0;
+
+	if (!dev->pm_domain)
+		return -ENODEV;
+
+	mutex_lock(&gpd_list_lock);
+	list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+		if (&gpd->domain == dev->pm_domain) {
+			pd = gpd;
+			break;
+		}
+	}
+	mutex_unlock(&gpd_list_lock);
+
+	if (!pd)
+		return -ENOENT;
+
+	dev_dbg(dev, "removing from power domain %s\n", pd->name);
+
+	while (1) {
+		ret = pm_genpd_remove_device(pd, dev);
+		if (ret != -EAGAIN)
+			break;
+		cond_resched();
+	}
+
+	if (ret < 0) {
+		dev_err(dev, "failed to remove from power domain %s: %d",
+			pd->name, ret);
+		return ret;
+	}
+
+	/* Check if domain can be powered off after removing this device. */
+	genpd_queue_power_off_work(pd);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(genpd_dev_pm_detach);
+#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 7c1d252..5989758 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -310,4 +310,50 @@ static inline void pm_genpd_syscore_poweron(struct device *dev)
 	pm_genpd_syscore_switch(dev, false);
 }
 
+/* OF power domain providers */
+struct of_device_id;
+
+struct genpd_onecell_data {
+	struct generic_pm_domain **domains;
+	unsigned int domain_num;
+};
+
+typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
+						   void *data);
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+int of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
+			  void *data);
+void of_genpd_del_provider(struct device_node *np);
+
+struct generic_pm_domain *of_genpd_xlate_simple(
+					struct of_phandle_args *genpdspec,
+					void *data);
+struct generic_pm_domain *of_genpd_xlate_onecell(
+					struct of_phandle_args *genpdspec,
+					void *data);
+
+int genpd_dev_pm_attach(struct device *dev);
+int genpd_dev_pm_detach(struct device *dev);
+#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
+static inline int of_genpd_add_provider(struct device_node *np,
+					genpd_xlate_t xlate, void *data)
+{
+	return 0;
+}
+static inline void of_genpd_del_provider(struct device_node *np) {}
+
+#define of_genpd_xlate_simple		NULL
+#define of_genpd_xlate_onecell		NULL
+
+static inline int genpd_dev_pm_attach(struct device *dev)
+{
+	return -ENODEV;
+}
+static inline int genpd_dev_pm_detach(struct device *dev)
+{
+	return -ENODEV;
+}
+#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
+
 #endif /* _LINUX_PM_DOMAIN_H */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index e4e4121..897619b 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -302,6 +302,10 @@ config PM_GENERIC_DOMAINS_RUNTIME
 	def_bool y
 	depends on PM_RUNTIME && PM_GENERIC_DOMAINS
 
+config PM_GENERIC_DOMAINS_OF
+	def_bool y
+	depends on PM_GENERIC_DOMAINS && OF && !ARCH_EXYNOS
+
 config CPU_PM
 	bool
 	depends on SUSPEND || CPU_IDLE
-- 
1.9.1


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

* [PATCH 2/9] PM / Domains: Add generic OF-based power domain look-up
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Figa <t.figa@samsung.com>

This patch introduces generic code to perform power domain look-up using
device tree and automatically bind devices to their power domains.
Generic device tree binding is introduced to specify power domains of
devices in their device tree nodes.

Backwards compatibility with legacy Samsung-specific power domain
bindings is provided, but for now the new code is not compiled when
CONFIG_ARCH_EXYNOS is selected to avoid collision with legacy code. This
will change as soon as Exynos power domain code gets converted to use
the generic framework in further patch.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
[Ulf:Add attach|detach functions]
---
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 drivers/base/power/domain.c                        | 291 +++++++++++++++++++++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 4 files changed, 392 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
new file mode 100644
index 0000000..303d0a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -0,0 +1,51 @@
+* Generic power domains
+
+System on chip designs are often divided into multiple power domains that
+can be used for power gating of selected IP blocks for power saving by
+reduced leakage current.
+
+This device tree binding can be used to bind power domain consumer devices
+with their power domains provided by power domain providers. A power domain
+provider can be represented by any node in the device tree and can provide
+one or more power domains. A consumer node can refer to the provider by
+a phandle and a set of phandle arguments (so called power domain specifier)
+of length specified by #power-domain-cells property in the power domain
+provider node.
+
+==Power domain providers==
+
+Required properties:
+ - #power-domain-cells : Number of cells in a power domain specifier;
+   Typically 0 for nodes representing a single power domain and 1 for nodes
+   providing multiple power domains (e.g. power controllers), but can be
+   any value as specified by device tree binding documentation of particular
+   provider.
+
+Example:
+
+	power: power-controller at 12340000 {
+		compatible = "foo,power-controller";
+		reg = <0x12340000 0x1000>;
+		#power-domain-cells = <1>;
+	};
+
+The node above defines a power controller that is a power domain provider
+and expects one cell as its phandle argument.
+
+==Power domain consumers==
+
+Required properties:
+ - power-domains : A phandle and power domain specifier as defined by bindings
+                   of power controller specified by phandle.
+
+Example:
+
+	leaky-device at 12350000 {
+		compatible = "foo,i-leak-current";
+		reg = <0x12350000 0x1000>;
+		power-domains = <&power 0>;
+	};
+
+The node above defines a typical power domain consumer device, which is located
+inside power domain with index 0 of power controller represented by node with
+label "power".
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index eee55c1..0fb26e5 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_qos.h>
@@ -2189,3 +2190,293 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
 	list_add(&genpd->gpd_list_node, &gpd_list);
 	mutex_unlock(&gpd_list_lock);
 }
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+/*
+ * Device Tree based power domain providers.
+ *
+ * The code below implements generic device tree based power domain providers
+ * that bind device tree nodes with generic power domains registered in the
+ * system.
+ *
+ * Any driver that registers generic power domains and need to support binding
+ * of devices to these domains is supposed to register a power domain provider,
+ * which maps a power domain specifier retrieved from device tree to a power
+ * domain.
+ *
+ * Two simple mapping functions have been provided for convenience:
+ *  - of_genpd_xlate_simple() for 1:1 device tree node to domain mapping,
+ *  - of_genpd_xlate_onecell() for mapping of multiple domains per node
+ *    by index.
+ */
+
+/**
+ * struct of_genpd_provider - Power domain provider registration structure
+ * @link: Entry in global list of domain providers
+ * @node: Pointer to device tree node of domain provider
+ * @xlate: Provider-specific xlate callback mapping a set of specifier cells
+ *         into a power domain.
+ * @data: context pointer to be passed into @xlate callback
+ */
+struct of_genpd_provider {
+	struct list_head link;
+	struct device_node *node;
+	genpd_xlate_t xlate;
+	void *data;
+};
+
+/* List of registered power domain providers. */
+static LIST_HEAD(of_genpd_providers);
+/* Mutex to protect the list above. */
+static DEFINE_MUTEX(of_genpd_mutex);
+
+/**
+ * of_genpd_xlate_simple() - Xlate function for direct node-domain mapping
+ * @genpdspec: OF phandle args to map into a power domain
+ * @data: xlate function private data - pointer to struct generic_pm_domain
+ *
+ * This is a generic xlate function that can be used to model power domains
+ * that have their own device tree nodes. The private data of xlate function
+ * needs to be a valid pointer to struct generic_pm_domain.
+ */
+struct generic_pm_domain *of_genpd_xlate_simple(
+					struct of_phandle_args *genpdspec,
+					void *data)
+{
+	if (genpdspec->args_count != 0)
+		return ERR_PTR(-EINVAL);
+	return data;
+}
+EXPORT_SYMBOL_GPL(of_genpd_xlate_simple);
+
+/**
+ * of_genpd_xlate_onecell() - Xlate function for providers using single index.
+ * @genpdspec: OF phandle args to map into a power domain
+ * @data: xlate function private data - pointer to struct genpd_onecell_data
+ *
+ * This is a generic xlate function that can be used to model simple power
+ * domain controllers that have one device tree node and provide multiple
+ * power domains. A single cell is used as an index to an array of power
+ * domains specified in genpd_onecell_data struct when registering the
+ * provider.
+ */
+struct generic_pm_domain *of_genpd_xlate_onecell(
+					struct of_phandle_args *genpdspec,
+					void *data)
+{
+	struct genpd_onecell_data *genpd_data = data;
+	unsigned int idx = genpdspec->args[0];
+
+	if (genpdspec->args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	if (idx >= genpd_data->domain_num) {
+		pr_err("%s: invalid domain index %d\n", __func__, idx);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return genpd_data->domains[idx];
+}
+EXPORT_SYMBOL_GPL(of_genpd_xlate_onecell);
+
+/**
+ * of_genpd_add_provider() - Register a domain provider for a node
+ * @np: Device node pointer associated with domain provider.
+ * @xlate: Callback for decoding domain from phandle arguments.
+ * @data: Context pointer for @genpd_src_get callback.
+ */
+int of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
+			  void *data)
+{
+	struct of_genpd_provider *cp;
+
+	cp = kzalloc(sizeof(*cp), GFP_KERNEL);
+	if (!cp)
+		return -ENOMEM;
+
+	cp->node = of_node_get(np);
+	cp->data = data;
+	cp->xlate = xlate;
+
+	mutex_lock(&of_genpd_mutex);
+	list_add(&cp->link, &of_genpd_providers);
+	mutex_unlock(&of_genpd_mutex);
+	pr_debug("Added domain provider from %s\n", np->full_name);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_genpd_add_provider);
+
+/**
+ * of_genpd_del_provider() - Remove a previously registered domain provider
+ * @np: Device node pointer associated with domain provider
+ */
+void of_genpd_del_provider(struct device_node *np)
+{
+	struct of_genpd_provider *cp;
+
+	mutex_lock(&of_genpd_mutex);
+	list_for_each_entry(cp, &of_genpd_providers, link) {
+		if (cp->node == np) {
+			list_del(&cp->link);
+			of_node_put(cp->node);
+			kfree(cp);
+			break;
+		}
+	}
+	mutex_unlock(&of_genpd_mutex);
+}
+EXPORT_SYMBOL_GPL(of_genpd_del_provider);
+
+/**
+ * of_genpd_get_from_provider() - Look-up power domain
+ * @genpdspec: OF phandle args to use for look-up
+ *
+ * Looks for domain provider under node specified by @genpdspec and if found
+ * uses xlate function of the provider to map phandle args to a power domain.
+ *
+ * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR()
+ * on failure.
+ */
+static struct generic_pm_domain *of_genpd_get_from_provider(
+					struct of_phandle_args *genpdspec)
+{
+	struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
+	struct of_genpd_provider *provider;
+
+	mutex_lock(&of_genpd_mutex);
+
+	/* Check if we have such a provider in our array */
+	list_for_each_entry(provider, &of_genpd_providers, link) {
+		if (provider->node == genpdspec->np)
+			genpd = provider->xlate(genpdspec, provider->data);
+		if (!IS_ERR(genpd))
+			break;
+	}
+
+	mutex_unlock(&of_genpd_mutex);
+
+	return genpd;
+}
+
+/**
+ * genpd_dev_pm_attach - Attach a device to it's power domain using DT.
+ * @dev: Device to attach.
+ *
+ * Parse device's OF node to find a power domain specifier. If such is found,
+ * attaches the device to retrieved pm_domain ops.
+ *
+ * Both generic and legacy Samsung-specific DT bindings are supported to
+ * keep backwards compatibility with existing DTBs.
+ *
+ * Returns 0 on successfully attached power domain or negative error code.
+ */
+int genpd_dev_pm_attach(struct device *dev)
+{
+	struct of_phandle_args pd_args;
+	struct generic_pm_domain *pd;
+	int ret;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	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;
+	}
+
+	pd = of_genpd_get_from_provider(&pd_args);
+	if (IS_ERR(pd)) {
+		dev_dbg(dev, "%s() failed to find power domain: %ld\n",
+			__func__, PTR_ERR(pd));
+		of_node_put(dev->of_node);
+		return PTR_ERR(pd);
+	}
+
+	dev_dbg(dev, "adding to power domain %s\n", pd->name);
+
+	while (1) {
+		ret = pm_genpd_add_device(pd, dev);
+		if (ret != -EAGAIN)
+			break;
+		cond_resched();
+	}
+
+	if (ret < 0) {
+		dev_err(dev, "failed to add to power domain %s: %d",
+			pd->name, ret);
+		of_node_put(dev->of_node);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
+
+/**
+ * genpd_dev_pm_detach - Detach a device from it's power domain.
+ * @dev: Device to attach.
+ *
+ * Try to locate a corresponding generic power domain, which the device
+ * then previously were attached to. If found the device is detached from
+ * the power domain.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
+ */
+int genpd_dev_pm_detach(struct device *dev)
+{
+	struct generic_pm_domain *pd = NULL, *gpd;
+	int ret = 0;
+
+	if (!dev->pm_domain)
+		return -ENODEV;
+
+	mutex_lock(&gpd_list_lock);
+	list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+		if (&gpd->domain == dev->pm_domain) {
+			pd = gpd;
+			break;
+		}
+	}
+	mutex_unlock(&gpd_list_lock);
+
+	if (!pd)
+		return -ENOENT;
+
+	dev_dbg(dev, "removing from power domain %s\n", pd->name);
+
+	while (1) {
+		ret = pm_genpd_remove_device(pd, dev);
+		if (ret != -EAGAIN)
+			break;
+		cond_resched();
+	}
+
+	if (ret < 0) {
+		dev_err(dev, "failed to remove from power domain %s: %d",
+			pd->name, ret);
+		return ret;
+	}
+
+	/* Check if domain can be powered off after removing this device. */
+	genpd_queue_power_off_work(pd);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(genpd_dev_pm_detach);
+#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 7c1d252..5989758 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -310,4 +310,50 @@ static inline void pm_genpd_syscore_poweron(struct device *dev)
 	pm_genpd_syscore_switch(dev, false);
 }
 
+/* OF power domain providers */
+struct of_device_id;
+
+struct genpd_onecell_data {
+	struct generic_pm_domain **domains;
+	unsigned int domain_num;
+};
+
+typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
+						   void *data);
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+int of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
+			  void *data);
+void of_genpd_del_provider(struct device_node *np);
+
+struct generic_pm_domain *of_genpd_xlate_simple(
+					struct of_phandle_args *genpdspec,
+					void *data);
+struct generic_pm_domain *of_genpd_xlate_onecell(
+					struct of_phandle_args *genpdspec,
+					void *data);
+
+int genpd_dev_pm_attach(struct device *dev);
+int genpd_dev_pm_detach(struct device *dev);
+#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
+static inline int of_genpd_add_provider(struct device_node *np,
+					genpd_xlate_t xlate, void *data)
+{
+	return 0;
+}
+static inline void of_genpd_del_provider(struct device_node *np) {}
+
+#define of_genpd_xlate_simple		NULL
+#define of_genpd_xlate_onecell		NULL
+
+static inline int genpd_dev_pm_attach(struct device *dev)
+{
+	return -ENODEV;
+}
+static inline int genpd_dev_pm_detach(struct device *dev)
+{
+	return -ENODEV;
+}
+#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
+
 #endif /* _LINUX_PM_DOMAIN_H */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index e4e4121..897619b 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -302,6 +302,10 @@ config PM_GENERIC_DOMAINS_RUNTIME
 	def_bool y
 	depends on PM_RUNTIME && PM_GENERIC_DOMAINS
 
+config PM_GENERIC_DOMAINS_OF
+	def_bool y
+	depends on PM_GENERIC_DOMAINS && OF && !ARCH_EXYNOS
+
 config CPU_PM
 	bool
 	depends on SUSPEND || CPU_IDLE
-- 
1.9.1

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

* [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Ulf Hansson

To maintain scalability let's add common methods to attach and detach
a power domain for a device, dev_pm_domain_attach|detach().

Typically dev_pm_domain_attach() shall be invoked from subsystem level
code at the probe phase to try to attach a device to it's power domain.
The reversed actions may be done a the remove phase and then by invoking
dev_pm_domain_detach().

The supported power domains at this point are the ACPI and the generic
power domains.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm.h          | 14 +++++++++++
 2 files changed, 72 insertions(+)

diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
index df2e5ee..f544128 100644
--- a/drivers/base/power/common.c
+++ b/drivers/base/power/common.c
@@ -11,6 +11,8 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/pm_clock.h>
+#include <linux/acpi.h>
+#include <linux/pm_domain.h>
 
 /**
  * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
@@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
+
+/**
+ * dev_pm_domain_attach - Attach a device to it's power domain.
+ * @dev: Device to attach.
+ * @power_on: Used to indicate whether we should power on the device.
+ *
+ * The @dev may only be attached to a single power domain. By iterating through
+ * the available alternatives we try to find a valid domain for the device.
+ *
+ * This function should typically be invoked from subsystem level code during
+ * the probe phase. Especially for those that's hold devices which requires
+ * power management through power domains.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns 0 on successfully attached power domain or negative error code.
+ */
+int dev_pm_domain_attach(struct device *dev, bool power_on)
+{
+	int ret;
+
+	ret = acpi_dev_pm_attach(dev, power_on);
+	if (ret == -EPROBE_DEFER)
+		return ret;
+	else
+		ret = genpd_dev_pm_attach(dev);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
+
+/**
+ * dev_pm_domain_detach - Detach a device from it's power domain.
+ * @dev: Device to attach.
+ * @power_off: Used to indicate whether we should power off the device.
+ *
+ * The @dev may be attached to a power domain. By iterating through the
+ * available alternatives we detach it from it's power domain.
+ *
+ * This functions will reverse the actions from dev_pm_domain_attach() and
+ * thus detach the @dev from it's power domain. Typically it should be invoked
+ * from subsystem level code during the remove phase.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
+ */
+int dev_pm_domain_detach(struct device *dev, bool power_off)
+{
+	if (acpi_dev_pm_detach(dev, power_off))
+		return genpd_dev_pm_detach(dev);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 72c0fe0..8176b07 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -621,6 +621,20 @@ struct dev_pm_domain {
 	struct dev_pm_ops	ops;
 };
 
+#ifdef CONFIG_PM
+extern int dev_pm_domain_attach(struct device *dev, bool power_on);
+extern int dev_pm_domain_detach(struct device *dev, bool power_off);
+#else
+static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
+{
+	return -ENODEV;
+}
+static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
+{
+	return -ENODEV;
+}
+#endif
+
 /*
  * The PM_EVENT_ messages are also used by drivers implementing the legacy
  * suspend framework, based on the ->suspend() and ->resume() callbacks common
-- 
1.9.1


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

* [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

To maintain scalability let's add common methods to attach and detach
a power domain for a device, dev_pm_domain_attach|detach().

Typically dev_pm_domain_attach() shall be invoked from subsystem level
code at the probe phase to try to attach a device to it's power domain.
The reversed actions may be done a the remove phase and then by invoking
dev_pm_domain_detach().

The supported power domains at this point are the ACPI and the generic
power domains.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm.h          | 14 +++++++++++
 2 files changed, 72 insertions(+)

diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
index df2e5ee..f544128 100644
--- a/drivers/base/power/common.c
+++ b/drivers/base/power/common.c
@@ -11,6 +11,8 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/pm_clock.h>
+#include <linux/acpi.h>
+#include <linux/pm_domain.h>
 
 /**
  * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
@@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
+
+/**
+ * dev_pm_domain_attach - Attach a device to it's power domain.
+ * @dev: Device to attach.
+ * @power_on: Used to indicate whether we should power on the device.
+ *
+ * The @dev may only be attached to a single power domain. By iterating through
+ * the available alternatives we try to find a valid domain for the device.
+ *
+ * This function should typically be invoked from subsystem level code during
+ * the probe phase. Especially for those that's hold devices which requires
+ * power management through power domains.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns 0 on successfully attached power domain or negative error code.
+ */
+int dev_pm_domain_attach(struct device *dev, bool power_on)
+{
+	int ret;
+
+	ret = acpi_dev_pm_attach(dev, power_on);
+	if (ret == -EPROBE_DEFER)
+		return ret;
+	else
+		ret = genpd_dev_pm_attach(dev);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
+
+/**
+ * dev_pm_domain_detach - Detach a device from it's power domain.
+ * @dev: Device to attach.
+ * @power_off: Used to indicate whether we should power off the device.
+ *
+ * The @dev may be attached to a power domain. By iterating through the
+ * available alternatives we detach it from it's power domain.
+ *
+ * This functions will reverse the actions from dev_pm_domain_attach() and
+ * thus detach the @dev from it's power domain. Typically it should be invoked
+ * from subsystem level code during the remove phase.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns 0 on successfully detached power domain or negative error code.
+ */
+int dev_pm_domain_detach(struct device *dev, bool power_off)
+{
+	if (acpi_dev_pm_detach(dev, power_off))
+		return genpd_dev_pm_detach(dev);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 72c0fe0..8176b07 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -621,6 +621,20 @@ struct dev_pm_domain {
 	struct dev_pm_ops	ops;
 };
 
+#ifdef CONFIG_PM
+extern int dev_pm_domain_attach(struct device *dev, bool power_on);
+extern int dev_pm_domain_detach(struct device *dev, bool power_off);
+#else
+static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
+{
+	return -ENODEV;
+}
+static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
+{
+	return -ENODEV;
+}
+#endif
+
 /*
  * The PM_EVENT_ messages are also used by drivers implementing the legacy
  * suspend framework, based on the ->suspend() and ->resume() callbacks common
-- 
1.9.1

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

* [PATCH 4/9] drivercore / platform: Convert to dev_pm_domain_attach|detach()
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Ulf Hansson

Previously only the ACPI power domain was supported by the platform
bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/platform.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ab4f4ce..904be3d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -506,11 +506,12 @@ static int platform_drv_probe(struct device *_dev)
 	if (ret < 0)
 		return ret;
 
-	acpi_dev_pm_attach(_dev, true);
-
-	ret = drv->probe(dev);
-	if (ret)
-		acpi_dev_pm_detach(_dev, true);
+	ret = dev_pm_domain_attach(_dev, true);
+	if (ret != -EPROBE_DEFER) {
+		ret = drv->probe(dev);
+		if (ret)
+			dev_pm_domain_detach(_dev, true);
+	}
 
 	if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
 		dev_warn(_dev, "probe deferral not supported\n");
@@ -532,7 +533,7 @@ static int platform_drv_remove(struct device *_dev)
 	int ret;
 
 	ret = drv->remove(dev);
-	acpi_dev_pm_detach(_dev, true);
+	dev_pm_domain_detach(_dev, true);
 
 	return ret;
 }
@@ -543,7 +544,7 @@ static void platform_drv_shutdown(struct device *_dev)
 	struct platform_device *dev = to_platform_device(_dev);
 
 	drv->shutdown(dev);
-	acpi_dev_pm_detach(_dev, true);
+	dev_pm_domain_detach(_dev, true);
 }
 
 /**
-- 
1.9.1


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

* [PATCH 4/9] drivercore / platform: Convert to dev_pm_domain_attach|detach()
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

Previously only the ACPI power domain was supported by the platform
bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/platform.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ab4f4ce..904be3d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -506,11 +506,12 @@ static int platform_drv_probe(struct device *_dev)
 	if (ret < 0)
 		return ret;
 
-	acpi_dev_pm_attach(_dev, true);
-
-	ret = drv->probe(dev);
-	if (ret)
-		acpi_dev_pm_detach(_dev, true);
+	ret = dev_pm_domain_attach(_dev, true);
+	if (ret != -EPROBE_DEFER) {
+		ret = drv->probe(dev);
+		if (ret)
+			dev_pm_domain_detach(_dev, true);
+	}
 
 	if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
 		dev_warn(_dev, "probe deferral not supported\n");
@@ -532,7 +533,7 @@ static int platform_drv_remove(struct device *_dev)
 	int ret;
 
 	ret = drv->remove(dev);
-	acpi_dev_pm_detach(_dev, true);
+	dev_pm_domain_detach(_dev, true);
 
 	return ret;
 }
@@ -543,7 +544,7 @@ static void platform_drv_shutdown(struct device *_dev)
 	struct platform_device *dev = to_platform_device(_dev);
 
 	drv->shutdown(dev);
-	acpi_dev_pm_detach(_dev, true);
+	dev_pm_domain_detach(_dev, true);
 }
 
 /**
-- 
1.9.1

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

* [PATCH 5/9] i2c: core: Convert to dev_pm_domain_attach|detach()
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07     ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
	Kevin Hilman, Alan Stern, Daniel Lezcano, Tomasz Figa,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Linus Walleij, Simon Horman,
	Magnus Damm, Ben Dooks, Kukjin Kim, Stephen Boyd, Philipp Zabel,
	Mark Brown, Wolfram Sang, Chris Ball, Russell King, Ulf Hansson,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA

Previously only the ACPI power domain was supported by the i2c bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/i2c/i2c-core.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 66aa83b..7cf7b47 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -279,10 +279,13 @@ static int i2c_device_probe(struct device *dev)
 	if (status < 0)
 		return status;
 
-	acpi_dev_pm_attach(&client->dev, true);
-	status = driver->probe(client, i2c_match_id(driver->id_table, client));
-	if (status)
-		acpi_dev_pm_detach(&client->dev, true);
+	status = dev_pm_domain_attach(&client->dev, true);
+	if (status != -EPROBE_DEFER) {
+		status = driver->probe(client, i2c_match_id(driver->id_table,
+					client));
+		if (status)
+			dev_pm_domain_detach(&client->dev, true);
+	}
 
 	return status;
 }
@@ -302,7 +305,7 @@ static int i2c_device_remove(struct device *dev)
 		status = driver->remove(client);
 	}
 
-	acpi_dev_pm_detach(&client->dev, true);
+	dev_pm_domain_detach(&client->dev, true);
 	return status;
 }
 
-- 
1.9.1

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

* [PATCH 5/9] i2c: core: Convert to dev_pm_domain_attach|detach()
@ 2014-08-26 12:07     ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

Previously only the ACPI power domain was supported by the i2c bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Cc: linux-i2c at vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/i2c/i2c-core.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 66aa83b..7cf7b47 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -279,10 +279,13 @@ static int i2c_device_probe(struct device *dev)
 	if (status < 0)
 		return status;
 
-	acpi_dev_pm_attach(&client->dev, true);
-	status = driver->probe(client, i2c_match_id(driver->id_table, client));
-	if (status)
-		acpi_dev_pm_detach(&client->dev, true);
+	status = dev_pm_domain_attach(&client->dev, true);
+	if (status != -EPROBE_DEFER) {
+		status = driver->probe(client, i2c_match_id(driver->id_table,
+					client));
+		if (status)
+			dev_pm_domain_detach(&client->dev, true);
+	}
 
 	return status;
 }
@@ -302,7 +305,7 @@ static int i2c_device_remove(struct device *dev)
 		status = driver->remove(client);
 	}
 
-	acpi_dev_pm_detach(&client->dev, true);
+	dev_pm_domain_detach(&client->dev, true);
 	return status;
 }
 
-- 
1.9.1

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

* [PATCH 6/9] mmc: sdio: Convert to dev_pm_domain_attach|detach()
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Ulf Hansson, linux-mmc

Previously only the ACPI power domain was supported by the i2c bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Cc: linux-mmc@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/sdio_bus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 4fa8fef9..1df0fc6 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -315,7 +315,7 @@ int sdio_add_func(struct sdio_func *func)
 	ret = device_add(&func->dev);
 	if (ret == 0) {
 		sdio_func_set_present(func);
-		acpi_dev_pm_attach(&func->dev, false);
+		dev_pm_domain_attach(&func->dev, false);
 	}
 
 	return ret;
@@ -332,7 +332,7 @@ void sdio_remove_func(struct sdio_func *func)
 	if (!sdio_func_present(func))
 		return;
 
-	acpi_dev_pm_detach(&func->dev, false);
+	dev_pm_domain_detach(&func->dev, false);
 	device_del(&func->dev);
 	put_device(&func->dev);
 }
-- 
1.9.1


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

* [PATCH 6/9] mmc: sdio: Convert to dev_pm_domain_attach|detach()
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

Previously only the ACPI power domain was supported by the i2c bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Cc: linux-mmc at vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/sdio_bus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 4fa8fef9..1df0fc6 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -315,7 +315,7 @@ int sdio_add_func(struct sdio_func *func)
 	ret = device_add(&func->dev);
 	if (ret == 0) {
 		sdio_func_set_present(func);
-		acpi_dev_pm_attach(&func->dev, false);
+		dev_pm_domain_attach(&func->dev, false);
 	}
 
 	return ret;
@@ -332,7 +332,7 @@ void sdio_remove_func(struct sdio_func *func)
 	if (!sdio_func_present(func))
 		return;
 
-	acpi_dev_pm_detach(&func->dev, false);
+	dev_pm_domain_detach(&func->dev, false);
 	device_del(&func->dev);
 	put_device(&func->dev);
 }
-- 
1.9.1

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

* [PATCH 7/9] spi: core: Convert to dev_pm_domain_attach|detach()
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Ulf Hansson, linux-spi

Previously only the ACPI power domain was supported by the i2c bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Cc: linux-spi@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/spi/spi.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e0531ba..6a7b0cc 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -264,10 +264,12 @@ static int spi_drv_probe(struct device *dev)
 	if (ret)
 		return ret;
 
-	acpi_dev_pm_attach(dev, true);
-	ret = sdrv->probe(to_spi_device(dev));
-	if (ret)
-		acpi_dev_pm_detach(dev, true);
+	ret = dev_pm_domain_attach(dev, true);
+	if (ret != -EPROBE_DEFER) {
+		ret = sdrv->probe(to_spi_device(dev));
+		if (ret)
+			dev_pm_domain_detach(dev, true);
+	}
 
 	return ret;
 }
@@ -278,7 +280,7 @@ static int spi_drv_remove(struct device *dev)
 	int ret;
 
 	ret = sdrv->remove(to_spi_device(dev));
-	acpi_dev_pm_detach(dev, true);
+	dev_pm_domain_detach(dev, true);
 
 	return ret;
 }
-- 
1.9.1


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

* [PATCH 7/9] spi: core: Convert to dev_pm_domain_attach|detach()
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

Previously only the ACPI power domain was supported by the i2c bus.

Let's convert to the common attach/detach functions for power domains,
which currently means we are extending the support to include the
generic power domain as well.

Cc: linux-spi at vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/spi/spi.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e0531ba..6a7b0cc 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -264,10 +264,12 @@ static int spi_drv_probe(struct device *dev)
 	if (ret)
 		return ret;
 
-	acpi_dev_pm_attach(dev, true);
-	ret = sdrv->probe(to_spi_device(dev));
-	if (ret)
-		acpi_dev_pm_detach(dev, true);
+	ret = dev_pm_domain_attach(dev, true);
+	if (ret != -EPROBE_DEFER) {
+		ret = sdrv->probe(to_spi_device(dev));
+		if (ret)
+			dev_pm_domain_detach(dev, true);
+	}
 
 	return ret;
 }
@@ -278,7 +280,7 @@ static int spi_drv_remove(struct device *dev)
 	int ret;
 
 	ret = sdrv->remove(to_spi_device(dev));
-	acpi_dev_pm_detach(dev, true);
+	dev_pm_domain_detach(dev, true);
 
 	return ret;
 }
-- 
1.9.1

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

* [PATCH 8/9] amba: Add support for attach/detach of power domains
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Ulf Hansson

AMBA devices may on some SoCs resides in power domains. To be able to
manage these devices from there, let's try to attach devices to their
corresponding power domain during the probe phase.

To reverse these actions at the remove phase, we try to detach the
device from it's power domain.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/amba/bus.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 3cf61a1..8f52393 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -182,9 +182,15 @@ static int amba_probe(struct device *dev)
 	int ret;
 
 	do {
+		ret = dev_pm_domain_attach(dev, true);
+		if (ret == -EPROBE_DEFER)
+			break;
+
 		ret = amba_get_enable_pclk(pcdev);
-		if (ret)
+		if (ret) {
+			dev_pm_domain_detach(dev, true);
 			break;
+		}
 
 		pm_runtime_get_noresume(dev);
 		pm_runtime_set_active(dev);
@@ -199,6 +205,7 @@ static int amba_probe(struct device *dev)
 		pm_runtime_put_noidle(dev);
 
 		amba_put_disable_pclk(pcdev);
+		dev_pm_domain_detach(dev, true);
 	} while (0);
 
 	return ret;
@@ -220,6 +227,7 @@ static int amba_remove(struct device *dev)
 	pm_runtime_put_noidle(dev);
 
 	amba_put_disable_pclk(pcdev);
+	dev_pm_domain_detach(dev, true);
 
 	return ret;
 }
-- 
1.9.1


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

* [PATCH 8/9] amba: Add support for attach/detach of power domains
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

AMBA devices may on some SoCs resides in power domains. To be able to
manage these devices from there, let's try to attach devices to their
corresponding power domain during the probe phase.

To reverse these actions at the remove phase, we try to detach the
device from it's power domain.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/amba/bus.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 3cf61a1..8f52393 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -182,9 +182,15 @@ static int amba_probe(struct device *dev)
 	int ret;
 
 	do {
+		ret = dev_pm_domain_attach(dev, true);
+		if (ret == -EPROBE_DEFER)
+			break;
+
 		ret = amba_get_enable_pclk(pcdev);
-		if (ret)
+		if (ret) {
+			dev_pm_domain_detach(dev, true);
 			break;
+		}
 
 		pm_runtime_get_noresume(dev);
 		pm_runtime_set_active(dev);
@@ -199,6 +205,7 @@ static int amba_probe(struct device *dev)
 		pm_runtime_put_noidle(dev);
 
 		amba_put_disable_pclk(pcdev);
+		dev_pm_domain_detach(dev, true);
 	} while (0);
 
 	return ret;
@@ -220,6 +227,7 @@ static int amba_remove(struct device *dev)
 	pm_runtime_put_noidle(dev);
 
 	amba_put_disable_pclk(pcdev);
+	dev_pm_domain_detach(dev, true);
 
 	return ret;
 }
-- 
1.9.1

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

* [PATCH 9/9] ARM: exynos: Move to generic power domain bindings
  2014-08-26 12:07 ` Ulf Hansson
@ 2014-08-26 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King, Tomasz Figa, linux-samsung-soc,
	Ulf Hansson

From: Tomasz Figa <t.figa@samsung.com>

This patch moves Exynos power domain code to use the new generic power
domain look-up framework introduced in previous patches, thus also
allowing the new code to be compiled with CONFIG_ARCH_EXYNOS as well.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Cc: linux-samsung-soc@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
[Ulf:Rebased and resolved conflicts]
---
 .../bindings/arm/exynos/power_domain.txt           | 13 ++--
 arch/arm/mach-exynos/pm_domains.c                  | 78 +---------------------
 kernel/power/Kconfig                               |  2 +-
 3 files changed, 8 insertions(+), 85 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index 8b4f7b7f..abde1ea 100644
--- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
+++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
@@ -8,6 +8,8 @@ Required Properties:
     * samsung,exynos4210-pd - for exynos4210 type power domain.
 - reg: physical base address of the controller and length of memory mapped
     region.
+- #power-domain-cells: number of cells in power domain specifier;
+    must be 0.
 
 Optional Properties:
 - clocks: List of clock handles. The parent clocks of the input clocks to the
@@ -29,6 +31,7 @@ Example:
 	lcd0: power-domain-lcd0 {
 		compatible = "samsung,exynos4210-pd";
 		reg = <0x10023C00 0x10>;
+		#power-domain-cells = <0>;
 	};
 
 	mfc_pd: power-domain@10044060 {
@@ -37,12 +40,8 @@ Example:
 		clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>,
 			<&clock CLK_MOUT_USER_ACLK333>;
 		clock-names = "oscclk", "pclk0", "clk0";
+		#power-domain-cells = <0>;
 	};
 
-Example of the node using power domain:
-
-	node {
-		/* ... */
-		samsung,power-domain = <&lcd0>;
-		/* ... */
-	};
+See Documentation/devicetree/bindings/power/power_domain.txt for description
+of consumer-side bindings.
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 797cb13..d05ecd1 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -106,78 +106,6 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
 	return exynos_pd_power(domain, false);
 }
 
-static void exynos_add_device_to_domain(struct exynos_pm_domain *pd,
-					 struct device *dev)
-{
-	int ret;
-
-	dev_dbg(dev, "adding to power domain %s\n", pd->pd.name);
-
-	while (1) {
-		ret = pm_genpd_add_device(&pd->pd, dev);
-		if (ret != -EAGAIN)
-			break;
-		cond_resched();
-	}
-
-	pm_genpd_dev_need_restore(dev, true);
-}
-
-static void exynos_remove_device_from_domain(struct device *dev)
-{
-	struct generic_pm_domain *genpd = dev_to_genpd(dev);
-	int ret;
-
-	dev_dbg(dev, "removing from power domain %s\n", genpd->name);
-
-	while (1) {
-		ret = pm_genpd_remove_device(genpd, dev);
-		if (ret != -EAGAIN)
-			break;
-		cond_resched();
-	}
-}
-
-static void exynos_read_domain_from_dt(struct device *dev)
-{
-	struct platform_device *pd_pdev;
-	struct exynos_pm_domain *pd;
-	struct device_node *node;
-
-	node = of_parse_phandle(dev->of_node, "samsung,power-domain", 0);
-	if (!node)
-		return;
-	pd_pdev = of_find_device_by_node(node);
-	if (!pd_pdev)
-		return;
-	pd = platform_get_drvdata(pd_pdev);
-	exynos_add_device_to_domain(pd, dev);
-}
-
-static int exynos_pm_notifier_call(struct notifier_block *nb,
-				    unsigned long event, void *data)
-{
-	struct device *dev = data;
-
-	switch (event) {
-	case BUS_NOTIFY_BIND_DRIVER:
-		if (dev->of_node)
-			exynos_read_domain_from_dt(dev);
-
-		break;
-
-	case BUS_NOTIFY_UNBOUND_DRIVER:
-		exynos_remove_device_from_domain(dev);
-
-		break;
-	}
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block platform_nb = {
-	.notifier_call = exynos_pm_notifier_call,
-};
-
 static __init int exynos4_pm_init_power_domain(void)
 {
 	struct platform_device *pdev;
@@ -203,7 +131,6 @@ static __init int exynos4_pm_init_power_domain(void)
 		pd->base = of_iomap(np, 0);
 		pd->pd.power_off = exynos_pd_power_off;
 		pd->pd.power_on = exynos_pd_power_on;
-		pd->pd.of_node = np;
 
 		pd->oscclk = clk_get(dev, "oscclk");
 		if (IS_ERR(pd->oscclk))
@@ -229,15 +156,12 @@ static __init int exynos4_pm_init_power_domain(void)
 			clk_put(pd->oscclk);
 
 no_clk:
-		platform_set_drvdata(pdev, pd);
-
 		on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN;
 
 		pm_genpd_init(&pd->pd, NULL, !on);
+		of_genpd_add_provider(np, of_genpd_xlate_simple, &pd->pd);
 	}
 
-	bus_register_notifier(&platform_bus_type, &platform_nb);
-
 	return 0;
 }
 arch_initcall(exynos4_pm_init_power_domain);
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 897619b..bbef57f 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -304,7 +304,7 @@ config PM_GENERIC_DOMAINS_RUNTIME
 
 config PM_GENERIC_DOMAINS_OF
 	def_bool y
-	depends on PM_GENERIC_DOMAINS && OF && !ARCH_EXYNOS
+	depends on PM_GENERIC_DOMAINS && OF
 
 config CPU_PM
 	bool
-- 
1.9.1


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

* [PATCH 9/9] ARM: exynos: Move to generic power domain bindings
@ 2014-08-26 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-26 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Figa <t.figa@samsung.com>

This patch moves Exynos power domain code to use the new generic power
domain look-up framework introduced in previous patches, thus also
allowing the new code to be compiled with CONFIG_ARCH_EXYNOS as well.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Cc: linux-samsung-soc at vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
[Ulf:Rebased and resolved conflicts]
---
 .../bindings/arm/exynos/power_domain.txt           | 13 ++--
 arch/arm/mach-exynos/pm_domains.c                  | 78 +---------------------
 kernel/power/Kconfig                               |  2 +-
 3 files changed, 8 insertions(+), 85 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index 8b4f7b7f..abde1ea 100644
--- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
+++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
@@ -8,6 +8,8 @@ Required Properties:
     * samsung,exynos4210-pd - for exynos4210 type power domain.
 - reg: physical base address of the controller and length of memory mapped
     region.
+- #power-domain-cells: number of cells in power domain specifier;
+    must be 0.
 
 Optional Properties:
 - clocks: List of clock handles. The parent clocks of the input clocks to the
@@ -29,6 +31,7 @@ Example:
 	lcd0: power-domain-lcd0 {
 		compatible = "samsung,exynos4210-pd";
 		reg = <0x10023C00 0x10>;
+		#power-domain-cells = <0>;
 	};
 
 	mfc_pd: power-domain at 10044060 {
@@ -37,12 +40,8 @@ Example:
 		clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>,
 			<&clock CLK_MOUT_USER_ACLK333>;
 		clock-names = "oscclk", "pclk0", "clk0";
+		#power-domain-cells = <0>;
 	};
 
-Example of the node using power domain:
-
-	node {
-		/* ... */
-		samsung,power-domain = <&lcd0>;
-		/* ... */
-	};
+See Documentation/devicetree/bindings/power/power_domain.txt for description
+of consumer-side bindings.
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 797cb13..d05ecd1 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -106,78 +106,6 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
 	return exynos_pd_power(domain, false);
 }
 
-static void exynos_add_device_to_domain(struct exynos_pm_domain *pd,
-					 struct device *dev)
-{
-	int ret;
-
-	dev_dbg(dev, "adding to power domain %s\n", pd->pd.name);
-
-	while (1) {
-		ret = pm_genpd_add_device(&pd->pd, dev);
-		if (ret != -EAGAIN)
-			break;
-		cond_resched();
-	}
-
-	pm_genpd_dev_need_restore(dev, true);
-}
-
-static void exynos_remove_device_from_domain(struct device *dev)
-{
-	struct generic_pm_domain *genpd = dev_to_genpd(dev);
-	int ret;
-
-	dev_dbg(dev, "removing from power domain %s\n", genpd->name);
-
-	while (1) {
-		ret = pm_genpd_remove_device(genpd, dev);
-		if (ret != -EAGAIN)
-			break;
-		cond_resched();
-	}
-}
-
-static void exynos_read_domain_from_dt(struct device *dev)
-{
-	struct platform_device *pd_pdev;
-	struct exynos_pm_domain *pd;
-	struct device_node *node;
-
-	node = of_parse_phandle(dev->of_node, "samsung,power-domain", 0);
-	if (!node)
-		return;
-	pd_pdev = of_find_device_by_node(node);
-	if (!pd_pdev)
-		return;
-	pd = platform_get_drvdata(pd_pdev);
-	exynos_add_device_to_domain(pd, dev);
-}
-
-static int exynos_pm_notifier_call(struct notifier_block *nb,
-				    unsigned long event, void *data)
-{
-	struct device *dev = data;
-
-	switch (event) {
-	case BUS_NOTIFY_BIND_DRIVER:
-		if (dev->of_node)
-			exynos_read_domain_from_dt(dev);
-
-		break;
-
-	case BUS_NOTIFY_UNBOUND_DRIVER:
-		exynos_remove_device_from_domain(dev);
-
-		break;
-	}
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block platform_nb = {
-	.notifier_call = exynos_pm_notifier_call,
-};
-
 static __init int exynos4_pm_init_power_domain(void)
 {
 	struct platform_device *pdev;
@@ -203,7 +131,6 @@ static __init int exynos4_pm_init_power_domain(void)
 		pd->base = of_iomap(np, 0);
 		pd->pd.power_off = exynos_pd_power_off;
 		pd->pd.power_on = exynos_pd_power_on;
-		pd->pd.of_node = np;
 
 		pd->oscclk = clk_get(dev, "oscclk");
 		if (IS_ERR(pd->oscclk))
@@ -229,15 +156,12 @@ static __init int exynos4_pm_init_power_domain(void)
 			clk_put(pd->oscclk);
 
 no_clk:
-		platform_set_drvdata(pdev, pd);
-
 		on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN;
 
 		pm_genpd_init(&pd->pd, NULL, !on);
+		of_genpd_add_provider(np, of_genpd_xlate_simple, &pd->pd);
 	}
 
-	bus_register_notifier(&platform_bus_type, &platform_nb);
-
 	return 0;
 }
 arch_initcall(exynos4_pm_init_power_domain);
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 897619b..bbef57f 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -304,7 +304,7 @@ config PM_GENERIC_DOMAINS_RUNTIME
 
 config PM_GENERIC_DOMAINS_OF
 	def_bool y
-	depends on PM_GENERIC_DOMAINS && OF && !ARCH_EXYNOS
+	depends on PM_GENERIC_DOMAINS && OF
 
 config CPU_PM
 	bool
-- 
1.9.1

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

* Re: [PATCH 2/9] PM / Domains: Add generic OF-based power domain look-up
  2014-08-26 12:07   ` Ulf Hansson
@ 2014-08-26 13:15     ` Philipp Zabel
  -1 siblings, 0 replies; 36+ messages in thread
From: Philipp Zabel @ 2014-08-26 13:15 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
	linux-pm, devicetree, Kevin Hilman, Russell King, Philipp Zabel,
	Geert Uytterhoeven, Wolfram Sang, Stephen Boyd, Linus Walleij,
	Daniel Lezcano, Magnus Damm, Tomasz Figa, Chris Ball, linux-acpi,
	Simon Horman, Alan Stern, Mark Brown, Ben Dooks, Kukjin Kim,
	Tomasz Figa

Hi Ulf,

Am Dienstag, den 26.08.2014, 14:07 +0200 schrieb Ulf Hansson:
> From: Tomasz Figa <t.figa@samsung.com>
> 
> This patch introduces generic code to perform power domain look-up using
> device tree and automatically bind devices to their power domains.
> Generic device tree binding is introduced to specify power domains of
> devices in their device tree nodes.
> 
> Backwards compatibility with legacy Samsung-specific power domain
> bindings is provided, but for now the new code is not compiled when
> CONFIG_ARCH_EXYNOS is selected to avoid collision with legacy code. This
> will change as soon as Exynos power domain code gets converted to use
> the generic framework in further patch.
> 
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

Thank you for updating this series. I've tested patches 1-4
using the PU power domain on i.MX6.

Tested-by: Philipp Zabel <p.zabel@pengutronix.de>

regards
Philipp


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

* [PATCH 2/9] PM / Domains: Add generic OF-based power domain look-up
@ 2014-08-26 13:15     ` Philipp Zabel
  0 siblings, 0 replies; 36+ messages in thread
From: Philipp Zabel @ 2014-08-26 13:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ulf,

Am Dienstag, den 26.08.2014, 14:07 +0200 schrieb Ulf Hansson:
> From: Tomasz Figa <t.figa@samsung.com>
> 
> This patch introduces generic code to perform power domain look-up using
> device tree and automatically bind devices to their power domains.
> Generic device tree binding is introduced to specify power domains of
> devices in their device tree nodes.
> 
> Backwards compatibility with legacy Samsung-specific power domain
> bindings is provided, but for now the new code is not compiled when
> CONFIG_ARCH_EXYNOS is selected to avoid collision with legacy code. This
> will change as soon as Exynos power domain code gets converted to use
> the generic framework in further patch.
> 
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

Thank you for updating this series. I've tested patches 1-4
using the PU power domain on i.MX6.

Tested-by: Philipp Zabel <p.zabel@pengutronix.de>

regards
Philipp

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

* Re: [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
  2014-08-26 12:07   ` Ulf Hansson
@ 2014-08-27  0:16     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 36+ messages in thread
From: Rafael J. Wysocki @ 2014-08-27  0:16 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm,
	linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King

On Tuesday, August 26, 2014 02:07:09 PM Ulf Hansson wrote:
> To give callers the option of acting on a errors while removing the
> pm_domain ops for the device in the ACPI power domain, let
> acpi_dev_pm_detach() return an int to provide the error code.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/acpi/device_pm.c | 4 ++++
>  include/linux/acpi.h     | 7 +++++--
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
> index 67075f8..fa78abb 100644
> --- a/drivers/acpi/device_pm.c
> +++ b/drivers/acpi/device_pm.c
> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>   *
>   * Callers must ensure proper synchronization of this function with power
>   * management callbacks.
> + *
> + * Returns 0 on successfully detached power domain or negative error code.

"PM domain" here, please, not "power domain".

>   */
>  void acpi_dev_pm_detach(struct device *dev, bool power_off)

It looks like you've never compiled this, have you?

>  {
> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>  			acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>  			acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>  		}
> +		return 0;
>  	}
> +	return -ENODEV;

-EINVAL perhaps?

>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>  #endif /* CONFIG_PM */
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 5320153..a7bfdf6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>  #else
>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>  {
> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>  {
>  	return -ENODEV;
>  }
> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
> +{
> +	return -ENODEV;
> +}
>  #endif
>  
>  #ifdef CONFIG_ACPI
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
@ 2014-08-27  0:16     ` Rafael J. Wysocki
  0 siblings, 0 replies; 36+ messages in thread
From: Rafael J. Wysocki @ 2014-08-27  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 26, 2014 02:07:09 PM Ulf Hansson wrote:
> To give callers the option of acting on a errors while removing the
> pm_domain ops for the device in the ACPI power domain, let
> acpi_dev_pm_detach() return an int to provide the error code.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/acpi/device_pm.c | 4 ++++
>  include/linux/acpi.h     | 7 +++++--
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
> index 67075f8..fa78abb 100644
> --- a/drivers/acpi/device_pm.c
> +++ b/drivers/acpi/device_pm.c
> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>   *
>   * Callers must ensure proper synchronization of this function with power
>   * management callbacks.
> + *
> + * Returns 0 on successfully detached power domain or negative error code.

"PM domain" here, please, not "power domain".

>   */
>  void acpi_dev_pm_detach(struct device *dev, bool power_off)

It looks like you've never compiled this, have you?

>  {
> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>  			acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>  			acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>  		}
> +		return 0;
>  	}
> +	return -ENODEV;

-EINVAL perhaps?

>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>  #endif /* CONFIG_PM */
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 5320153..a7bfdf6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>  #else
>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>  {
> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>  {
>  	return -ENODEV;
>  }
> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
> +{
> +	return -ENODEV;
> +}
>  #endif
>  
>  #ifdef CONFIG_ACPI
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
  2014-08-26 12:07   ` Ulf Hansson
@ 2014-08-27  0:20     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 36+ messages in thread
From: Rafael J. Wysocki @ 2014-08-27  0:20 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm,
	linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King

On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
> To maintain scalability let's add common methods to attach and detach
> a power domain for a device, dev_pm_domain_attach|detach().
> 
> Typically dev_pm_domain_attach() shall be invoked from subsystem level
> code at the probe phase to try to attach a device to it's power domain.
> The reversed actions may be done a the remove phase and then by invoking
> dev_pm_domain_detach().
> 
> The supported power domains at this point are the ACPI and the generic
> power domains.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pm.h          | 14 +++++++++++
>  2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
> index df2e5ee..f544128 100644
> --- a/drivers/base/power/common.c
> +++ b/drivers/base/power/common.c
> @@ -11,6 +11,8 @@
>  #include <linux/export.h>
>  #include <linux/slab.h>
>  #include <linux/pm_clock.h>
> +#include <linux/acpi.h>
> +#include <linux/pm_domain.h>
>  
>  /**
>   * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
> @@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
> +
> +/**
> + * dev_pm_domain_attach - Attach a device to it's power domain.
> + * @dev: Device to attach.
> + * @power_on: Used to indicate whether we should power on the device.
> + *
> + * The @dev may only be attached to a single power domain. By iterating through
> + * the available alternatives we try to find a valid domain for the device.
> + *
> + * This function should typically be invoked from subsystem level code during
> + * the probe phase. Especially for those that's hold devices which requires
> + * power management through power domains.
> + *
> + * Callers must ensure proper synchronization of this function with power
> + * management callbacks.
> + *
> + * Returns 0 on successfully attached power domain or negative error code.
> + */
> +int dev_pm_domain_attach(struct device *dev, bool power_on)
> +{
> +	int ret;
> +
> +	ret = acpi_dev_pm_attach(dev, power_on);
> +	if (ret == -EPROBE_DEFER)

This doesn't seem to be possible today.  At least I'm not sure how it can
happen.

> +		return ret;
> +	else
> +		ret = genpd_dev_pm_attach(dev);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(dev_pm_domain_attach);

On a more general note, are you sure that the place where we call
acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?

> +
> +/**
> + * dev_pm_domain_detach - Detach a device from it's power domain.
> + * @dev: Device to attach.
> + * @power_off: Used to indicate whether we should power off the device.
> + *
> + * The @dev may be attached to a power domain. By iterating through the
> + * available alternatives we detach it from it's power domain.
> + *
> + * This functions will reverse the actions from dev_pm_domain_attach() and
> + * thus detach the @dev from it's power domain. Typically it should be invoked
> + * from subsystem level code during the remove phase.
> + *
> + * Callers must ensure proper synchronization of this function with power
> + * management callbacks.
> + *
> + * Returns 0 on successfully detached power domain or negative error code.
> + */
> +int dev_pm_domain_detach(struct device *dev, bool power_off)
> +{
> +	if (acpi_dev_pm_detach(dev, power_off))
> +		return genpd_dev_pm_detach(dev);
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 72c0fe0..8176b07 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -621,6 +621,20 @@ struct dev_pm_domain {
>  	struct dev_pm_ops	ops;
>  };
>  
> +#ifdef CONFIG_PM
> +extern int dev_pm_domain_attach(struct device *dev, bool power_on);
> +extern int dev_pm_domain_detach(struct device *dev, bool power_off);
> +#else
> +static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
> +{
> +	return -ENODEV;
> +}
> +static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>  /*
>   * The PM_EVENT_ messages are also used by drivers implementing the legacy
>   * suspend framework, based on the ->suspend() and ->resume() callbacks common
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
@ 2014-08-27  0:20     ` Rafael J. Wysocki
  0 siblings, 0 replies; 36+ messages in thread
From: Rafael J. Wysocki @ 2014-08-27  0:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
> To maintain scalability let's add common methods to attach and detach
> a power domain for a device, dev_pm_domain_attach|detach().
> 
> Typically dev_pm_domain_attach() shall be invoked from subsystem level
> code at the probe phase to try to attach a device to it's power domain.
> The reversed actions may be done a the remove phase and then by invoking
> dev_pm_domain_detach().
> 
> The supported power domains at this point are the ACPI and the generic
> power domains.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pm.h          | 14 +++++++++++
>  2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
> index df2e5ee..f544128 100644
> --- a/drivers/base/power/common.c
> +++ b/drivers/base/power/common.c
> @@ -11,6 +11,8 @@
>  #include <linux/export.h>
>  #include <linux/slab.h>
>  #include <linux/pm_clock.h>
> +#include <linux/acpi.h>
> +#include <linux/pm_domain.h>
>  
>  /**
>   * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
> @@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
> +
> +/**
> + * dev_pm_domain_attach - Attach a device to it's power domain.
> + * @dev: Device to attach.
> + * @power_on: Used to indicate whether we should power on the device.
> + *
> + * The @dev may only be attached to a single power domain. By iterating through
> + * the available alternatives we try to find a valid domain for the device.
> + *
> + * This function should typically be invoked from subsystem level code during
> + * the probe phase. Especially for those that's hold devices which requires
> + * power management through power domains.
> + *
> + * Callers must ensure proper synchronization of this function with power
> + * management callbacks.
> + *
> + * Returns 0 on successfully attached power domain or negative error code.
> + */
> +int dev_pm_domain_attach(struct device *dev, bool power_on)
> +{
> +	int ret;
> +
> +	ret = acpi_dev_pm_attach(dev, power_on);
> +	if (ret == -EPROBE_DEFER)

This doesn't seem to be possible today.  At least I'm not sure how it can
happen.

> +		return ret;
> +	else
> +		ret = genpd_dev_pm_attach(dev);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(dev_pm_domain_attach);

On a more general note, are you sure that the place where we call
acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?

> +
> +/**
> + * dev_pm_domain_detach - Detach a device from it's power domain.
> + * @dev: Device to attach.
> + * @power_off: Used to indicate whether we should power off the device.
> + *
> + * The @dev may be attached to a power domain. By iterating through the
> + * available alternatives we detach it from it's power domain.
> + *
> + * This functions will reverse the actions from dev_pm_domain_attach() and
> + * thus detach the @dev from it's power domain. Typically it should be invoked
> + * from subsystem level code during the remove phase.
> + *
> + * Callers must ensure proper synchronization of this function with power
> + * management callbacks.
> + *
> + * Returns 0 on successfully detached power domain or negative error code.
> + */
> +int dev_pm_domain_detach(struct device *dev, bool power_off)
> +{
> +	if (acpi_dev_pm_detach(dev, power_off))
> +		return genpd_dev_pm_detach(dev);
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 72c0fe0..8176b07 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -621,6 +621,20 @@ struct dev_pm_domain {
>  	struct dev_pm_ops	ops;
>  };
>  
> +#ifdef CONFIG_PM
> +extern int dev_pm_domain_attach(struct device *dev, bool power_on);
> +extern int dev_pm_domain_detach(struct device *dev, bool power_off);
> +#else
> +static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
> +{
> +	return -ENODEV;
> +}
> +static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>  /*
>   * The PM_EVENT_ messages are also used by drivers implementing the legacy
>   * suspend framework, based on the ->suspend() and ->resume() callbacks common
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* RE: [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
  2014-08-26 12:07   ` Ulf Hansson
@ 2014-08-27  5:43     ` Zheng, Lv
  -1 siblings, 0 replies; 36+ messages in thread
From: Zheng, Lv @ 2014-08-27  5:43 UTC (permalink / raw)
  To: Ulf Hansson, Rafael J. Wysocki, Brown, Len, Pavel Machek,
	Greg Kroah-Hartman, linux-pm
  Cc: linux-arm-kernel, linux-acpi, Geert Uytterhoeven, Kevin Hilman,
	Alan Stern, Daniel Lezcano, Tomasz Figa, devicetree,
	Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks, Kukjin Kim,
	Stephen Boyd, Philipp Zabel, Mark Brown, Wolfram Sang,
	Chris Ball, Russell King

Hi,

> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-owner@vger.kernel.org] On Behalf Of Ulf Hansson
> Sent: Tuesday, August 26, 2014 8:07 PM
> To: Rafael J. Wysocki; Brown, Len; Pavel Machek; Greg Kroah-Hartman; linux-pm@vger.kernel.org
> 
> To give callers the option of acting on a errors while removing the
> pm_domain ops for the device in the ACPI power domain, let
> acpi_dev_pm_detach() return an int to provide the error code.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/acpi/device_pm.c | 4 ++++
>  include/linux/acpi.h     | 7 +++++--
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
> index 67075f8..fa78abb 100644
> --- a/drivers/acpi/device_pm.c
> +++ b/drivers/acpi/device_pm.c
> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>   *
>   * Callers must ensure proper synchronization of this function with power
>   * management callbacks.
> + *
> + * Returns 0 on successfully detached power domain or negative error code.
>   */
>  void acpi_dev_pm_detach(struct device *dev, bool power_off)

Should the return type be "int" here?

Thanks and best regards
-Lv

>  {
> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>  			acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>  			acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>  		}
> +		return 0;
>  	}
> +	return -ENODEV;
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>  #endif /* CONFIG_PM */
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 5320153..a7bfdf6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>  #else
>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>  {
> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>  {
>  	return -ENODEV;
>  }
> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
> +{
> +	return -ENODEV;
> +}
>  #endif
> 
>  #ifdef CONFIG_ACPI
> --
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
@ 2014-08-27  5:43     ` Zheng, Lv
  0 siblings, 0 replies; 36+ messages in thread
From: Zheng, Lv @ 2014-08-27  5:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-owner at vger.kernel.org] On Behalf Of Ulf Hansson
> Sent: Tuesday, August 26, 2014 8:07 PM
> To: Rafael J. Wysocki; Brown, Len; Pavel Machek; Greg Kroah-Hartman; linux-pm at vger.kernel.org
> 
> To give callers the option of acting on a errors while removing the
> pm_domain ops for the device in the ACPI power domain, let
> acpi_dev_pm_detach() return an int to provide the error code.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/acpi/device_pm.c | 4 ++++
>  include/linux/acpi.h     | 7 +++++--
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
> index 67075f8..fa78abb 100644
> --- a/drivers/acpi/device_pm.c
> +++ b/drivers/acpi/device_pm.c
> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>   *
>   * Callers must ensure proper synchronization of this function with power
>   * management callbacks.
> + *
> + * Returns 0 on successfully detached power domain or negative error code.
>   */
>  void acpi_dev_pm_detach(struct device *dev, bool power_off)

Should the return type be "int" here?

Thanks and best regards
-Lv

>  {
> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>  			acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>  			acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>  		}
> +		return 0;
>  	}
> +	return -ENODEV;
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>  #endif /* CONFIG_PM */
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 5320153..a7bfdf6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>  #else
>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>  {
> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>  {
>  	return -ENODEV;
>  }
> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
> +{
> +	return -ENODEV;
> +}
>  #endif
> 
>  #ifdef CONFIG_ACPI
> --
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
  2014-08-27  0:16     ` Rafael J. Wysocki
@ 2014-08-27  7:25       ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:25 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm,
	linux-arm-kernel, ACPI Devel Maling List, Geert Uytterhoeven,
	Kevin Hilman, Alan Stern, Daniel Lezcano, Tomasz Figa,
	devicetree, Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks,
	Kukjin Kim, Stephen Boyd, Philipp Zabel, Mark Brown,
	Wolfram Sang

On 27 August 2014 02:16, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Tuesday, August 26, 2014 02:07:09 PM Ulf Hansson wrote:
>> To give callers the option of acting on a errors while removing the
>> pm_domain ops for the device in the ACPI power domain, let
>> acpi_dev_pm_detach() return an int to provide the error code.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> ---
>>  drivers/acpi/device_pm.c | 4 ++++
>>  include/linux/acpi.h     | 7 +++++--
>>  2 files changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
>> index 67075f8..fa78abb 100644
>> --- a/drivers/acpi/device_pm.c
>> +++ b/drivers/acpi/device_pm.c
>> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>>   *
>>   * Callers must ensure proper synchronization of this function with power
>>   * management callbacks.
>> + *
>> + * Returns 0 on successfully detached power domain or negative error code.
>
> "PM domain" here, please, not "power domain".
>

Sure.

If you prefer that term, I can also change on the other patches in
this patchset. There are commit-msg etc , where I think I have used
"power domain".

>>   */
>>  void acpi_dev_pm_detach(struct device *dev, bool power_off)
>
> It looks like you've never compiled this, have you?

You are absolutely right. There were quite some combinations of
CONFIG_PM_* that I tried out, but I totally forgot ACPI, sorry! I will
make sure to do it in v2.

>
>>  {
>> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>>                       acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>>                       acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>>               }
>> +             return 0;
>>       }
>> +     return -ENODEV;
>
> -EINVAL perhaps?

Sure!

>
>>  }
>>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>>  #endif /* CONFIG_PM */
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 5320153..a7bfdf6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
>> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
>> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>>  #else
>>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>>  {
>> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>>  {
>>       return -ENODEV;
>>  }
>> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
>> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
>> +{
>> +     return -ENODEV;
>> +}
>>  #endif
>>
>>  #ifdef CONFIG_ACPI
>>
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

Thanks for reviewing!

Kind regards
Uffe

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

* [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
@ 2014-08-27  7:25       ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 27 August 2014 02:16, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Tuesday, August 26, 2014 02:07:09 PM Ulf Hansson wrote:
>> To give callers the option of acting on a errors while removing the
>> pm_domain ops for the device in the ACPI power domain, let
>> acpi_dev_pm_detach() return an int to provide the error code.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> ---
>>  drivers/acpi/device_pm.c | 4 ++++
>>  include/linux/acpi.h     | 7 +++++--
>>  2 files changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
>> index 67075f8..fa78abb 100644
>> --- a/drivers/acpi/device_pm.c
>> +++ b/drivers/acpi/device_pm.c
>> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>>   *
>>   * Callers must ensure proper synchronization of this function with power
>>   * management callbacks.
>> + *
>> + * Returns 0 on successfully detached power domain or negative error code.
>
> "PM domain" here, please, not "power domain".
>

Sure.

If you prefer that term, I can also change on the other patches in
this patchset. There are commit-msg etc , where I think I have used
"power domain".

>>   */
>>  void acpi_dev_pm_detach(struct device *dev, bool power_off)
>
> It looks like you've never compiled this, have you?

You are absolutely right. There were quite some combinations of
CONFIG_PM_* that I tried out, but I totally forgot ACPI, sorry! I will
make sure to do it in v2.

>
>>  {
>> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>>                       acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>>                       acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>>               }
>> +             return 0;
>>       }
>> +     return -ENODEV;
>
> -EINVAL perhaps?

Sure!

>
>>  }
>>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>>  #endif /* CONFIG_PM */
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 5320153..a7bfdf6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
>> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
>> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>>  #else
>>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>>  {
>> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>>  {
>>       return -ENODEV;
>>  }
>> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
>> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
>> +{
>> +     return -ENODEV;
>> +}
>>  #endif
>>
>>  #ifdef CONFIG_ACPI
>>
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

Thanks for reviewing!

Kind regards
Uffe

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

* Re: [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
  2014-08-27  5:43     ` Zheng, Lv
@ 2014-08-27  7:26       ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:26 UTC (permalink / raw)
  To: Zheng, Lv
  Cc: Rafael J. Wysocki, Brown, Len, Pavel Machek, Greg Kroah-Hartman,
	linux-pm, linux-arm-kernel, linux-acpi, Geert Uytterhoeven,
	Kevin Hilman, Alan Stern, Daniel Lezcano, Tomasz Figa,
	devicetree, Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks,
	Kukjin Kim, Stephen Boyd, Philipp Zabel, Mark

On 27 August 2014 07:43, Zheng, Lv <lv.zheng@intel.com> wrote:
> Hi,
>
>> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-owner@vger.kernel.org] On Behalf Of Ulf Hansson
>> Sent: Tuesday, August 26, 2014 8:07 PM
>> To: Rafael J. Wysocki; Brown, Len; Pavel Machek; Greg Kroah-Hartman; linux-pm@vger.kernel.org
>>
>> To give callers the option of acting on a errors while removing the
>> pm_domain ops for the device in the ACPI power domain, let
>> acpi_dev_pm_detach() return an int to provide the error code.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> ---
>>  drivers/acpi/device_pm.c | 4 ++++
>>  include/linux/acpi.h     | 7 +++++--
>>  2 files changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
>> index 67075f8..fa78abb 100644
>> --- a/drivers/acpi/device_pm.c
>> +++ b/drivers/acpi/device_pm.c
>> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>>   *
>>   * Callers must ensure proper synchronization of this function with power
>>   * management callbacks.
>> + *
>> + * Returns 0 on successfully detached power domain or negative error code.
>>   */
>>  void acpi_dev_pm_detach(struct device *dev, bool power_off)
>
> Should the return type be "int" here?

You are right, thanks!

Kind regards
Uffe

>
> Thanks and best regards
> -Lv
>
>>  {
>> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>>                       acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>>                       acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>>               }
>> +             return 0;
>>       }
>> +     return -ENODEV;
>>  }
>>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>>  #endif /* CONFIG_PM */
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 5320153..a7bfdf6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
>> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
>> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>>  #else
>>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>>  {
>> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>>  {
>>       return -ENODEV;
>>  }
>> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
>> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
>> +{
>> +     return -ENODEV;
>> +}
>>  #endif
>>
>>  #ifdef CONFIG_ACPI
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code
@ 2014-08-27  7:26       ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 27 August 2014 07:43, Zheng, Lv <lv.zheng@intel.com> wrote:
> Hi,
>
>> From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-owner at vger.kernel.org] On Behalf Of Ulf Hansson
>> Sent: Tuesday, August 26, 2014 8:07 PM
>> To: Rafael J. Wysocki; Brown, Len; Pavel Machek; Greg Kroah-Hartman; linux-pm at vger.kernel.org
>>
>> To give callers the option of acting on a errors while removing the
>> pm_domain ops for the device in the ACPI power domain, let
>> acpi_dev_pm_detach() return an int to provide the error code.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> ---
>>  drivers/acpi/device_pm.c | 4 ++++
>>  include/linux/acpi.h     | 7 +++++--
>>  2 files changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
>> index 67075f8..fa78abb 100644
>> --- a/drivers/acpi/device_pm.c
>> +++ b/drivers/acpi/device_pm.c
>> @@ -1087,6 +1087,8 @@ EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
>>   *
>>   * Callers must ensure proper synchronization of this function with power
>>   * management callbacks.
>> + *
>> + * Returns 0 on successfully detached power domain or negative error code.
>>   */
>>  void acpi_dev_pm_detach(struct device *dev, bool power_off)
>
> Should the return type be "int" here?

You are right, thanks!

Kind regards
Uffe

>
> Thanks and best regards
> -Lv
>
>>  {
>> @@ -1107,7 +1109,9 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
>>                       acpi_device_wakeup(adev, ACPI_STATE_S0, false);
>>                       acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
>>               }
>> +             return 0;
>>       }
>> +     return -ENODEV;
>>  }
>>  EXPORT_SYMBOL_GPL(acpi_dev_pm_detach);
>>  #endif /* CONFIG_PM */
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 5320153..a7bfdf6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -576,7 +576,7 @@ static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
>>  #if defined(CONFIG_ACPI) && defined(CONFIG_PM)
>>  struct acpi_device *acpi_dev_pm_get_node(struct device *dev);
>>  int acpi_dev_pm_attach(struct device *dev, bool power_on);
>> -void acpi_dev_pm_detach(struct device *dev, bool power_off);
>> +int acpi_dev_pm_detach(struct device *dev, bool power_off);
>>  #else
>>  static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
>>  {
>> @@ -586,7 +586,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
>>  {
>>       return -ENODEV;
>>  }
>> -static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
>> +static inline int acpi_dev_pm_detach(struct device *dev, bool power_off)
>> +{
>> +     return -ENODEV;
>> +}
>>  #endif
>>
>>  #ifdef CONFIG_ACPI
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
  2014-08-27  0:20     ` Rafael J. Wysocki
@ 2014-08-27  7:37       ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:37 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm,
	linux-arm-kernel, ACPI Devel Maling List, Geert Uytterhoeven,
	Kevin Hilman, Alan Stern, Daniel Lezcano, Tomasz Figa,
	devicetree, Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks,
	Kukjin Kim, Stephen Boyd, Philipp Zabel, Mark Brown,
	Wolfram Sang

On 27 August 2014 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
>> To maintain scalability let's add common methods to attach and detach
>> a power domain for a device, dev_pm_domain_attach|detach().
>>
>> Typically dev_pm_domain_attach() shall be invoked from subsystem level
>> code at the probe phase to try to attach a device to it's power domain.
>> The reversed actions may be done a the remove phase and then by invoking
>> dev_pm_domain_detach().
>>
>> The supported power domains at this point are the ACPI and the generic
>> power domains.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> ---
>>  drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/pm.h          | 14 +++++++++++
>>  2 files changed, 72 insertions(+)
>>
>> diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
>> index df2e5ee..f544128 100644
>> --- a/drivers/base/power/common.c
>> +++ b/drivers/base/power/common.c
>> @@ -11,6 +11,8 @@
>>  #include <linux/export.h>
>>  #include <linux/slab.h>
>>  #include <linux/pm_clock.h>
>> +#include <linux/acpi.h>
>> +#include <linux/pm_domain.h>
>>
>>  /**
>>   * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
>> @@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
>>       return ret;
>>  }
>>  EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
>> +
>> +/**
>> + * dev_pm_domain_attach - Attach a device to it's power domain.
>> + * @dev: Device to attach.
>> + * @power_on: Used to indicate whether we should power on the device.
>> + *
>> + * The @dev may only be attached to a single power domain. By iterating through
>> + * the available alternatives we try to find a valid domain for the device.
>> + *
>> + * This function should typically be invoked from subsystem level code during
>> + * the probe phase. Especially for those that's hold devices which requires
>> + * power management through power domains.
>> + *
>> + * Callers must ensure proper synchronization of this function with power
>> + * management callbacks.
>> + *
>> + * Returns 0 on successfully attached power domain or negative error code.
>> + */
>> +int dev_pm_domain_attach(struct device *dev, bool power_on)
>> +{
>> +     int ret;
>> +
>> +     ret = acpi_dev_pm_attach(dev, power_on);
>> +     if (ret == -EPROBE_DEFER)
>
> This doesn't seem to be possible today.  At least I'm not sure how it can
> happen.

You are right, but I did this intentionally. The reason for having
this check, was that I didn't want the new API to put the limit on
handling deferred probe.

I happy the above check, if you think it's better!?

Kind regards
Uffe

>
>> +             return ret;
>> +     else
>> +             ret = genpd_dev_pm_attach(dev);
>> +
>> +     return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
>
> On a more general note, are you sure that the place where we call
> acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?
>

Currently, I haven't seen any place where it doesn't make sense.

Additionally if such place is found, we may either just ignore it and
let the caller of the API worry about the returned error or invoke the
genpd/acpi API immediately instead.

>> +
>> +/**
>> + * dev_pm_domain_detach - Detach a device from it's power domain.
>> + * @dev: Device to attach.
>> + * @power_off: Used to indicate whether we should power off the device.
>> + *
>> + * The @dev may be attached to a power domain. By iterating through the
>> + * available alternatives we detach it from it's power domain.
>> + *
>> + * This functions will reverse the actions from dev_pm_domain_attach() and
>> + * thus detach the @dev from it's power domain. Typically it should be invoked
>> + * from subsystem level code during the remove phase.
>> + *
>> + * Callers must ensure proper synchronization of this function with power
>> + * management callbacks.
>> + *
>> + * Returns 0 on successfully detached power domain or negative error code.
>> + */
>> +int dev_pm_domain_detach(struct device *dev, bool power_off)
>> +{
>> +     if (acpi_dev_pm_detach(dev, power_off))
>> +             return genpd_dev_pm_detach(dev);
>> +     return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
>> diff --git a/include/linux/pm.h b/include/linux/pm.h
>> index 72c0fe0..8176b07 100644
>> --- a/include/linux/pm.h
>> +++ b/include/linux/pm.h
>> @@ -621,6 +621,20 @@ struct dev_pm_domain {
>>       struct dev_pm_ops       ops;
>>  };
>>
>> +#ifdef CONFIG_PM
>> +extern int dev_pm_domain_attach(struct device *dev, bool power_on);
>> +extern int dev_pm_domain_detach(struct device *dev, bool power_off);
>> +#else
>> +static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
>> +{
>> +     return -ENODEV;
>> +}
>> +static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
>> +{
>> +     return -ENODEV;
>> +}
>> +#endif
>> +
>>  /*
>>   * The PM_EVENT_ messages are also used by drivers implementing the legacy
>>   * suspend framework, based on the ->suspend() and ->resume() callbacks common
>>
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
@ 2014-08-27  7:37       ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 27 August 2014 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
>> To maintain scalability let's add common methods to attach and detach
>> a power domain for a device, dev_pm_domain_attach|detach().
>>
>> Typically dev_pm_domain_attach() shall be invoked from subsystem level
>> code at the probe phase to try to attach a device to it's power domain.
>> The reversed actions may be done a the remove phase and then by invoking
>> dev_pm_domain_detach().
>>
>> The supported power domains at this point are the ACPI and the generic
>> power domains.
>>
>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>> ---
>>  drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/pm.h          | 14 +++++++++++
>>  2 files changed, 72 insertions(+)
>>
>> diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
>> index df2e5ee..f544128 100644
>> --- a/drivers/base/power/common.c
>> +++ b/drivers/base/power/common.c
>> @@ -11,6 +11,8 @@
>>  #include <linux/export.h>
>>  #include <linux/slab.h>
>>  #include <linux/pm_clock.h>
>> +#include <linux/acpi.h>
>> +#include <linux/pm_domain.h>
>>
>>  /**
>>   * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
>> @@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
>>       return ret;
>>  }
>>  EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
>> +
>> +/**
>> + * dev_pm_domain_attach - Attach a device to it's power domain.
>> + * @dev: Device to attach.
>> + * @power_on: Used to indicate whether we should power on the device.
>> + *
>> + * The @dev may only be attached to a single power domain. By iterating through
>> + * the available alternatives we try to find a valid domain for the device.
>> + *
>> + * This function should typically be invoked from subsystem level code during
>> + * the probe phase. Especially for those that's hold devices which requires
>> + * power management through power domains.
>> + *
>> + * Callers must ensure proper synchronization of this function with power
>> + * management callbacks.
>> + *
>> + * Returns 0 on successfully attached power domain or negative error code.
>> + */
>> +int dev_pm_domain_attach(struct device *dev, bool power_on)
>> +{
>> +     int ret;
>> +
>> +     ret = acpi_dev_pm_attach(dev, power_on);
>> +     if (ret == -EPROBE_DEFER)
>
> This doesn't seem to be possible today.  At least I'm not sure how it can
> happen.

You are right, but I did this intentionally. The reason for having
this check, was that I didn't want the new API to put the limit on
handling deferred probe.

I happy the above check, if you think it's better!?

Kind regards
Uffe

>
>> +             return ret;
>> +     else
>> +             ret = genpd_dev_pm_attach(dev);
>> +
>> +     return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
>
> On a more general note, are you sure that the place where we call
> acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?
>

Currently, I haven't seen any place where it doesn't make sense.

Additionally if such place is found, we may either just ignore it and
let the caller of the API worry about the returned error or invoke the
genpd/acpi API immediately instead.

>> +
>> +/**
>> + * dev_pm_domain_detach - Detach a device from it's power domain.
>> + * @dev: Device to attach.
>> + * @power_off: Used to indicate whether we should power off the device.
>> + *
>> + * The @dev may be attached to a power domain. By iterating through the
>> + * available alternatives we detach it from it's power domain.
>> + *
>> + * This functions will reverse the actions from dev_pm_domain_attach() and
>> + * thus detach the @dev from it's power domain. Typically it should be invoked
>> + * from subsystem level code during the remove phase.
>> + *
>> + * Callers must ensure proper synchronization of this function with power
>> + * management callbacks.
>> + *
>> + * Returns 0 on successfully detached power domain or negative error code.
>> + */
>> +int dev_pm_domain_detach(struct device *dev, bool power_off)
>> +{
>> +     if (acpi_dev_pm_detach(dev, power_off))
>> +             return genpd_dev_pm_detach(dev);
>> +     return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
>> diff --git a/include/linux/pm.h b/include/linux/pm.h
>> index 72c0fe0..8176b07 100644
>> --- a/include/linux/pm.h
>> +++ b/include/linux/pm.h
>> @@ -621,6 +621,20 @@ struct dev_pm_domain {
>>       struct dev_pm_ops       ops;
>>  };
>>
>> +#ifdef CONFIG_PM
>> +extern int dev_pm_domain_attach(struct device *dev, bool power_on);
>> +extern int dev_pm_domain_detach(struct device *dev, bool power_off);
>> +#else
>> +static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
>> +{
>> +     return -ENODEV;
>> +}
>> +static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
>> +{
>> +     return -ENODEV;
>> +}
>> +#endif
>> +
>>  /*
>>   * The PM_EVENT_ messages are also used by drivers implementing the legacy
>>   * suspend framework, based on the ->suspend() and ->resume() callbacks common
>>
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
  2014-08-27  7:37       ` Ulf Hansson
@ 2014-08-27  7:38         ` Ulf Hansson
  -1 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:38 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Len Brown, Pavel Machek, Greg Kroah-Hartman, linux-pm,
	linux-arm-kernel, ACPI Devel Maling List, Geert Uytterhoeven,
	Kevin Hilman, Alan Stern, Daniel Lezcano, Tomasz Figa,
	devicetree, Linus Walleij, Simon Horman, Magnus Damm, Ben Dooks,
	Kukjin Kim, Stephen Boyd, Philipp Zabel, Mark Brown,
	Wolfram Sang

On 27 August 2014 09:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On 27 August 2014 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
>>> To maintain scalability let's add common methods to attach and detach
>>> a power domain for a device, dev_pm_domain_attach|detach().
>>>
>>> Typically dev_pm_domain_attach() shall be invoked from subsystem level
>>> code at the probe phase to try to attach a device to it's power domain.
>>> The reversed actions may be done a the remove phase and then by invoking
>>> dev_pm_domain_detach().
>>>
>>> The supported power domains at this point are the ACPI and the generic
>>> power domains.
>>>
>>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>>> ---
>>>  drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>>>  include/linux/pm.h          | 14 +++++++++++
>>>  2 files changed, 72 insertions(+)
>>>
>>> diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
>>> index df2e5ee..f544128 100644
>>> --- a/drivers/base/power/common.c
>>> +++ b/drivers/base/power/common.c
>>> @@ -11,6 +11,8 @@
>>>  #include <linux/export.h>
>>>  #include <linux/slab.h>
>>>  #include <linux/pm_clock.h>
>>> +#include <linux/acpi.h>
>>> +#include <linux/pm_domain.h>
>>>
>>>  /**
>>>   * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
>>> @@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
>>>       return ret;
>>>  }
>>>  EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
>>> +
>>> +/**
>>> + * dev_pm_domain_attach - Attach a device to it's power domain.
>>> + * @dev: Device to attach.
>>> + * @power_on: Used to indicate whether we should power on the device.
>>> + *
>>> + * The @dev may only be attached to a single power domain. By iterating through
>>> + * the available alternatives we try to find a valid domain for the device.
>>> + *
>>> + * This function should typically be invoked from subsystem level code during
>>> + * the probe phase. Especially for those that's hold devices which requires
>>> + * power management through power domains.
>>> + *
>>> + * Callers must ensure proper synchronization of this function with power
>>> + * management callbacks.
>>> + *
>>> + * Returns 0 on successfully attached power domain or negative error code.
>>> + */
>>> +int dev_pm_domain_attach(struct device *dev, bool power_on)
>>> +{
>>> +     int ret;
>>> +
>>> +     ret = acpi_dev_pm_attach(dev, power_on);
>>> +     if (ret == -EPROBE_DEFER)
>>
>> This doesn't seem to be possible today.  At least I'm not sure how it can
>> happen.
>
> You are right, but I did this intentionally. The reason for having
> this check, was that I didn't want the new API to put the limit on
> handling deferred probe.
>
> I happy the above check, if you think it's better!?

s/happy/happy to change

>
> Kind regards
> Uffe
>
>>
>>> +             return ret;
>>> +     else
>>> +             ret = genpd_dev_pm_attach(dev);
>>> +
>>> +     return ret;
>>> +}
>>> +EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
>>
>> On a more general note, are you sure that the place where we call
>> acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?
>>
>
> Currently, I haven't seen any place where it doesn't make sense.
>
> Additionally if such place is found, we may either just ignore it and
> let the caller of the API worry about the returned error or invoke the
> genpd/acpi API immediately instead.
>
>>> +
>>> +/**
>>> + * dev_pm_domain_detach - Detach a device from it's power domain.
>>> + * @dev: Device to attach.
>>> + * @power_off: Used to indicate whether we should power off the device.
>>> + *
>>> + * The @dev may be attached to a power domain. By iterating through the
>>> + * available alternatives we detach it from it's power domain.
>>> + *
>>> + * This functions will reverse the actions from dev_pm_domain_attach() and
>>> + * thus detach the @dev from it's power domain. Typically it should be invoked
>>> + * from subsystem level code during the remove phase.
>>> + *
>>> + * Callers must ensure proper synchronization of this function with power
>>> + * management callbacks.
>>> + *
>>> + * Returns 0 on successfully detached power domain or negative error code.
>>> + */
>>> +int dev_pm_domain_detach(struct device *dev, bool power_off)
>>> +{
>>> +     if (acpi_dev_pm_detach(dev, power_off))
>>> +             return genpd_dev_pm_detach(dev);
>>> +     return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
>>> diff --git a/include/linux/pm.h b/include/linux/pm.h
>>> index 72c0fe0..8176b07 100644
>>> --- a/include/linux/pm.h
>>> +++ b/include/linux/pm.h
>>> @@ -621,6 +621,20 @@ struct dev_pm_domain {
>>>       struct dev_pm_ops       ops;
>>>  };
>>>
>>> +#ifdef CONFIG_PM
>>> +extern int dev_pm_domain_attach(struct device *dev, bool power_on);
>>> +extern int dev_pm_domain_detach(struct device *dev, bool power_off);
>>> +#else
>>> +static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
>>> +{
>>> +     return -ENODEV;
>>> +}
>>> +static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
>>> +{
>>> +     return -ENODEV;
>>> +}
>>> +#endif
>>> +
>>>  /*
>>>   * The PM_EVENT_ messages are also used by drivers implementing the legacy
>>>   * suspend framework, based on the ->suspend() and ->resume() callbacks common
>>>
>>
>> --
>> I speak only for myself.
>> Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device
@ 2014-08-27  7:38         ` Ulf Hansson
  0 siblings, 0 replies; 36+ messages in thread
From: Ulf Hansson @ 2014-08-27  7:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 27 August 2014 09:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On 27 August 2014 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> On Tuesday, August 26, 2014 02:07:11 PM Ulf Hansson wrote:
>>> To maintain scalability let's add common methods to attach and detach
>>> a power domain for a device, dev_pm_domain_attach|detach().
>>>
>>> Typically dev_pm_domain_attach() shall be invoked from subsystem level
>>> code at the probe phase to try to attach a device to it's power domain.
>>> The reversed actions may be done a the remove phase and then by invoking
>>> dev_pm_domain_detach().
>>>
>>> The supported power domains at this point are the ACPI and the generic
>>> power domains.
>>>
>>> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
>>> ---
>>>  drivers/base/power/common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
>>>  include/linux/pm.h          | 14 +++++++++++
>>>  2 files changed, 72 insertions(+)
>>>
>>> diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
>>> index df2e5ee..f544128 100644
>>> --- a/drivers/base/power/common.c
>>> +++ b/drivers/base/power/common.c
>>> @@ -11,6 +11,8 @@
>>>  #include <linux/export.h>
>>>  #include <linux/slab.h>
>>>  #include <linux/pm_clock.h>
>>> +#include <linux/acpi.h>
>>> +#include <linux/pm_domain.h>
>>>
>>>  /**
>>>   * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
>>> @@ -82,3 +84,59 @@ int dev_pm_put_subsys_data(struct device *dev)
>>>       return ret;
>>>  }
>>>  EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
>>> +
>>> +/**
>>> + * dev_pm_domain_attach - Attach a device to it's power domain.
>>> + * @dev: Device to attach.
>>> + * @power_on: Used to indicate whether we should power on the device.
>>> + *
>>> + * The @dev may only be attached to a single power domain. By iterating through
>>> + * the available alternatives we try to find a valid domain for the device.
>>> + *
>>> + * This function should typically be invoked from subsystem level code during
>>> + * the probe phase. Especially for those that's hold devices which requires
>>> + * power management through power domains.
>>> + *
>>> + * Callers must ensure proper synchronization of this function with power
>>> + * management callbacks.
>>> + *
>>> + * Returns 0 on successfully attached power domain or negative error code.
>>> + */
>>> +int dev_pm_domain_attach(struct device *dev, bool power_on)
>>> +{
>>> +     int ret;
>>> +
>>> +     ret = acpi_dev_pm_attach(dev, power_on);
>>> +     if (ret == -EPROBE_DEFER)
>>
>> This doesn't seem to be possible today.  At least I'm not sure how it can
>> happen.
>
> You are right, but I did this intentionally. The reason for having
> this check, was that I didn't want the new API to put the limit on
> handling deferred probe.
>
> I happy the above check, if you think it's better!?

s/happy/happy to change

>
> Kind regards
> Uffe
>
>>
>>> +             return ret;
>>> +     else
>>> +             ret = genpd_dev_pm_attach(dev);
>>> +
>>> +     return ret;
>>> +}
>>> +EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
>>
>> On a more general note, are you sure that the place where we call
>> acpi_dev_pm_attach() will always be suitable for calling genpd_dev_pm_attach()?
>>
>
> Currently, I haven't seen any place where it doesn't make sense.
>
> Additionally if such place is found, we may either just ignore it and
> let the caller of the API worry about the returned error or invoke the
> genpd/acpi API immediately instead.
>
>>> +
>>> +/**
>>> + * dev_pm_domain_detach - Detach a device from it's power domain.
>>> + * @dev: Device to attach.
>>> + * @power_off: Used to indicate whether we should power off the device.
>>> + *
>>> + * The @dev may be attached to a power domain. By iterating through the
>>> + * available alternatives we detach it from it's power domain.
>>> + *
>>> + * This functions will reverse the actions from dev_pm_domain_attach() and
>>> + * thus detach the @dev from it's power domain. Typically it should be invoked
>>> + * from subsystem level code during the remove phase.
>>> + *
>>> + * Callers must ensure proper synchronization of this function with power
>>> + * management callbacks.
>>> + *
>>> + * Returns 0 on successfully detached power domain or negative error code.
>>> + */
>>> +int dev_pm_domain_detach(struct device *dev, bool power_off)
>>> +{
>>> +     if (acpi_dev_pm_detach(dev, power_off))
>>> +             return genpd_dev_pm_detach(dev);
>>> +     return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
>>> diff --git a/include/linux/pm.h b/include/linux/pm.h
>>> index 72c0fe0..8176b07 100644
>>> --- a/include/linux/pm.h
>>> +++ b/include/linux/pm.h
>>> @@ -621,6 +621,20 @@ struct dev_pm_domain {
>>>       struct dev_pm_ops       ops;
>>>  };
>>>
>>> +#ifdef CONFIG_PM
>>> +extern int dev_pm_domain_attach(struct device *dev, bool power_on);
>>> +extern int dev_pm_domain_detach(struct device *dev, bool power_off);
>>> +#else
>>> +static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
>>> +{
>>> +     return -ENODEV;
>>> +}
>>> +static inline int dev_pm_domain_detach(struct device *dev, bool power_off)
>>> +{
>>> +     return -ENODEV;
>>> +}
>>> +#endif
>>> +
>>>  /*
>>>   * The PM_EVENT_ messages are also used by drivers implementing the legacy
>>>   * suspend framework, based on the ->suspend() and ->resume() callbacks common
>>>
>>
>> --
>> I speak only for myself.
>> Rafael J. Wysocki, Intel Open Source Technology Center.

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

end of thread, other threads:[~2014-08-27  7:38 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26 12:07 [PATCH 0/9] PM / Domains: Generic OF-based support Ulf Hansson
2014-08-26 12:07 ` Ulf Hansson
2014-08-26 12:07 ` [PATCH 1/9] ACPI / PM: Let acpi_dev_pm_detach() return an error code Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson
2014-08-27  0:16   ` Rafael J. Wysocki
2014-08-27  0:16     ` Rafael J. Wysocki
2014-08-27  7:25     ` Ulf Hansson
2014-08-27  7:25       ` Ulf Hansson
2014-08-27  5:43   ` Zheng, Lv
2014-08-27  5:43     ` Zheng, Lv
2014-08-27  7:26     ` Ulf Hansson
2014-08-27  7:26       ` Ulf Hansson
2014-08-26 12:07 ` [PATCH 2/9] PM / Domains: Add generic OF-based power domain look-up Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson
2014-08-26 13:15   ` Philipp Zabel
2014-08-26 13:15     ` Philipp Zabel
2014-08-26 12:07 ` [PATCH 3/9] PM / Domains: Add APIs to attach/detach a power domain for a device Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson
2014-08-27  0:20   ` Rafael J. Wysocki
2014-08-27  0:20     ` Rafael J. Wysocki
2014-08-27  7:37     ` Ulf Hansson
2014-08-27  7:37       ` Ulf Hansson
2014-08-27  7:38       ` Ulf Hansson
2014-08-27  7:38         ` Ulf Hansson
2014-08-26 12:07 ` [PATCH 4/9] drivercore / platform: Convert to dev_pm_domain_attach|detach() Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson
     [not found] ` <1409054837-5667-1-git-send-email-ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2014-08-26 12:07   ` [PATCH 5/9] i2c: core: " Ulf Hansson
2014-08-26 12:07     ` Ulf Hansson
2014-08-26 12:07 ` [PATCH 6/9] mmc: sdio: " Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson
2014-08-26 12:07 ` [PATCH 7/9] spi: core: " Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson
2014-08-26 12:07 ` [PATCH 8/9] amba: Add support for attach/detach of power domains Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson
2014-08-26 12:07 ` [PATCH 9/9] ARM: exynos: Move to generic power domain bindings Ulf Hansson
2014-08-26 12:07   ` Ulf Hansson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.