All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] Generic Device Tree based power domain look-up
@ 2014-03-03 16:02 ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

Up till now there was no single generic method to bind devices to their
power domains using Device Tree. Each platform has been doing this using
its own way, example of which are Exynos power domain bindings [1] and
look-up code [2].

This series is intended to change this and provide generic DT bindings for
power domain specification and generic code performing look-up of power
domains and binding them to devices.

First two patches are the most important part of this series, as they
introduce $subject. Patch 3 converts mach-exynos to use the new generic
method. Further patches are adding one more user of the new code,
mach-s3c64xx, with first 3 patches (4-6) required to clean-up its power
domain driver a bit and last 3 patches (9-11) adding display support for
Mini6410 board, including a node for display controller (FIMD) which is
a power domain consumer.

The design of DT bindings and provider code is heavily inspired by
implementation of clock providers in Common Clock Framework, while
the code binding devices to power domains by my Exynos power domain
implementation (now removed by this series ;)).

Successfully tested on S3C6410-based Mini6410 board.

[1] Documentation/devicetree/bindings/arm/exynos/power_domain.txt
[2] arch/arm/mach-exynos/pm_domains.c

Changes since v1 (RFC):
[https://lkml.org/lkml/2014/1/11/141]
 - rebased onto current Rafael's linux-pm bleeding-edge branch,
 - reordered the patches a bit (to have the generic ones first),
 - dropped renaming of S3C64xx power domains (as suggested by Mark Brown),
 - added support for deferred probing (as suggested by Stephen Boyd),
 - fixed several minor issues pointed by Stephen Boyd,
 - replaced notifiers with direct hooks in driver core to make power domain
   support independent from specific bus type and allow error handling.

Tomasz Figa (11):
  base: power: Add generic OF-based power domain look-up
  drivercore: Bind/unbind power domain on probe/remove
  ARM: exynos: Move to generic power domain bindings
  ARM: s3c64xx: pm: Use name field of generic_pm_domain
  ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
  ARM: s3c64xx: pm: Add pwr_stat bit for domain G
  ARM: s3c64xx: pm: Add device tree based power domain instantiation
  ARM: s3c64xx: dt: Enable SoC-level power management
  ARM: dts: s3c64xx: Add nodes for power domains
  ARM: dts: s3c64xx: Add node for display controller
  ARM: dts: s3c6410-mini6410: Add support for LCD screen

 .../bindings/arm/exynos/power_domain.txt           |  12 +-
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 arch/arm/boot/dts/s3c6400.dtsi                     |   1 +
 arch/arm/boot/dts/s3c6410-mini6410.dts             |  33 +++
 arch/arm/boot/dts/s3c6410.dtsi                     |   1 +
 arch/arm/boot/dts/s3c64xx.dtsi                     |  13 +
 arch/arm/mach-exynos/pm_domains.c                  |  80 +-----
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c            |   8 +
 arch/arm/mach-s3c64xx/pm.c                         | 106 ++++++--
 drivers/base/dd.c                                  |   9 +-
 drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
 include/dt-bindings/arm/s3c64xx-power-domains.h    |  26 ++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 14 files changed, 576 insertions(+), 112 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt
 create mode 100644 include/dt-bindings/arm/s3c64xx-power-domains.h

-- 
1.9.0


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

* [PATCH v2 00/11] Generic Device Tree based power domain look-up
@ 2014-03-03 16:02 ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

Up till now there was no single generic method to bind devices to their
power domains using Device Tree. Each platform has been doing this using
its own way, example of which are Exynos power domain bindings [1] and
look-up code [2].

This series is intended to change this and provide generic DT bindings for
power domain specification and generic code performing look-up of power
domains and binding them to devices.

First two patches are the most important part of this series, as they
introduce $subject. Patch 3 converts mach-exynos to use the new generic
method. Further patches are adding one more user of the new code,
mach-s3c64xx, with first 3 patches (4-6) required to clean-up its power
domain driver a bit and last 3 patches (9-11) adding display support for
Mini6410 board, including a node for display controller (FIMD) which is
a power domain consumer.

The design of DT bindings and provider code is heavily inspired by
implementation of clock providers in Common Clock Framework, while
the code binding devices to power domains by my Exynos power domain
implementation (now removed by this series ;)).

Successfully tested on S3C6410-based Mini6410 board.

[1] Documentation/devicetree/bindings/arm/exynos/power_domain.txt
[2] arch/arm/mach-exynos/pm_domains.c

Changes since v1 (RFC):
[https://lkml.org/lkml/2014/1/11/141]
 - rebased onto current Rafael's linux-pm bleeding-edge branch,
 - reordered the patches a bit (to have the generic ones first),
 - dropped renaming of S3C64xx power domains (as suggested by Mark Brown),
 - added support for deferred probing (as suggested by Stephen Boyd),
 - fixed several minor issues pointed by Stephen Boyd,
 - replaced notifiers with direct hooks in driver core to make power domain
   support independent from specific bus type and allow error handling.

Tomasz Figa (11):
  base: power: Add generic OF-based power domain look-up
  drivercore: Bind/unbind power domain on probe/remove
  ARM: exynos: Move to generic power domain bindings
  ARM: s3c64xx: pm: Use name field of generic_pm_domain
  ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
  ARM: s3c64xx: pm: Add pwr_stat bit for domain G
  ARM: s3c64xx: pm: Add device tree based power domain instantiation
  ARM: s3c64xx: dt: Enable SoC-level power management
  ARM: dts: s3c64xx: Add nodes for power domains
  ARM: dts: s3c64xx: Add node for display controller
  ARM: dts: s3c6410-mini6410: Add support for LCD screen

 .../bindings/arm/exynos/power_domain.txt           |  12 +-
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 arch/arm/boot/dts/s3c6400.dtsi                     |   1 +
 arch/arm/boot/dts/s3c6410-mini6410.dts             |  33 +++
 arch/arm/boot/dts/s3c6410.dtsi                     |   1 +
 arch/arm/boot/dts/s3c64xx.dtsi                     |  13 +
 arch/arm/mach-exynos/pm_domains.c                  |  80 +-----
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c            |   8 +
 arch/arm/mach-s3c64xx/pm.c                         | 106 ++++++--
 drivers/base/dd.c                                  |   9 +-
 drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
 include/dt-bindings/arm/s3c64xx-power-domains.h    |  26 ++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 14 files changed, 576 insertions(+), 112 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt
 create mode 100644 include/dt-bindings/arm/s3c64xx-power-domains.h

-- 
1.9.0

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

* [PATCH v2 00/11] Generic Device Tree based power domain look-up
@ 2014-03-03 16:02 ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

Up till now there was no single generic method to bind devices to their
power domains using Device Tree. Each platform has been doing this using
its own way, example of which are Exynos power domain bindings [1] and
look-up code [2].

This series is intended to change this and provide generic DT bindings for
power domain specification and generic code performing look-up of power
domains and binding them to devices.

First two patches are the most important part of this series, as they
introduce $subject. Patch 3 converts mach-exynos to use the new generic
method. Further patches are adding one more user of the new code,
mach-s3c64xx, with first 3 patches (4-6) required to clean-up its power
domain driver a bit and last 3 patches (9-11) adding display support for
Mini6410 board, including a node for display controller (FIMD) which is
a power domain consumer.

The design of DT bindings and provider code is heavily inspired by
implementation of clock providers in Common Clock Framework, while
the code binding devices to power domains by my Exynos power domain
implementation (now removed by this series ;)).

Successfully tested on S3C6410-based Mini6410 board.

[1] Documentation/devicetree/bindings/arm/exynos/power_domain.txt
[2] arch/arm/mach-exynos/pm_domains.c

Changes since v1 (RFC):
[https://lkml.org/lkml/2014/1/11/141]
 - rebased onto current Rafael's linux-pm bleeding-edge branch,
 - reordered the patches a bit (to have the generic ones first),
 - dropped renaming of S3C64xx power domains (as suggested by Mark Brown),
 - added support for deferred probing (as suggested by Stephen Boyd),
 - fixed several minor issues pointed by Stephen Boyd,
 - replaced notifiers with direct hooks in driver core to make power domain
   support independent from specific bus type and allow error handling.

Tomasz Figa (11):
  base: power: Add generic OF-based power domain look-up
  drivercore: Bind/unbind power domain on probe/remove
  ARM: exynos: Move to generic power domain bindings
  ARM: s3c64xx: pm: Use name field of generic_pm_domain
  ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
  ARM: s3c64xx: pm: Add pwr_stat bit for domain G
  ARM: s3c64xx: pm: Add device tree based power domain instantiation
  ARM: s3c64xx: dt: Enable SoC-level power management
  ARM: dts: s3c64xx: Add nodes for power domains
  ARM: dts: s3c64xx: Add node for display controller
  ARM: dts: s3c6410-mini6410: Add support for LCD screen

 .../bindings/arm/exynos/power_domain.txt           |  12 +-
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 arch/arm/boot/dts/s3c6400.dtsi                     |   1 +
 arch/arm/boot/dts/s3c6410-mini6410.dts             |  33 +++
 arch/arm/boot/dts/s3c6410.dtsi                     |   1 +
 arch/arm/boot/dts/s3c64xx.dtsi                     |  13 +
 arch/arm/mach-exynos/pm_domains.c                  |  80 +-----
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c            |   8 +
 arch/arm/mach-s3c64xx/pm.c                         | 106 ++++++--
 drivers/base/dd.c                                  |   9 +-
 drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
 include/dt-bindings/arm/s3c64xx-power-domains.h    |  26 ++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 14 files changed, 576 insertions(+), 112 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/power_domain.txt
 create mode 100644 include/dt-bindings/arm/s3c64xx-power-domains.h

-- 
1.9.0

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

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 <tomasz.figa@gmail.com>
---
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 4 files changed, 399 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..93be5d9
--- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -3,12 +3,16 @@
  *
  * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
  *
+ * Support for Device Tree based power domain providers:
+ * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
+ *
  * This file is released under the GPLv2.
  */
 
 #include <linux/init.h>
 #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>
@@ -2177,3 +2181,297 @@ 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);
+
+/* See of_genpd_get_from_provider(). */
+static struct generic_pm_domain *__of_genpd_get_from_provider(
+					struct of_phandle_args *genpdspec)
+{
+	struct of_genpd_provider *provider;
+	struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
+
+	/* 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;
+	}
+
+	return genpd;
+}
+
+/**
+ * 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;
+
+	mutex_lock(&of_genpd_mutex);
+	genpd = __of_genpd_get_from_provider(genpdspec);
+	mutex_unlock(&of_genpd_mutex);
+
+	return genpd;
+}
+
+/*
+ * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
+ *
+ * The code below registers a notifier for platform bus devices'
+ * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
+ * domains by looking them up using Device Tree.
+ *
+ * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
+ * domain, since it no longer supports runtime PM without any driver bound
+ * to it.
+ *
+ * Both generic and legacy Samsung-specific DT bindings are supported to
+ * keep backwards compatibility with existing DTBs.
+ */
+
+/**
+ * genpd_bind_domain - Bind device to its power domain using Device Tree.
+ * @dev: Device to bind to its power domain.
+ *
+ * Tries to parse power domain specifier from device's OF node and if succeeds
+ * attaches the device to retrieved power domain.
+ *
+ * Returns 0 on success or negative error code otherwise.
+ */
+int genpd_bind_domain(struct device *dev)
+{
+	struct of_phandle_args pd_args;
+	struct generic_pm_domain *pd;
+	int ret;
+
+	if (!dev->of_node)
+		return 0;
+
+	ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
+					"#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 0;
+	}
+
+	pd = of_genpd_get_from_provider(&pd_args);
+	if (IS_ERR(pd)) {
+		if (PTR_ERR(pd) != -EPROBE_DEFER)
+			dev_err(dev, "failed to find power domain: %ld\n",
+				PTR_ERR(pd));
+		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);
+		return ret;
+	}
+
+	pm_genpd_dev_need_restore(dev, true);
+
+	return 0;
+}
+
+/**
+ * genpd_unbind_domain - Unbind device from its power domain.
+ * @dev: Device to unbind from its power domain.
+ *
+ * Unbinds device from power domain previously bound to it.
+ *
+ * Returns 0 on success or negative error code otherwise.
+ */
+int genpd_unbind_domain(struct device *dev)
+{
+	struct generic_pm_domain *pd = dev_to_genpd(dev);
+	int ret;
+
+	if (!dev->of_node || IS_ERR(pd))
+		return 0;
+
+	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;
+}
+#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 7c1d252..04473d4 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_bind_domain(struct device *dev);
+int genpd_unbind_domain(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_bind_domain(struct device *dev)
+{
+	return 0;
+}
+static inline int genpd_unbind_domain(struct device *dev)
+{
+	return 0;
+}
+#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
+
 #endif /* _LINUX_PM_DOMAIN_H */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 2fac9cc..45aa98e 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -306,6 +306,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.0


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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar

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 <tomasz.figa@gmail.com>
---
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 4 files changed, 399 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..93be5d9
--- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -3,12 +3,16 @@
  *
  * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
  *
+ * Support for Device Tree based power domain providers:
+ * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
+ *
  * This file is released under the GPLv2.
  */
 
 #include <linux/init.h>
 #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>
@@ -2177,3 +2181,297 @@ 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);
+
+/* See of_genpd_get_from_provider(). */
+static struct generic_pm_domain *__of_genpd_get_from_provider(
+					struct of_phandle_args *genpdspec)
+{
+	struct of_genpd_provider *provider;
+	struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
+
+	/* 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;
+	}
+
+	return genpd;
+}
+
+/**
+ * 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;
+
+	mutex_lock(&of_genpd_mutex);
+	genpd = __of_genpd_get_from_provider(genpdspec);
+	mutex_unlock(&of_genpd_mutex);
+
+	return genpd;
+}
+
+/*
+ * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
+ *
+ * The code below registers a notifier for platform bus devices'
+ * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
+ * domains by looking them up using Device Tree.
+ *
+ * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
+ * domain, since it no longer supports runtime PM without any driver bound
+ * to it.
+ *
+ * Both generic and legacy Samsung-specific DT bindings are supported to
+ * keep backwards compatibility with existing DTBs.
+ */
+
+/**
+ * genpd_bind_domain - Bind device to its power domain using Device Tree.
+ * @dev: Device to bind to its power domain.
+ *
+ * Tries to parse power domain specifier from device's OF node and if succeeds
+ * attaches the device to retrieved power domain.
+ *
+ * Returns 0 on success or negative error code otherwise.
+ */
+int genpd_bind_domain(struct device *dev)
+{
+	struct of_phandle_args pd_args;
+	struct generic_pm_domain *pd;
+	int ret;
+
+	if (!dev->of_node)
+		return 0;
+
+	ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
+					"#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 0;
+	}
+
+	pd = of_genpd_get_from_provider(&pd_args);
+	if (IS_ERR(pd)) {
+		if (PTR_ERR(pd) != -EPROBE_DEFER)
+			dev_err(dev, "failed to find power domain: %ld\n",
+				PTR_ERR(pd));
+		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);
+		return ret;
+	}
+
+	pm_genpd_dev_need_restore(dev, true);
+
+	return 0;
+}
+
+/**
+ * genpd_unbind_domain - Unbind device from its power domain.
+ * @dev: Device to unbind from its power domain.
+ *
+ * Unbinds device from power domain previously bound to it.
+ *
+ * Returns 0 on success or negative error code otherwise.
+ */
+int genpd_unbind_domain(struct device *dev)
+{
+	struct generic_pm_domain *pd = dev_to_genpd(dev);
+	int ret;
+
+	if (!dev->of_node || IS_ERR(pd))
+		return 0;
+
+	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;
+}
+#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 7c1d252..04473d4 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_bind_domain(struct device *dev);
+int genpd_unbind_domain(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_bind_domain(struct device *dev)
+{
+	return 0;
+}
+static inline int genpd_unbind_domain(struct device *dev)
+{
+	return 0;
+}
+#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
+
 #endif /* _LINUX_PM_DOMAIN_H */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 2fac9cc..45aa98e 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -306,6 +306,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.0

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

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 <tomasz.figa@gmail.com>
---
 .../devicetree/bindings/power/power_domain.txt     |  51 ++++
 drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
 include/linux/pm_domain.h                          |  46 ++++
 kernel/power/Kconfig                               |   4 +
 4 files changed, 399 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..93be5d9
--- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -3,12 +3,16 @@
  *
  * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
  *
+ * Support for Device Tree based power domain providers:
+ * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
+ *
  * This file is released under the GPLv2.
  */
 
 #include <linux/init.h>
 #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>
@@ -2177,3 +2181,297 @@ 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);
+
+/* See of_genpd_get_from_provider(). */
+static struct generic_pm_domain *__of_genpd_get_from_provider(
+					struct of_phandle_args *genpdspec)
+{
+	struct of_genpd_provider *provider;
+	struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
+
+	/* 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;
+	}
+
+	return genpd;
+}
+
+/**
+ * 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;
+
+	mutex_lock(&of_genpd_mutex);
+	genpd = __of_genpd_get_from_provider(genpdspec);
+	mutex_unlock(&of_genpd_mutex);
+
+	return genpd;
+}
+
+/*
+ * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
+ *
+ * The code below registers a notifier for platform bus devices'
+ * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
+ * domains by looking them up using Device Tree.
+ *
+ * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
+ * domain, since it no longer supports runtime PM without any driver bound
+ * to it.
+ *
+ * Both generic and legacy Samsung-specific DT bindings are supported to
+ * keep backwards compatibility with existing DTBs.
+ */
+
+/**
+ * genpd_bind_domain - Bind device to its power domain using Device Tree.
+ * @dev: Device to bind to its power domain.
+ *
+ * Tries to parse power domain specifier from device's OF node and if succeeds
+ * attaches the device to retrieved power domain.
+ *
+ * Returns 0 on success or negative error code otherwise.
+ */
+int genpd_bind_domain(struct device *dev)
+{
+	struct of_phandle_args pd_args;
+	struct generic_pm_domain *pd;
+	int ret;
+
+	if (!dev->of_node)
+		return 0;
+
+	ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
+					"#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 0;
+	}
+
+	pd = of_genpd_get_from_provider(&pd_args);
+	if (IS_ERR(pd)) {
+		if (PTR_ERR(pd) != -EPROBE_DEFER)
+			dev_err(dev, "failed to find power domain: %ld\n",
+				PTR_ERR(pd));
+		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);
+		return ret;
+	}
+
+	pm_genpd_dev_need_restore(dev, true);
+
+	return 0;
+}
+
+/**
+ * genpd_unbind_domain - Unbind device from its power domain.
+ * @dev: Device to unbind from its power domain.
+ *
+ * Unbinds device from power domain previously bound to it.
+ *
+ * Returns 0 on success or negative error code otherwise.
+ */
+int genpd_unbind_domain(struct device *dev)
+{
+	struct generic_pm_domain *pd = dev_to_genpd(dev);
+	int ret;
+
+	if (!dev->of_node || IS_ERR(pd))
+		return 0;
+
+	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;
+}
+#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 7c1d252..04473d4 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_bind_domain(struct device *dev);
+int genpd_unbind_domain(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_bind_domain(struct device *dev)
+{
+	return 0;
+}
+static inline int genpd_unbind_domain(struct device *dev)
+{
+	return 0;
+}
+#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
+
 #endif /* _LINUX_PM_DOMAIN_H */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 2fac9cc..45aa98e 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -306,6 +306,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.0

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

* [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

On a number of platforms, devices are part of controllable power
domains, which need to be enabled before such devices can be accessed
and may be powered down when the device is idle to save some power.
This means that on systems that support power domain control using
generic power domains subsystem, it is necessary to add device to its
power domain before binding a driver to it and remove it from its power
domain after its driver is unbound to make sure that an unused device
does not affect power domain state.

Since this is not limited to particular busses and specific
archs/platforms, it is more convenient to do the above directly in
driver core, just as done with pinctrl default configuration. This patch
adds necessary code to really_probe() and __device_release_driver() to
achieve this and maintain consistent stack-like ordering of operations
happening when binding and unbinding a driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/base/dd.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..78e5b36 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/async.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/pinctrl/devinfo.h>
 
@@ -273,6 +274,11 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 
 	dev->driver = drv;
 
+	/* If using genpd, bind power domain now before probing */
+	ret = genpd_bind_domain(dev);
+	if (ret)
+		goto probe_failed;
+
 	/* If using pinctrl, bind pins now before probing */
 	ret = pinctrl_bind_pins(dev);
 	if (ret)
@@ -303,6 +309,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 probe_failed:
 	devres_release_all(dev);
 	driver_sysfs_remove(dev);
+	genpd_unbind_domain(dev);
 	dev->driver = NULL;
 	dev_set_drvdata(dev, NULL);
 
@@ -513,7 +520,7 @@ static void __device_release_driver(struct device *dev)
 			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 						     BUS_NOTIFY_UNBOUND_DRIVER,
 						     dev);
-
+		genpd_unbind_domain(dev);
 	}
 }
 
-- 
1.9.0


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

* [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar

On a number of platforms, devices are part of controllable power
domains, which need to be enabled before such devices can be accessed
and may be powered down when the device is idle to save some power.
This means that on systems that support power domain control using
generic power domains subsystem, it is necessary to add device to its
power domain before binding a driver to it and remove it from its power
domain after its driver is unbound to make sure that an unused device
does not affect power domain state.

Since this is not limited to particular busses and specific
archs/platforms, it is more convenient to do the above directly in
driver core, just as done with pinctrl default configuration. This patch
adds necessary code to really_probe() and __device_release_driver() to
achieve this and maintain consistent stack-like ordering of operations
happening when binding and unbinding a driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/base/dd.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..78e5b36 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/async.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/pinctrl/devinfo.h>
 
@@ -273,6 +274,11 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 
 	dev->driver = drv;
 
+	/* If using genpd, bind power domain now before probing */
+	ret = genpd_bind_domain(dev);
+	if (ret)
+		goto probe_failed;
+
 	/* If using pinctrl, bind pins now before probing */
 	ret = pinctrl_bind_pins(dev);
 	if (ret)
@@ -303,6 +309,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 probe_failed:
 	devres_release_all(dev);
 	driver_sysfs_remove(dev);
+	genpd_unbind_domain(dev);
 	dev->driver = NULL;
 	dev_set_drvdata(dev, NULL);
 
@@ -513,7 +520,7 @@ static void __device_release_driver(struct device *dev)
 			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 						     BUS_NOTIFY_UNBOUND_DRIVER,
 						     dev);
-
+		genpd_unbind_domain(dev);
 	}
 }
 
-- 
1.9.0

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

* [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

On a number of platforms, devices are part of controllable power
domains, which need to be enabled before such devices can be accessed
and may be powered down when the device is idle to save some power.
This means that on systems that support power domain control using
generic power domains subsystem, it is necessary to add device to its
power domain before binding a driver to it and remove it from its power
domain after its driver is unbound to make sure that an unused device
does not affect power domain state.

Since this is not limited to particular busses and specific
archs/platforms, it is more convenient to do the above directly in
driver core, just as done with pinctrl default configuration. This patch
adds necessary code to really_probe() and __device_release_driver() to
achieve this and maintain consistent stack-like ordering of operations
happening when binding and unbinding a driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/base/dd.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..78e5b36 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/async.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/pinctrl/devinfo.h>
 
@@ -273,6 +274,11 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 
 	dev->driver = drv;
 
+	/* If using genpd, bind power domain now before probing */
+	ret = genpd_bind_domain(dev);
+	if (ret)
+		goto probe_failed;
+
 	/* If using pinctrl, bind pins now before probing */
 	ret = pinctrl_bind_pins(dev);
 	if (ret)
@@ -303,6 +309,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 probe_failed:
 	devres_release_all(dev);
 	driver_sysfs_remove(dev);
+	genpd_unbind_domain(dev);
 	dev->driver = NULL;
 	dev_set_drvdata(dev, NULL);
 
@@ -513,7 +520,7 @@ static void __device_release_driver(struct device *dev)
 			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 						     BUS_NOTIFY_UNBOUND_DRIVER,
 						     dev);
-
+		genpd_unbind_domain(dev);
 	}
 }
 
-- 
1.9.0

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

* [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

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

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 .../bindings/arm/exynos/power_domain.txt           | 12 ++--
 arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
 kernel/power/Kconfig                               |  2 +-
 3 files changed, 7 insertions(+), 87 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index 5216b41..60f26a8 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.
 
 Node of a device using power domains must have a samsung,power-domain property
 defined with a phandle to respective power domain.
@@ -17,12 +19,8 @@ Example:
 	lcd0: power-domain-lcd0 {
 		compatible = "samsung,exynos4210-pd";
 		reg = <0x10023C00 0x10>;
+		#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 8fd2488..48ee6c9 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -75,78 +75,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;
@@ -156,8 +84,6 @@ static __init int exynos4_pm_init_power_domain(void)
 		struct exynos_pm_domain *pd;
 		int on;
 
-		pdev = of_find_device_by_node(np);
-
 		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 		if (!pd) {
 			pr_err("%s: failed to allocate memory for domain\n",
@@ -170,17 +96,13 @@ 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;
-
-		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 45aa98e..b17588c 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -308,7 +308,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.0


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

* [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

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

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 .../bindings/arm/exynos/power_domain.txt           | 12 ++--
 arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
 kernel/power/Kconfig                               |  2 +-
 3 files changed, 7 insertions(+), 87 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index 5216b41..60f26a8 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.
 
 Node of a device using power domains must have a samsung,power-domain property
 defined with a phandle to respective power domain.
@@ -17,12 +19,8 @@ Example:
 	lcd0: power-domain-lcd0 {
 		compatible = "samsung,exynos4210-pd";
 		reg = <0x10023C00 0x10>;
+		#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 8fd2488..48ee6c9 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -75,78 +75,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;
@@ -156,8 +84,6 @@ static __init int exynos4_pm_init_power_domain(void)
 		struct exynos_pm_domain *pd;
 		int on;
 
-		pdev = of_find_device_by_node(np);
-
 		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 		if (!pd) {
 			pr_err("%s: failed to allocate memory for domain\n",
@@ -170,17 +96,13 @@ 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;
-
-		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 45aa98e..b17588c 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -308,7 +308,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.0

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

* [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 .../bindings/arm/exynos/power_domain.txt           | 12 ++--
 arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
 kernel/power/Kconfig                               |  2 +-
 3 files changed, 7 insertions(+), 87 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index 5216b41..60f26a8 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.
 
 Node of a device using power domains must have a samsung,power-domain property
 defined with a phandle to respective power domain.
@@ -17,12 +19,8 @@ Example:
 	lcd0: power-domain-lcd0 {
 		compatible = "samsung,exynos4210-pd";
 		reg = <0x10023C00 0x10>;
+		#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 8fd2488..48ee6c9 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -75,78 +75,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;
@@ -156,8 +84,6 @@ static __init int exynos4_pm_init_power_domain(void)
 		struct exynos_pm_domain *pd;
 		int on;
 
-		pdev = of_find_device_by_node(np);
-
 		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 		if (!pd) {
 			pr_err("%s: failed to allocate memory for domain\n",
@@ -170,17 +96,13 @@ 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;
-
-		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 45aa98e..b17588c 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -308,7 +308,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.0

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

* [PATCH v2 04/11] ARM: s3c64xx: pm: Use name field of generic_pm_domain
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

This patch removes name field from private s3c64xx_pm_domain struct and
moves domain name to dedicated field of generic_pm_domain struct.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index b5a6698..df4b7b2 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -36,7 +36,6 @@
 #include "regs-syscon-power.h"
 
 struct s3c64xx_pm_domain {
-	char *const name;
 	u32 ena;
 	u32 pwr_stat;
 	struct generic_pm_domain pd;
@@ -77,7 +76,7 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 		} while (retry--);
 
 		if (!retry) {
-			pr_err("Failed to start domain %s\n", pd->name);
+			pr_err("Failed to start domain %s\n", pd->pd.name);
 			return -EBUSY;
 		}
 	}
@@ -86,78 +85,78 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 }
 
 static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
-	.name = "IROM",
 	.ena = S3C64XX_NORMALCFG_IROM_ON,
 	.pd = {
+		.name = "IROM",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_etm = {
-	.name = "ETM",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_ETM_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_ETM,
 	.pd = {
+		.name = "ETM",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_s = {
-	.name = "S",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_S_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_S,
 	.pd = {
+		.name = "S",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_f = {
-	.name = "F",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_F_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_F,
 	.pd = {
+		.name = "F",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_p = {
-	.name = "P",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_P_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_P,
 	.pd = {
+		.name = "P",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_i = {
-	.name = "I",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_I_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_I,
 	.pd = {
+		.name = "I",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_g = {
-	.name = "G",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
 	.pd = {
+		.name = "G",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_v = {
-	.name = "V",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_V_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_V,
 	.pd = {
+		.name = "V",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
-- 
1.9.0


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

* [PATCH v2 04/11] ARM: s3c64xx: pm: Use name field of generic_pm_domain
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

This patch removes name field from private s3c64xx_pm_domain struct and
moves domain name to dedicated field of generic_pm_domain struct.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index b5a6698..df4b7b2 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -36,7 +36,6 @@
 #include "regs-syscon-power.h"
 
 struct s3c64xx_pm_domain {
-	char *const name;
 	u32 ena;
 	u32 pwr_stat;
 	struct generic_pm_domain pd;
@@ -77,7 +76,7 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 		} while (retry--);
 
 		if (!retry) {
-			pr_err("Failed to start domain %s\n", pd->name);
+			pr_err("Failed to start domain %s\n", pd->pd.name);
 			return -EBUSY;
 		}
 	}
@@ -86,78 +85,78 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 }
 
 static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
-	.name = "IROM",
 	.ena = S3C64XX_NORMALCFG_IROM_ON,
 	.pd = {
+		.name = "IROM",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_etm = {
-	.name = "ETM",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_ETM_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_ETM,
 	.pd = {
+		.name = "ETM",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_s = {
-	.name = "S",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_S_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_S,
 	.pd = {
+		.name = "S",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_f = {
-	.name = "F",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_F_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_F,
 	.pd = {
+		.name = "F",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_p = {
-	.name = "P",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_P_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_P,
 	.pd = {
+		.name = "P",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_i = {
-	.name = "I",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_I_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_I,
 	.pd = {
+		.name = "I",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_g = {
-	.name = "G",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
 	.pd = {
+		.name = "G",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_v = {
-	.name = "V",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_V_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_V,
 	.pd = {
+		.name = "V",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
-- 
1.9.0

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

* [PATCH v2 04/11] ARM: s3c64xx: pm: Use name field of generic_pm_domain
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes name field from private s3c64xx_pm_domain struct and
moves domain name to dedicated field of generic_pm_domain struct.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index b5a6698..df4b7b2 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -36,7 +36,6 @@
 #include "regs-syscon-power.h"
 
 struct s3c64xx_pm_domain {
-	char *const name;
 	u32 ena;
 	u32 pwr_stat;
 	struct generic_pm_domain pd;
@@ -77,7 +76,7 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 		} while (retry--);
 
 		if (!retry) {
-			pr_err("Failed to start domain %s\n", pd->name);
+			pr_err("Failed to start domain %s\n", pd->pd.name);
 			return -EBUSY;
 		}
 	}
@@ -86,78 +85,78 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 }
 
 static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
-	.name = "IROM",
 	.ena = S3C64XX_NORMALCFG_IROM_ON,
 	.pd = {
+		.name = "IROM",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_etm = {
-	.name = "ETM",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_ETM_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_ETM,
 	.pd = {
+		.name = "ETM",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_s = {
-	.name = "S",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_S_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_S,
 	.pd = {
+		.name = "S",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_f = {
-	.name = "F",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_F_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_F,
 	.pd = {
+		.name = "F",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_p = {
-	.name = "P",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_P_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_P,
 	.pd = {
+		.name = "P",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_i = {
-	.name = "I",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_I_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_I,
 	.pd = {
+		.name = "I",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_g = {
-	.name = "G",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
 	.pd = {
+		.name = "G",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
 };
 
 static struct s3c64xx_pm_domain s3c64xx_pm_v = {
-	.name = "V",
 	.ena = S3C64XX_NORMALCFG_DOMAIN_V_ON,
 	.pwr_stat = S3C64XX_BLKPWRSTAT_V,
 	.pd = {
+		.name = "V",
 		.power_off = s3c64xx_pd_off,
 		.power_on = s3c64xx_pd_on,
 	},
-- 
1.9.0

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

* [PATCH v2 05/11] ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

This patch adds always_on field to s3c64xx_pm_domain struct to allow
handling registration of all domains in the same way, without the need
to have separate arrays for normal and always on domains.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index df4b7b2..c930245 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -36,6 +36,7 @@
 #include "regs-syscon-power.h"
 
 struct s3c64xx_pm_domain {
+	bool always_on;
 	u32 ena;
 	u32 pwr_stat;
 	struct generic_pm_domain pd;
@@ -85,6 +86,7 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 }
 
 static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
+	.always_on = true,
 	.ena = S3C64XX_NORMALCFG_IROM_ON,
 	.pd = {
 		.name = "IROM",
@@ -162,11 +164,8 @@ static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	},
 };
 
-static struct s3c64xx_pm_domain *s3c64xx_always_on_pm_domains[] = {
-	&s3c64xx_pm_irom,
-};
-
 static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
+	&s3c64xx_pm_irom,
 	&s3c64xx_pm_etm,
 	&s3c64xx_pm_g,
 	&s3c64xx_pm_v,
@@ -312,12 +311,16 @@ int __init s3c64xx_pm_init(void)
 
 	s3c_pm_init();
 
-	for (i = 0; i < ARRAY_SIZE(s3c64xx_always_on_pm_domains); i++)
-		pm_genpd_init(&s3c64xx_always_on_pm_domains[i]->pd,
-			      &pm_domain_always_on_gov, false);
 
-	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++)
-		pm_genpd_init(&s3c64xx_pm_domains[i]->pd, NULL, false);
+	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) {
+		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
+		struct dev_power_governor *gov = NULL;
+
+		if (pd->always_on)
+			gov = &pm_domain_always_on_gov;
+
+		pm_genpd_init(&pd->pd, gov, false);
+	}
 
 #ifdef CONFIG_S3C_DEV_FB
 	if (dev_get_platdata(&s3c_device_fb.dev))
-- 
1.9.0


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

* [PATCH v2 05/11] ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

This patch adds always_on field to s3c64xx_pm_domain struct to allow
handling registration of all domains in the same way, without the need
to have separate arrays for normal and always on domains.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index df4b7b2..c930245 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -36,6 +36,7 @@
 #include "regs-syscon-power.h"
 
 struct s3c64xx_pm_domain {
+	bool always_on;
 	u32 ena;
 	u32 pwr_stat;
 	struct generic_pm_domain pd;
@@ -85,6 +86,7 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 }
 
 static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
+	.always_on = true,
 	.ena = S3C64XX_NORMALCFG_IROM_ON,
 	.pd = {
 		.name = "IROM",
@@ -162,11 +164,8 @@ static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	},
 };
 
-static struct s3c64xx_pm_domain *s3c64xx_always_on_pm_domains[] = {
-	&s3c64xx_pm_irom,
-};
-
 static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
+	&s3c64xx_pm_irom,
 	&s3c64xx_pm_etm,
 	&s3c64xx_pm_g,
 	&s3c64xx_pm_v,
@@ -312,12 +311,16 @@ int __init s3c64xx_pm_init(void)
 
 	s3c_pm_init();
 
-	for (i = 0; i < ARRAY_SIZE(s3c64xx_always_on_pm_domains); i++)
-		pm_genpd_init(&s3c64xx_always_on_pm_domains[i]->pd,
-			      &pm_domain_always_on_gov, false);
 
-	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++)
-		pm_genpd_init(&s3c64xx_pm_domains[i]->pd, NULL, false);
+	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) {
+		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
+		struct dev_power_governor *gov = NULL;
+
+		if (pd->always_on)
+			gov = &pm_domain_always_on_gov;
+
+		pm_genpd_init(&pd->pd, gov, false);
+	}
 
 #ifdef CONFIG_S3C_DEV_FB
 	if (dev_get_platdata(&s3c_device_fb.dev))
-- 
1.9.0


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

* [PATCH v2 05/11] ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds always_on field to s3c64xx_pm_domain struct to allow
handling registration of all domains in the same way, without the need
to have separate arrays for normal and always on domains.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index df4b7b2..c930245 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -36,6 +36,7 @@
 #include "regs-syscon-power.h"
 
 struct s3c64xx_pm_domain {
+	bool always_on;
 	u32 ena;
 	u32 pwr_stat;
 	struct generic_pm_domain pd;
@@ -85,6 +86,7 @@ static int s3c64xx_pd_on(struct generic_pm_domain *domain)
 }
 
 static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
+	.always_on = true,
 	.ena = S3C64XX_NORMALCFG_IROM_ON,
 	.pd = {
 		.name = "IROM",
@@ -162,11 +164,8 @@ static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	},
 };
 
-static struct s3c64xx_pm_domain *s3c64xx_always_on_pm_domains[] = {
-	&s3c64xx_pm_irom,
-};
-
 static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
+	&s3c64xx_pm_irom,
 	&s3c64xx_pm_etm,
 	&s3c64xx_pm_g,
 	&s3c64xx_pm_v,
@@ -312,12 +311,16 @@ int __init s3c64xx_pm_init(void)
 
 	s3c_pm_init();
 
-	for (i = 0; i < ARRAY_SIZE(s3c64xx_always_on_pm_domains); i++)
-		pm_genpd_init(&s3c64xx_always_on_pm_domains[i]->pd,
-			      &pm_domain_always_on_gov, false);
 
-	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++)
-		pm_genpd_init(&s3c64xx_pm_domains[i]->pd, NULL, false);
+	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) {
+		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
+		struct dev_power_governor *gov = NULL;
+
+		if (pd->always_on)
+			gov = &pm_domain_always_on_gov;
+
+		pm_genpd_init(&pd->pd, gov, false);
+	}
 
 #ifdef CONFIG_S3C_DEV_FB
 	if (dev_get_platdata(&s3c_device_fb.dev))
-- 
1.9.0

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

* [PATCH v2 06/11] ARM: s3c64xx: pm: Add pwr_stat bit for domain G
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

There is a status bit for domain G present in BLK_PWR_STAT register, but
it is currently not specified in the driver.

This patch adds the status bit of domain G to structure describing it.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index c930245..b422eed 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -147,6 +147,7 @@ static struct s3c64xx_pm_domain s3c64xx_pm_i = {
 
 static struct s3c64xx_pm_domain s3c64xx_pm_g = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
+	.pwr_stat = S3C64XX_BLKPWRSTAT_G,
 	.pd = {
 		.name = "G",
 		.power_off = s3c64xx_pd_off,
-- 
1.9.0


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

* [PATCH v2 06/11] ARM: s3c64xx: pm: Add pwr_stat bit for domain G
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

There is a status bit for domain G present in BLK_PWR_STAT register, but
it is currently not specified in the driver.

This patch adds the status bit of domain G to structure describing it.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index c930245..b422eed 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -147,6 +147,7 @@ static struct s3c64xx_pm_domain s3c64xx_pm_i = {
 
 static struct s3c64xx_pm_domain s3c64xx_pm_g = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
+	.pwr_stat = S3C64XX_BLKPWRSTAT_G,
 	.pd = {
 		.name = "G",
 		.power_off = s3c64xx_pd_off,
-- 
1.9.0


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

* [PATCH v2 06/11] ARM: s3c64xx: pm: Add pwr_stat bit for domain G
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

There is a status bit for domain G present in BLK_PWR_STAT register, but
it is currently not specified in the driver.

This patch adds the status bit of domain G to structure describing it.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index c930245..b422eed 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -147,6 +147,7 @@ static struct s3c64xx_pm_domain s3c64xx_pm_i = {
 
 static struct s3c64xx_pm_domain s3c64xx_pm_g = {
 	.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
+	.pwr_stat = S3C64XX_BLKPWRSTAT_G,
 	.pd = {
 		.name = "G",
 		.power_off = s3c64xx_pd_off,
-- 
1.9.0

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

* [PATCH v2 07/11] ARM: s3c64xx: pm: Add device tree based power domain instantiation
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

This patch adds support for registering power domains of S3C64xx SoCs
and binding devices to them using device tree.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c                      | 71 +++++++++++++++++++++----
 include/dt-bindings/arm/s3c64xx-power-domains.h | 26 +++++++++
 2 files changed, 88 insertions(+), 9 deletions(-)
 create mode 100644 include/dt-bindings/arm/s3c64xx-power-domains.h

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index b422eed..cebbd44 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -17,8 +17,11 @@
 #include <linux/serial_core.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 #include <linux/pm_domain.h>
 
+#include <dt-bindings/arm/s3c64xx-power-domains.h>
+
 #include <mach/map.h>
 #include <mach/irqs.h>
 
@@ -165,17 +168,63 @@ static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	},
 };
 
-static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
-	&s3c64xx_pm_irom,
-	&s3c64xx_pm_etm,
-	&s3c64xx_pm_g,
-	&s3c64xx_pm_v,
-	&s3c64xx_pm_i,
-	&s3c64xx_pm_p,
-	&s3c64xx_pm_s,
-	&s3c64xx_pm_f,
+static struct s3c64xx_pm_domain *s3c64xx_pm_domains[NR_DOMAINS] = {
+	[DOMAIN_V] = &s3c64xx_pm_v,
+	[DOMAIN_G] = &s3c64xx_pm_g,
+	[DOMAIN_I] = &s3c64xx_pm_i,
+	[DOMAIN_P] = &s3c64xx_pm_p,
+	[DOMAIN_F] = &s3c64xx_pm_f,
+	[DOMAIN_S] = &s3c64xx_pm_s,
+	[DOMAIN_ETM] = &s3c64xx_pm_etm,
+	[DOMAIN_IROM] = &s3c64xx_pm_irom,
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id s3c64xx_pd_matches[] = {
+	{ .compatible = "samsung,s3c6400-clock", },
+	{ .compatible = "samsung,s3c6410-clock", },
+	{ },
 };
 
+static struct genpd_onecell_data pd_data;
+
+static int s3c64xx_pm_parse_domains(void)
+{
+	struct device_node *np;
+	int i;
+
+	np = of_find_matching_node(NULL, s3c64xx_pd_matches);
+	if (!np)
+		return -ENODEV;
+
+	pd_data.domains = kcalloc(ARRAY_SIZE(s3c64xx_pm_domains),
+				  sizeof(*pd_data.domains), GFP_KERNEL);
+	if (!pd_data.domains)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); ++i) {
+		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
+		struct dev_power_governor *gov = NULL;
+		int on;
+
+		on = __raw_readl(S3C64XX_NORMAL_CFG) & pd->ena;
+
+		if (pd->always_on)
+			gov = &pm_domain_always_on_gov;
+
+		pm_genpd_init(&pd->pd, gov, !on);
+		pd_data.domains[i] = &pd->pd;
+
+		pr_debug("%s: registered domain %s\n", __func__, pd->pd.name);
+	}
+
+	pd_data.domain_num = ARRAY_SIZE(s3c64xx_pm_domains);
+	of_genpd_add_provider(np, of_genpd_xlate_onecell, &pd_data);
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
 void s3c_pm_debug_smdkled(u32 set, u32 clear)
 {
@@ -312,6 +361,10 @@ int __init s3c64xx_pm_init(void)
 
 	s3c_pm_init();
 
+#ifdef CONFIG_OF
+	if (of_have_populated_dt())
+		return s3c64xx_pm_parse_domains();
+#endif
 
 	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) {
 		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
diff --git a/include/dt-bindings/arm/s3c64xx-power-domains.h b/include/dt-bindings/arm/s3c64xx-power-domains.h
new file mode 100644
index 0000000..ce39bef
--- /dev/null
+++ b/include/dt-bindings/arm/s3c64xx-power-domains.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 Tomasz Figa <tomasz.figa at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Device Tree binding constants for Samsung S3C64xx power domains.
+*/
+
+#ifndef _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+#define _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+
+#define DOMAIN_V		0
+#define DOMAIN_G		1
+#define DOMAIN_I		2
+#define DOMAIN_P		3
+#define DOMAIN_F		4
+#define DOMAIN_S		5
+#define DOMAIN_ETM		6
+#define DOMAIN_IROM		7
+
+/* Total number of clocks. */
+#define NR_DOMAINS		(DOMAIN_IROM + 1)
+
+#endif /* _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H */
-- 
1.9.0


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

* [PATCH v2 07/11] ARM: s3c64xx: pm: Add device tree based power domain instantiation
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

This patch adds support for registering power domains of S3C64xx SoCs
and binding devices to them using device tree.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c                      | 71 +++++++++++++++++++++----
 include/dt-bindings/arm/s3c64xx-power-domains.h | 26 +++++++++
 2 files changed, 88 insertions(+), 9 deletions(-)
 create mode 100644 include/dt-bindings/arm/s3c64xx-power-domains.h

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index b422eed..cebbd44 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -17,8 +17,11 @@
 #include <linux/serial_core.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 #include <linux/pm_domain.h>
 
+#include <dt-bindings/arm/s3c64xx-power-domains.h>
+
 #include <mach/map.h>
 #include <mach/irqs.h>
 
@@ -165,17 +168,63 @@ static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	},
 };
 
-static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
-	&s3c64xx_pm_irom,
-	&s3c64xx_pm_etm,
-	&s3c64xx_pm_g,
-	&s3c64xx_pm_v,
-	&s3c64xx_pm_i,
-	&s3c64xx_pm_p,
-	&s3c64xx_pm_s,
-	&s3c64xx_pm_f,
+static struct s3c64xx_pm_domain *s3c64xx_pm_domains[NR_DOMAINS] = {
+	[DOMAIN_V] = &s3c64xx_pm_v,
+	[DOMAIN_G] = &s3c64xx_pm_g,
+	[DOMAIN_I] = &s3c64xx_pm_i,
+	[DOMAIN_P] = &s3c64xx_pm_p,
+	[DOMAIN_F] = &s3c64xx_pm_f,
+	[DOMAIN_S] = &s3c64xx_pm_s,
+	[DOMAIN_ETM] = &s3c64xx_pm_etm,
+	[DOMAIN_IROM] = &s3c64xx_pm_irom,
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id s3c64xx_pd_matches[] = {
+	{ .compatible = "samsung,s3c6400-clock", },
+	{ .compatible = "samsung,s3c6410-clock", },
+	{ },
 };
 
+static struct genpd_onecell_data pd_data;
+
+static int s3c64xx_pm_parse_domains(void)
+{
+	struct device_node *np;
+	int i;
+
+	np = of_find_matching_node(NULL, s3c64xx_pd_matches);
+	if (!np)
+		return -ENODEV;
+
+	pd_data.domains = kcalloc(ARRAY_SIZE(s3c64xx_pm_domains),
+				  sizeof(*pd_data.domains), GFP_KERNEL);
+	if (!pd_data.domains)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); ++i) {
+		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
+		struct dev_power_governor *gov = NULL;
+		int on;
+
+		on = __raw_readl(S3C64XX_NORMAL_CFG) & pd->ena;
+
+		if (pd->always_on)
+			gov = &pm_domain_always_on_gov;
+
+		pm_genpd_init(&pd->pd, gov, !on);
+		pd_data.domains[i] = &pd->pd;
+
+		pr_debug("%s: registered domain %s\n", __func__, pd->pd.name);
+	}
+
+	pd_data.domain_num = ARRAY_SIZE(s3c64xx_pm_domains);
+	of_genpd_add_provider(np, of_genpd_xlate_onecell, &pd_data);
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
 void s3c_pm_debug_smdkled(u32 set, u32 clear)
 {
@@ -312,6 +361,10 @@ int __init s3c64xx_pm_init(void)
 
 	s3c_pm_init();
 
+#ifdef CONFIG_OF
+	if (of_have_populated_dt())
+		return s3c64xx_pm_parse_domains();
+#endif
 
 	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) {
 		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
diff --git a/include/dt-bindings/arm/s3c64xx-power-domains.h b/include/dt-bindings/arm/s3c64xx-power-domains.h
new file mode 100644
index 0000000..ce39bef
--- /dev/null
+++ b/include/dt-bindings/arm/s3c64xx-power-domains.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 Tomasz Figa <tomasz.figa at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Device Tree binding constants for Samsung S3C64xx power domains.
+*/
+
+#ifndef _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+#define _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+
+#define DOMAIN_V		0
+#define DOMAIN_G		1
+#define DOMAIN_I		2
+#define DOMAIN_P		3
+#define DOMAIN_F		4
+#define DOMAIN_S		5
+#define DOMAIN_ETM		6
+#define DOMAIN_IROM		7
+
+/* Total number of clocks. */
+#define NR_DOMAINS		(DOMAIN_IROM + 1)
+
+#endif /* _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H */
-- 
1.9.0


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

* [PATCH v2 07/11] ARM: s3c64xx: pm: Add device tree based power domain instantiation
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for registering power domains of S3C64xx SoCs
and binding devices to them using device tree.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/pm.c                      | 71 +++++++++++++++++++++----
 include/dt-bindings/arm/s3c64xx-power-domains.h | 26 +++++++++
 2 files changed, 88 insertions(+), 9 deletions(-)
 create mode 100644 include/dt-bindings/arm/s3c64xx-power-domains.h

diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index b422eed..cebbd44 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -17,8 +17,11 @@
 #include <linux/serial_core.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 #include <linux/pm_domain.h>
 
+#include <dt-bindings/arm/s3c64xx-power-domains.h>
+
 #include <mach/map.h>
 #include <mach/irqs.h>
 
@@ -165,17 +168,63 @@ static struct s3c64xx_pm_domain s3c64xx_pm_v = {
 	},
 };
 
-static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
-	&s3c64xx_pm_irom,
-	&s3c64xx_pm_etm,
-	&s3c64xx_pm_g,
-	&s3c64xx_pm_v,
-	&s3c64xx_pm_i,
-	&s3c64xx_pm_p,
-	&s3c64xx_pm_s,
-	&s3c64xx_pm_f,
+static struct s3c64xx_pm_domain *s3c64xx_pm_domains[NR_DOMAINS] = {
+	[DOMAIN_V] = &s3c64xx_pm_v,
+	[DOMAIN_G] = &s3c64xx_pm_g,
+	[DOMAIN_I] = &s3c64xx_pm_i,
+	[DOMAIN_P] = &s3c64xx_pm_p,
+	[DOMAIN_F] = &s3c64xx_pm_f,
+	[DOMAIN_S] = &s3c64xx_pm_s,
+	[DOMAIN_ETM] = &s3c64xx_pm_etm,
+	[DOMAIN_IROM] = &s3c64xx_pm_irom,
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id s3c64xx_pd_matches[] = {
+	{ .compatible = "samsung,s3c6400-clock", },
+	{ .compatible = "samsung,s3c6410-clock", },
+	{ },
 };
 
+static struct genpd_onecell_data pd_data;
+
+static int s3c64xx_pm_parse_domains(void)
+{
+	struct device_node *np;
+	int i;
+
+	np = of_find_matching_node(NULL, s3c64xx_pd_matches);
+	if (!np)
+		return -ENODEV;
+
+	pd_data.domains = kcalloc(ARRAY_SIZE(s3c64xx_pm_domains),
+				  sizeof(*pd_data.domains), GFP_KERNEL);
+	if (!pd_data.domains)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); ++i) {
+		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
+		struct dev_power_governor *gov = NULL;
+		int on;
+
+		on = __raw_readl(S3C64XX_NORMAL_CFG) & pd->ena;
+
+		if (pd->always_on)
+			gov = &pm_domain_always_on_gov;
+
+		pm_genpd_init(&pd->pd, gov, !on);
+		pd_data.domains[i] = &pd->pd;
+
+		pr_debug("%s: registered domain %s\n", __func__, pd->pd.name);
+	}
+
+	pd_data.domain_num = ARRAY_SIZE(s3c64xx_pm_domains);
+	of_genpd_add_provider(np, of_genpd_xlate_onecell, &pd_data);
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
 void s3c_pm_debug_smdkled(u32 set, u32 clear)
 {
@@ -312,6 +361,10 @@ int __init s3c64xx_pm_init(void)
 
 	s3c_pm_init();
 
+#ifdef CONFIG_OF
+	if (of_have_populated_dt())
+		return s3c64xx_pm_parse_domains();
+#endif
 
 	for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++) {
 		struct s3c64xx_pm_domain *pd = s3c64xx_pm_domains[i];
diff --git a/include/dt-bindings/arm/s3c64xx-power-domains.h b/include/dt-bindings/arm/s3c64xx-power-domains.h
new file mode 100644
index 0000000..ce39bef
--- /dev/null
+++ b/include/dt-bindings/arm/s3c64xx-power-domains.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Device Tree binding constants for Samsung S3C64xx power domains.
+*/
+
+#ifndef _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+#define _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H
+
+#define DOMAIN_V		0
+#define DOMAIN_G		1
+#define DOMAIN_I		2
+#define DOMAIN_P		3
+#define DOMAIN_F		4
+#define DOMAIN_S		5
+#define DOMAIN_ETM		6
+#define DOMAIN_IROM		7
+
+/* Total number of clocks. */
+#define NR_DOMAINS		(DOMAIN_IROM + 1)
+
+#endif /* _DT_BINDINGS_ARM_S3C64XX_POWER_DOMAINS_H */
-- 
1.9.0

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

* [PATCH v2 08/11] ARM: s3c64xx: dt: Enable SoC-level power management
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

This patch adds call to s3c64xx_pm_init() from init_machine() callback
of mach-s3c64xx-dt to enable SoC-level power management features, such
as power domain management and sleep support.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
index 2fddf38..45a4ddc 100644
--- a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
+++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
@@ -15,6 +15,7 @@
 #include <asm/system_misc.h>
 
 #include <plat/cpu.h>
+#include <plat/pm.h>
 #include <plat/watchdog-reset.h>
 
 #include <mach/map.h>
@@ -49,9 +50,15 @@ static void __init s3c64xx_dt_map_io(void)
 static void __init s3c64xx_dt_init_machine(void)
 {
 	samsung_wdt_reset_of_init();
+	s3c64xx_pm_init();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
+static void __init s3c64xx_dt_init_late(void)
+{
+	s3c64xx_pm_late_initcall();
+}
+
 static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd)
 {
 	if (mode != REBOOT_SOFT)
@@ -72,5 +79,6 @@ DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
 	.dt_compat	= s3c64xx_dt_compat,
 	.map_io		= s3c64xx_dt_map_io,
 	.init_machine	= s3c64xx_dt_init_machine,
+	.init_late	= s3c64xx_dt_init_late,
 	.restart        = s3c64xx_dt_restart,
 MACHINE_END
-- 
1.9.0


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

* [PATCH v2 08/11] ARM: s3c64xx: dt: Enable SoC-level power management
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

This patch adds call to s3c64xx_pm_init() from init_machine() callback
of mach-s3c64xx-dt to enable SoC-level power management features, such
as power domain management and sleep support.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
index 2fddf38..45a4ddc 100644
--- a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
+++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
@@ -15,6 +15,7 @@
 #include <asm/system_misc.h>
 
 #include <plat/cpu.h>
+#include <plat/pm.h>
 #include <plat/watchdog-reset.h>
 
 #include <mach/map.h>
@@ -49,9 +50,15 @@ static void __init s3c64xx_dt_map_io(void)
 static void __init s3c64xx_dt_init_machine(void)
 {
 	samsung_wdt_reset_of_init();
+	s3c64xx_pm_init();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
+static void __init s3c64xx_dt_init_late(void)
+{
+	s3c64xx_pm_late_initcall();
+}
+
 static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd)
 {
 	if (mode != REBOOT_SOFT)
@@ -72,5 +79,6 @@ DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
 	.dt_compat	= s3c64xx_dt_compat,
 	.map_io		= s3c64xx_dt_map_io,
 	.init_machine	= s3c64xx_dt_init_machine,
+	.init_late	= s3c64xx_dt_init_late,
 	.restart        = s3c64xx_dt_restart,
 MACHINE_END
-- 
1.9.0

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

* [PATCH v2 08/11] ARM: s3c64xx: dt: Enable SoC-level power management
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds call to s3c64xx_pm_init() from init_machine() callback
of mach-s3c64xx-dt to enable SoC-level power management features, such
as power domain management and sleep support.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
index 2fddf38..45a4ddc 100644
--- a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
+++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
@@ -15,6 +15,7 @@
 #include <asm/system_misc.h>
 
 #include <plat/cpu.h>
+#include <plat/pm.h>
 #include <plat/watchdog-reset.h>
 
 #include <mach/map.h>
@@ -49,9 +50,15 @@ static void __init s3c64xx_dt_map_io(void)
 static void __init s3c64xx_dt_init_machine(void)
 {
 	samsung_wdt_reset_of_init();
+	s3c64xx_pm_init();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
+static void __init s3c64xx_dt_init_late(void)
+{
+	s3c64xx_pm_late_initcall();
+}
+
 static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd)
 {
 	if (mode != REBOOT_SOFT)
@@ -72,5 +79,6 @@ DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
 	.dt_compat	= s3c64xx_dt_compat,
 	.map_io		= s3c64xx_dt_map_io,
 	.init_machine	= s3c64xx_dt_init_machine,
+	.init_late	= s3c64xx_dt_init_late,
 	.restart        = s3c64xx_dt_restart,
 MACHINE_END
-- 
1.9.0

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

* [PATCH v2 09/11] ARM: dts: s3c64xx: Add nodes for power domains
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

This patch adds device tree nodes for power domains available on S3C64xx
SoCs.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c6400.dtsi | 1 +
 arch/arm/boot/dts/s3c6410.dtsi | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/s3c6400.dtsi b/arch/arm/boot/dts/s3c6400.dtsi
index a7d1c8e..c1abdaf 100644
--- a/arch/arm/boot/dts/s3c6400.dtsi
+++ b/arch/arm/boot/dts/s3c6400.dtsi
@@ -37,5 +37,6 @@
 		compatible = "samsung,s3c6400-clock";
 		reg = <0x7e00f000 0x1000>;
 		#clock-cells = <1>;
+		#power-domain-cells = <1>;
 	};
 };
diff --git a/arch/arm/boot/dts/s3c6410.dtsi b/arch/arm/boot/dts/s3c6410.dtsi
index eb4226b..7e48c86 100644
--- a/arch/arm/boot/dts/s3c6410.dtsi
+++ b/arch/arm/boot/dts/s3c6410.dtsi
@@ -41,6 +41,7 @@
 		compatible = "samsung,s3c6410-clock";
 		reg = <0x7e00f000 0x1000>;
 		#clock-cells = <1>;
+		#power-domain-cells = <1>;
 	};
 
 	i2c1: i2c@7f00f000 {
-- 
1.9.0


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

* [PATCH v2 09/11] ARM: dts: s3c64xx: Add nodes for power domains
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Russell King,
	Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland, Pawel Moll,
	Rob Herring, Bartlomiej Zolnierkiewicz, Stephen Warren,
	Tomasz Figa, Mark Brown, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

This patch adds device tree nodes for power domains available on S3C64xx
SoCs.

Signed-off-by: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/s3c6400.dtsi | 1 +
 arch/arm/boot/dts/s3c6410.dtsi | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/s3c6400.dtsi b/arch/arm/boot/dts/s3c6400.dtsi
index a7d1c8e..c1abdaf 100644
--- a/arch/arm/boot/dts/s3c6400.dtsi
+++ b/arch/arm/boot/dts/s3c6400.dtsi
@@ -37,5 +37,6 @@
 		compatible = "samsung,s3c6400-clock";
 		reg = <0x7e00f000 0x1000>;
 		#clock-cells = <1>;
+		#power-domain-cells = <1>;
 	};
 };
diff --git a/arch/arm/boot/dts/s3c6410.dtsi b/arch/arm/boot/dts/s3c6410.dtsi
index eb4226b..7e48c86 100644
--- a/arch/arm/boot/dts/s3c6410.dtsi
+++ b/arch/arm/boot/dts/s3c6410.dtsi
@@ -41,6 +41,7 @@
 		compatible = "samsung,s3c6410-clock";
 		reg = <0x7e00f000 0x1000>;
 		#clock-cells = <1>;
+		#power-domain-cells = <1>;
 	};
 
 	i2c1: i2c@7f00f000 {
-- 
1.9.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 09/11] ARM: dts: s3c64xx: Add nodes for power domains
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds device tree nodes for power domains available on S3C64xx
SoCs.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c6400.dtsi | 1 +
 arch/arm/boot/dts/s3c6410.dtsi | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/s3c6400.dtsi b/arch/arm/boot/dts/s3c6400.dtsi
index a7d1c8e..c1abdaf 100644
--- a/arch/arm/boot/dts/s3c6400.dtsi
+++ b/arch/arm/boot/dts/s3c6400.dtsi
@@ -37,5 +37,6 @@
 		compatible = "samsung,s3c6400-clock";
 		reg = <0x7e00f000 0x1000>;
 		#clock-cells = <1>;
+		#power-domain-cells = <1>;
 	};
 };
diff --git a/arch/arm/boot/dts/s3c6410.dtsi b/arch/arm/boot/dts/s3c6410.dtsi
index eb4226b..7e48c86 100644
--- a/arch/arm/boot/dts/s3c6410.dtsi
+++ b/arch/arm/boot/dts/s3c6410.dtsi
@@ -41,6 +41,7 @@
 		compatible = "samsung,s3c6410-clock";
 		reg = <0x7e00f000 0x1000>;
 		#clock-cells = <1>;
+		#power-domain-cells = <1>;
 	};
 
 	i2c1: i2c at 7f00f000 {
-- 
1.9.0

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

* [PATCH v2 10/11] ARM: dts: s3c64xx: Add node for display controller
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

This patch adds device tree node for the display controller present on
S3C64xx SoCs.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c64xx.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
index 4e3be4d..6fe1042 100644
--- a/arch/arm/boot/dts/s3c64xx.dtsi
+++ b/arch/arm/boot/dts/s3c64xx.dtsi
@@ -18,6 +18,7 @@
 
 #include "skeleton.dtsi"
 #include <dt-bindings/clock/samsung,s3c64xx-clock.h>
+#include <dt-bindings/arm/s3c64xx-power-domains.h>
 
 / {
 	aliases {
@@ -56,6 +57,18 @@
 			#interrupt-cells = <1>;
 		};
 
+		fimd: display@77100000 {
+			compatible = "samsung,s3c6400-fimd";
+			reg = <0x77100000 0x1000>;
+			interrupt-parent = <&vic0>;
+			interrupts = <29>, <30>, <31>;
+			interrupt-names = "fifo", "vsync", "lcd_sys";
+			clocks = <&clocks HCLK_LCD>, <&clocks SCLK_LCD>;
+			clock-names = "fimd", "sclk_fimd";
+			power-domain = <&clocks DOMAIN_F>;
+			status = "disabled";
+		};
+
 		sdhci0: sdhci@7c200000 {
 			compatible = "samsung,s3c6410-sdhci";
 			reg = <0x7c200000 0x100>;
-- 
1.9.0


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

* [PATCH v2 10/11] ARM: dts: s3c64xx: Add node for display controller
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

This patch adds device tree node for the display controller present on
S3C64xx SoCs.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c64xx.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
index 4e3be4d..6fe1042 100644
--- a/arch/arm/boot/dts/s3c64xx.dtsi
+++ b/arch/arm/boot/dts/s3c64xx.dtsi
@@ -18,6 +18,7 @@
 
 #include "skeleton.dtsi"
 #include <dt-bindings/clock/samsung,s3c64xx-clock.h>
+#include <dt-bindings/arm/s3c64xx-power-domains.h>
 
 / {
 	aliases {
@@ -56,6 +57,18 @@
 			#interrupt-cells = <1>;
 		};
 
+		fimd: display@77100000 {
+			compatible = "samsung,s3c6400-fimd";
+			reg = <0x77100000 0x1000>;
+			interrupt-parent = <&vic0>;
+			interrupts = <29>, <30>, <31>;
+			interrupt-names = "fifo", "vsync", "lcd_sys";
+			clocks = <&clocks HCLK_LCD>, <&clocks SCLK_LCD>;
+			clock-names = "fimd", "sclk_fimd";
+			power-domain = <&clocks DOMAIN_F>;
+			status = "disabled";
+		};
+
 		sdhci0: sdhci@7c200000 {
 			compatible = "samsung,s3c6410-sdhci";
 			reg = <0x7c200000 0x100>;
-- 
1.9.0


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

* [PATCH v2 10/11] ARM: dts: s3c64xx: Add node for display controller
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds device tree node for the display controller present on
S3C64xx SoCs.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c64xx.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
index 4e3be4d..6fe1042 100644
--- a/arch/arm/boot/dts/s3c64xx.dtsi
+++ b/arch/arm/boot/dts/s3c64xx.dtsi
@@ -18,6 +18,7 @@
 
 #include "skeleton.dtsi"
 #include <dt-bindings/clock/samsung,s3c64xx-clock.h>
+#include <dt-bindings/arm/s3c64xx-power-domains.h>
 
 / {
 	aliases {
@@ -56,6 +57,18 @@
 			#interrupt-cells = <1>;
 		};
 
+		fimd: display at 77100000 {
+			compatible = "samsung,s3c6400-fimd";
+			reg = <0x77100000 0x1000>;
+			interrupt-parent = <&vic0>;
+			interrupts = <29>, <30>, <31>;
+			interrupt-names = "fifo", "vsync", "lcd_sys";
+			clocks = <&clocks HCLK_LCD>, <&clocks SCLK_LCD>;
+			clock-names = "fimd", "sclk_fimd";
+			power-domain = <&clocks DOMAIN_F>;
+			status = "disabled";
+		};
+
 		sdhci0: sdhci at 7c200000 {
 			compatible = "samsung,s3c6410-sdhci";
 			reg = <0x7c200000 0x100>;
-- 
1.9.0

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

* [PATCH v2 11/11] ARM: dts: s3c6410-mini6410: Add support for LCD screen
  2014-03-03 16:02 ` Tomasz Figa
  (?)
@ 2014-03-03 16:02   ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski, Tomasz Figa

This patch adds necessary device tree nodes and properties to enable LCD
screen on mini6410 board.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c6410-mini6410.dts | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
index 57e00f9..97f6353 100644
--- a/arch/arm/boot/dts/s3c6410-mini6410.dts
+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts
@@ -167,6 +167,33 @@
 	};
 };
 
+&fimd {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd_data24>, <&lcd_power>;
+
+	display-timings {
+		native-mode = <&timing0>;
+
+		timing0: timing@0 {
+			/* 480x272@60Hz */
+			clock-frequency = <10000000>;
+			hactive = <480>;
+			vactive = <272>;
+			hfront-porch = <4>;
+			hback-porch = <45>;
+			hsync-len = <40>;
+			vback-porch = <3>;
+			vfront-porch = <2>;
+			vsync-len = <6>;
+			vsync-active = <1>;
+			hsync-active = <1>;
+			de-active = <1>;
+			pixelclk-active = <0>;
+		};
+	};
+};
+
 &sdhci0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
@@ -213,6 +240,12 @@
 				"gpn-4", "gpn-5", "gpl-11", "gpl-12";
 		samsung,pin-pud = <PIN_PULL_NONE>;
 	};
+
+	lcd_power: lcd-power {
+		samsung,pins = "gpe-0";
+		samsung,pin-function = <0>;
+		samsung,pin-pud = <PIN_PULL_UP>;
+	};
 };
 
 &i2c0 {
-- 
1.9.0


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

* [PATCH v2 11/11] ARM: dts: s3c6410-mini6410: Add support for LCD screen
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-pm
  Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, devicetree,
	Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Russell King, Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland,
	Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Ulf Hansson, Marek Szyprowski

This patch adds necessary device tree nodes and properties to enable LCD
screen on mini6410 board.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c6410-mini6410.dts | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
index 57e00f9..97f6353 100644
--- a/arch/arm/boot/dts/s3c6410-mini6410.dts
+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts
@@ -167,6 +167,33 @@
 	};
 };
 
+&fimd {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd_data24>, <&lcd_power>;
+
+	display-timings {
+		native-mode = <&timing0>;
+
+		timing0: timing@0 {
+			/* 480x272@60Hz */
+			clock-frequency = <10000000>;
+			hactive = <480>;
+			vactive = <272>;
+			hfront-porch = <4>;
+			hback-porch = <45>;
+			hsync-len = <40>;
+			vback-porch = <3>;
+			vfront-porch = <2>;
+			vsync-len = <6>;
+			vsync-active = <1>;
+			hsync-active = <1>;
+			de-active = <1>;
+			pixelclk-active = <0>;
+		};
+	};
+};
+
 &sdhci0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
@@ -213,6 +240,12 @@
 				"gpn-4", "gpn-5", "gpl-11", "gpl-12";
 		samsung,pin-pud = <PIN_PULL_NONE>;
 	};
+
+	lcd_power: lcd-power {
+		samsung,pins = "gpe-0";
+		samsung,pin-function = <0>;
+		samsung,pin-pud = <PIN_PULL_UP>;
+	};
 };
 
 &i2c0 {
-- 
1.9.0

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

* [PATCH v2 11/11] ARM: dts: s3c6410-mini6410: Add support for LCD screen
@ 2014-03-03 16:02   ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-03 16:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds necessary device tree nodes and properties to enable LCD
screen on mini6410 board.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/boot/dts/s3c6410-mini6410.dts | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
index 57e00f9..97f6353 100644
--- a/arch/arm/boot/dts/s3c6410-mini6410.dts
+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts
@@ -167,6 +167,33 @@
 	};
 };
 
+&fimd {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd_data24>, <&lcd_power>;
+
+	display-timings {
+		native-mode = <&timing0>;
+
+		timing0: timing at 0 {
+			/* 480x272 at 60Hz */
+			clock-frequency = <10000000>;
+			hactive = <480>;
+			vactive = <272>;
+			hfront-porch = <4>;
+			hback-porch = <45>;
+			hsync-len = <40>;
+			vback-porch = <3>;
+			vfront-porch = <2>;
+			vsync-len = <6>;
+			vsync-active = <1>;
+			hsync-active = <1>;
+			de-active = <1>;
+			pixelclk-active = <0>;
+		};
+	};
+};
+
 &sdhci0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
@@ -213,6 +240,12 @@
 				"gpn-4", "gpn-5", "gpl-11", "gpl-12";
 		samsung,pin-pud = <PIN_PULL_NONE>;
 	};
+
+	lcd_power: lcd-power {
+		samsung,pins = "gpe-0";
+		samsung,pin-function = <0>;
+		samsung,pin-pud = <PIN_PULL_UP>;
+	};
 };
 
 &i2c0 {
-- 
1.9.0

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-04 18:23     ` Stephen Boyd
  -1 siblings, 0 replies; 103+ messages in thread
From: Stephen Boyd @ 2014-03-04 18:23 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

On 03/03, Tomasz Figa wrote:
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>  
>  #include <linux/init.h>
>  #include <linux/kernel.h>
>  #include <linux/io.h>
> +#include <linux/platform_device.h>

Is this still needed?

>  #include <linux/pm_runtime.h>
>  #include <linux/pm_domain.h>
>  #include <linux/pm_qos.h>
[...]
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.

This looks outdated.

> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-04 18:23     ` Stephen Boyd
  0 siblings, 0 replies; 103+ messages in thread
From: Stephen Boyd @ 2014-03-04 18:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/03, Tomasz Figa wrote:
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>  
>  #include <linux/init.h>
>  #include <linux/kernel.h>
>  #include <linux/io.h>
> +#include <linux/platform_device.h>

Is this still needed?

>  #include <linux/pm_runtime.h>
>  #include <linux/pm_domain.h>
>  #include <linux/pm_qos.h>
[...]
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.

This looks outdated.

> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-04 18:29     ` Stephen Boyd
  -1 siblings, 0 replies; 103+ messages in thread
From: Stephen Boyd @ 2014-03-04 18:29 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

On 03/03, Tomasz Figa wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
> 
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-04 18:29     ` Stephen Boyd
  0 siblings, 0 replies; 103+ messages in thread
From: Stephen Boyd @ 2014-03-04 18:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/03, Tomasz Figa wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
> 
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

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

* Re: [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
  2014-03-03 16:02   ` Tomasz Figa
  (?)
@ 2014-03-04 19:17     ` Philipp Zabel
  -1 siblings, 0 replies; 103+ messages in thread
From: Philipp Zabel @ 2014-03-04 19:17 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, LKML, Mark Brown,
	Kumar Gala

Hi Tomasz,

On Mon, Mar 3, 2014 at 5:02 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
>
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

patches 01 and 02
Reviewed-by: Philipp Zabel <philipp.zabel@gmail.com>
Tested-by: Philipp Zabel <philipp.zabel@gmail.com>
on i.MX6 GK802.

regards
Philipp

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

* Re: [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-04 19:17     ` Philipp Zabel
  0 siblings, 0 replies; 103+ messages in thread
From: Philipp Zabel @ 2014-03-04 19:17 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, LKML, Mark Brown

Hi Tomasz,

On Mon, Mar 3, 2014 at 5:02 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
>
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

patches 01 and 02
Reviewed-by: Philipp Zabel <philipp.zabel@gmail.com>
Tested-by: Philipp Zabel <philipp.zabel@gmail.com>
on i.MX6 GK802.

regards
Philipp

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

* [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-04 19:17     ` Philipp Zabel
  0 siblings, 0 replies; 103+ messages in thread
From: Philipp Zabel @ 2014-03-04 19:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tomasz,

On Mon, Mar 3, 2014 at 5:02 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
>
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

patches 01 and 02
Reviewed-by: Philipp Zabel <philipp.zabel@gmail.com>
Tested-by: Philipp Zabel <philipp.zabel@gmail.com>
on i.MX6 GK802.

regards
Philipp

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05  4:24     ` Mark Brown
  -1 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:24 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 727 bytes --]

On Mon, Mar 03, 2014 at 05:02:06PM +0100, Tomasz Figa wrote:
> 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.

Reviwed-by: Mark Brown <broonie@linaro.org>

(mainly the binding)

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05  4:24     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:06PM +0100, Tomasz Figa wrote:
> 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.

Reviwed-by: Mark Brown <broonie@linaro.org>

(mainly the binding)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/15f11668/attachment.sig>

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

* Re: [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05  4:26     ` Mark Brown
  -1 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:26 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 641 bytes --]

On Mon, Mar 03, 2014 at 05:02:07PM +0100, Tomasz Figa wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.

Reviewed-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-05  4:26     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:07PM +0100, Tomasz Figa wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.

Reviewed-by: Mark Brown <broonie@linaro.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/1b9eb003/attachment.sig>

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

* Re: [PATCH v2 06/11] ARM: s3c64xx: pm: Add pwr_stat bit for domain G
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05  4:28     ` Mark Brown
  -1 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:28 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 311 bytes --]

On Mon, Mar 03, 2014 at 05:02:11PM +0100, Tomasz Figa wrote:
> There is a status bit for domain G present in BLK_PWR_STAT register, but
> it is currently not specified in the driver.
> 
> This patch adds the status bit of domain G to structure describing it.

Reviwed-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 06/11] ARM: s3c64xx: pm: Add pwr_stat bit for domain G
@ 2014-03-05  4:28     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:11PM +0100, Tomasz Figa wrote:
> There is a status bit for domain G present in BLK_PWR_STAT register, but
> it is currently not specified in the driver.
> 
> This patch adds the status bit of domain G to structure describing it.

Reviwed-by: Mark Brown <broonie@linaro.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/1fd297b5/attachment.sig>

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

* Re: [PATCH v2 05/11] ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05  4:28     ` Mark Brown
  -1 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:28 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 310 bytes --]

On Mon, Mar 03, 2014 at 05:02:10PM +0100, Tomasz Figa wrote:
> This patch adds always_on field to s3c64xx_pm_domain struct to allow
> handling registration of all domains in the same way, without the need
> to have separate arrays for normal and always on domains.

Reviwed-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 05/11] ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct
@ 2014-03-05  4:28     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:10PM +0100, Tomasz Figa wrote:
> This patch adds always_on field to s3c64xx_pm_domain struct to allow
> handling registration of all domains in the same way, without the need
> to have separate arrays for normal and always on domains.

Reviwed-by: Mark Brown <broonie@linaro.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/67347281/attachment-0001.sig>

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

* Re: [PATCH v2 04/11] ARM: s3c64xx: pm: Use name field of generic_pm_domain
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05  4:28     ` Mark Brown
  -1 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:28 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 248 bytes --]

On Mon, Mar 03, 2014 at 05:02:09PM +0100, Tomasz Figa wrote:
> This patch removes name field from private s3c64xx_pm_domain struct and
> moves domain name to dedicated field of generic_pm_domain struct.

Reviwed-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 04/11] ARM: s3c64xx: pm: Use name field of generic_pm_domain
@ 2014-03-05  4:28     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:09PM +0100, Tomasz Figa wrote:
> This patch removes name field from private s3c64xx_pm_domain struct and
> moves domain name to dedicated field of generic_pm_domain struct.

Reviwed-by: Mark Brown <broonie@linaro.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/a7133a01/attachment.sig>

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

* Re: [PATCH v2 07/11] ARM: s3c64xx: pm: Add device tree based power domain instantiation
@ 2014-03-05  4:29     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:29 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 227 bytes --]

On Mon, Mar 03, 2014 at 05:02:12PM +0100, Tomasz Figa wrote:
> This patch adds support for registering power domains of S3C64xx SoCs
> and binding devices to them using device tree.

Reviwed-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 07/11] ARM: s3c64xx: pm: Add device tree based power domain instantiation
@ 2014-03-05  4:29     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:29 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Russell King,
	Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland, Pawel Moll,
	Rob Herring, Bartlomiej Zolnierkiewicz, Stephen Warren,
	Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi, Ulf Hansson,
	Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 256 bytes --]

On Mon, Mar 03, 2014 at 05:02:12PM +0100, Tomasz Figa wrote:
> This patch adds support for registering power domains of S3C64xx SoCs
> and binding devices to them using device tree.

Reviwed-by: Mark Brown <broonie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 07/11] ARM: s3c64xx: pm: Add device tree based power domain instantiation
@ 2014-03-05  4:29     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:12PM +0100, Tomasz Figa wrote:
> This patch adds support for registering power domains of S3C64xx SoCs
> and binding devices to them using device tree.

Reviwed-by: Mark Brown <broonie@linaro.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/7f5233b0/attachment.sig>

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

* Re: [PATCH v2 08/11] ARM: s3c64xx: dt: Enable SoC-level power management
@ 2014-03-05  4:30     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:30 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 301 bytes --]

On Mon, Mar 03, 2014 at 05:02:13PM +0100, Tomasz Figa wrote:
> This patch adds call to s3c64xx_pm_init() from init_machine() callback
> of mach-s3c64xx-dt to enable SoC-level power management features, such
> as power domain management and sleep support.

Reviewed-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v2 08/11] ARM: s3c64xx: dt: Enable SoC-level power management
@ 2014-03-05  4:30     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:30 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Russell King,
	Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland, Pawel Moll,
	Rob Herring, Bartlomiej Zolnierkiewicz, Stephen Warren,
	Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi, Ulf Hansson,
	Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 330 bytes --]

On Mon, Mar 03, 2014 at 05:02:13PM +0100, Tomasz Figa wrote:
> This patch adds call to s3c64xx_pm_init() from init_machine() callback
> of mach-s3c64xx-dt to enable SoC-level power management features, such
> as power domain management and sleep support.

Reviewed-by: Mark Brown <broonie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 08/11] ARM: s3c64xx: dt: Enable SoC-level power management
@ 2014-03-05  4:30     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:13PM +0100, Tomasz Figa wrote:
> This patch adds call to s3c64xx_pm_init() from init_machine() callback
> of mach-s3c64xx-dt to enable SoC-level power management features, such
> as power domain management and sleep support.

Reviewed-by: Mark Brown <broonie@linaro.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/7b530bb5/attachment.sig>

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

* Re: [PATCH v2 09/11] ARM: dts: s3c64xx: Add nodes for power domains
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05  4:31     ` Mark Brown
  -1 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:31 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 189 bytes --]

On Mon, Mar 03, 2014 at 05:02:14PM +0100, Tomasz Figa wrote:
> This patch adds device tree nodes for power domains available on S3C64xx
> SoCs.

Reviwed-by: Mark Brown <broonie@linaro.org>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 09/11] ARM: dts: s3c64xx: Add nodes for power domains
@ 2014-03-05  4:31     ` Mark Brown
  0 siblings, 0 replies; 103+ messages in thread
From: Mark Brown @ 2014-03-05  4:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 05:02:14PM +0100, Tomasz Figa wrote:
> This patch adds device tree nodes for power domains available on S3C64xx
> SoCs.

Reviwed-by: Mark Brown <broonie@linaro.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/7217ff08/attachment.sig>

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05  6:41     ` Rob Herring
  -1 siblings, 0 replies; 103+ messages in thread
From: Rob Herring @ 2014-03-05  6:41 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King, Ian Campbell,
	Lorenzo Pieralisi, devicetree, Pawel Moll, linux-pm, Rob Herring,
	linux-arm-kernel, Greg Kroah-Hartman, Rafael J. Wysocki

On Mon, Mar 3, 2014 at 10:02 AM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>

Acked-by: Rob Herring <robh@kernel.org>

> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);
> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05  6:41     ` Rob Herring
  0 siblings, 0 replies; 103+ messages in thread
From: Rob Herring @ 2014-03-05  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 3, 2014 at 10:02 AM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>

Acked-by: Rob Herring <robh@kernel.org>

> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);
> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
  (?)
@ 2014-03-05  7:19     ` Ulf Hansson
  -1 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-03-05  7:19 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Marek Szyprowski

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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

Do we need a new config for this? Can't we just use CONFIG_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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);

So this will reflect the device as being inactive, which I think is
the wrong approach.

Usually we should expect drivers that's being probed successfully to
leave their devices in active state, right?

Kind regards
Ulf Hansson

> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05  7:19     ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-03-05  7:19 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd, Loren

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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

Do we need a new config for this? Can't we just use CONFIG_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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);

So this will reflect the device as being inactive, which I think is
the wrong approach.

Usually we should expect drivers that's being probed successfully to
leave their devices in active state, right?

Kind regards
Ulf Hansson

> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05  7:19     ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-03-05  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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

Do we need a new config for this? Can't we just use CONFIG_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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);

So this will reflect the device as being inactive, which I think is
the wrong approach.

Usually we should expect drivers that's being probed successfully to
leave their devices in active state, right?

Kind regards
Ulf Hansson

> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* Re: [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
  2014-03-03 16:02   ` Tomasz Figa
  (?)
@ 2014-03-05  7:22     ` Ulf Hansson
  -1 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-03-05  7:22 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Marek Szyprowski

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
>
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

This definitely makes sense to me!

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

> ---
>  drivers/base/dd.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 0605176..78e5b36 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -23,6 +23,7 @@
>  #include <linux/kthread.h>
>  #include <linux/wait.h>
>  #include <linux/async.h>
> +#include <linux/pm_domain.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/pinctrl/devinfo.h>
>
> @@ -273,6 +274,11 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>
>         dev->driver = drv;
>
> +       /* If using genpd, bind power domain now before probing */
> +       ret = genpd_bind_domain(dev);
> +       if (ret)
> +               goto probe_failed;
> +
>         /* If using pinctrl, bind pins now before probing */
>         ret = pinctrl_bind_pins(dev);
>         if (ret)
> @@ -303,6 +309,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>  probe_failed:
>         devres_release_all(dev);
>         driver_sysfs_remove(dev);
> +       genpd_unbind_domain(dev);
>         dev->driver = NULL;
>         dev_set_drvdata(dev, NULL);
>
> @@ -513,7 +520,7 @@ static void __device_release_driver(struct device *dev)
>                         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
>                                                      BUS_NOTIFY_UNBOUND_DRIVER,
>                                                      dev);
> -
> +               genpd_unbind_domain(dev);
>         }
>  }
>
> --
> 1.9.0
>

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

* Re: [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-05  7:22     ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-03-05  7:22 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd, Loren

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
>
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

This definitely makes sense to me!

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

> ---
>  drivers/base/dd.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 0605176..78e5b36 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -23,6 +23,7 @@
>  #include <linux/kthread.h>
>  #include <linux/wait.h>
>  #include <linux/async.h>
> +#include <linux/pm_domain.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/pinctrl/devinfo.h>
>
> @@ -273,6 +274,11 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>
>         dev->driver = drv;
>
> +       /* If using genpd, bind power domain now before probing */
> +       ret = genpd_bind_domain(dev);
> +       if (ret)
> +               goto probe_failed;
> +
>         /* If using pinctrl, bind pins now before probing */
>         ret = pinctrl_bind_pins(dev);
>         if (ret)
> @@ -303,6 +309,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>  probe_failed:
>         devres_release_all(dev);
>         driver_sysfs_remove(dev);
> +       genpd_unbind_domain(dev);
>         dev->driver = NULL;
>         dev_set_drvdata(dev, NULL);
>
> @@ -513,7 +520,7 @@ static void __device_release_driver(struct device *dev)
>                         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
>                                                      BUS_NOTIFY_UNBOUND_DRIVER,
>                                                      dev);
> -
> +               genpd_unbind_domain(dev);
>         }
>  }
>
> --
> 1.9.0
>

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

* [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove
@ 2014-03-05  7:22     ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-03-05  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> On a number of platforms, devices are part of controllable power
> domains, which need to be enabled before such devices can be accessed
> and may be powered down when the device is idle to save some power.
> This means that on systems that support power domain control using
> generic power domains subsystem, it is necessary to add device to its
> power domain before binding a driver to it and remove it from its power
> domain after its driver is unbound to make sure that an unused device
> does not affect power domain state.
>
> Since this is not limited to particular busses and specific
> archs/platforms, it is more convenient to do the above directly in
> driver core, just as done with pinctrl default configuration. This patch
> adds necessary code to really_probe() and __device_release_driver() to
> achieve this and maintain consistent stack-like ordering of operations
> happening when binding and unbinding a driver.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

This definitely makes sense to me!

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

> ---
>  drivers/base/dd.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 0605176..78e5b36 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -23,6 +23,7 @@
>  #include <linux/kthread.h>
>  #include <linux/wait.h>
>  #include <linux/async.h>
> +#include <linux/pm_domain.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/pinctrl/devinfo.h>
>
> @@ -273,6 +274,11 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>
>         dev->driver = drv;
>
> +       /* If using genpd, bind power domain now before probing */
> +       ret = genpd_bind_domain(dev);
> +       if (ret)
> +               goto probe_failed;
> +
>         /* If using pinctrl, bind pins now before probing */
>         ret = pinctrl_bind_pins(dev);
>         if (ret)
> @@ -303,6 +309,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>  probe_failed:
>         devres_release_all(dev);
>         driver_sysfs_remove(dev);
> +       genpd_unbind_domain(dev);
>         dev->driver = NULL;
>         dev_set_drvdata(dev, NULL);
>
> @@ -513,7 +520,7 @@ static void __device_release_driver(struct device *dev)
>                         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
>                                                      BUS_NOTIFY_UNBOUND_DRIVER,
>                                                      dev);
> -
> +               genpd_unbind_domain(dev);
>         }
>  }
>
> --
> 1.9.0
>

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-05  7:19     ` Ulf Hansson
  (?)
@ 2014-03-05 11:47       ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 11:47 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Marek Szyprowski

Hi Ulf,

On 05.03.2014 08:19, Ulf Hansson wrote:
>> @@ -2177,3 +2181,297 @@ 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
>
> Do we need a new config for this? Can't we just use CONFIG_OF?
>

I guess we could, but initially it would have to be CONFIG_OF && 
!CONFIG_ARCH_EXYNOS until patch 03/11 converts Exynos to use the common 
code.

>> +       if (ret < 0) {
>> +               dev_err(dev, "failed to add to power domain %s: %d",
>> +                       pd->name, ret);
>> +               return ret;
>> +       }
>> +
>> +       pm_genpd_dev_need_restore(dev, true);
>
> So this will reflect the device as being inactive, which I think is
> the wrong approach.
>
> Usually we should expect drivers that's being probed successfully to
> leave their devices in active state, right?

It depends on domain power state, but actually it seems to be already 
handled in __pm_genpd_add_device(), so this line might be not needed indeed.

Strangely enough, it seemed to be needed on Exynos for correct 
operation, but maybe in the meantime some fixes in genpd code showed up. 
This will need some extra testing.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05 11:47       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 11:47 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd, Loren

Hi Ulf,

On 05.03.2014 08:19, Ulf Hansson wrote:
>> @@ -2177,3 +2181,297 @@ 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
>
> Do we need a new config for this? Can't we just use CONFIG_OF?
>

I guess we could, but initially it would have to be CONFIG_OF && 
!CONFIG_ARCH_EXYNOS until patch 03/11 converts Exynos to use the common 
code.

>> +       if (ret < 0) {
>> +               dev_err(dev, "failed to add to power domain %s: %d",
>> +                       pd->name, ret);
>> +               return ret;
>> +       }
>> +
>> +       pm_genpd_dev_need_restore(dev, true);
>
> So this will reflect the device as being inactive, which I think is
> the wrong approach.
>
> Usually we should expect drivers that's being probed successfully to
> leave their devices in active state, right?

It depends on domain power state, but actually it seems to be already 
handled in __pm_genpd_add_device(), so this line might be not needed indeed.

Strangely enough, it seemed to be needed on Exynos for correct 
operation, but maybe in the meantime some fixes in genpd code showed up. 
This will need some extra testing.

Best regards,
Tomasz

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05 11:47       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 11:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ulf,

On 05.03.2014 08:19, Ulf Hansson wrote:
>> @@ -2177,3 +2181,297 @@ 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
>
> Do we need a new config for this? Can't we just use CONFIG_OF?
>

I guess we could, but initially it would have to be CONFIG_OF && 
!CONFIG_ARCH_EXYNOS until patch 03/11 converts Exynos to use the common 
code.

>> +       if (ret < 0) {
>> +               dev_err(dev, "failed to add to power domain %s: %d",
>> +                       pd->name, ret);
>> +               return ret;
>> +       }
>> +
>> +       pm_genpd_dev_need_restore(dev, true);
>
> So this will reflect the device as being inactive, which I think is
> the wrong approach.
>
> Usually we should expect drivers that's being probed successfully to
> leave their devices in active state, right?

It depends on domain power state, but actually it seems to be already 
handled in __pm_genpd_add_device(), so this line might be not needed indeed.

Strangely enough, it seemed to be needed on Exynos for correct 
operation, but maybe in the meantime some fixes in genpd code showed up. 
This will need some extra testing.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-04 18:23     ` Stephen Boyd
@ 2014-03-05 11:53       ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 11:53 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

On 04.03.2014 19:23, Stephen Boyd wrote:
> On 03/03, Tomasz Figa wrote:
>> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
>> index dc127e5..006b455 100644
>> --- a/drivers/base/power/domain.c
>> +++ b/drivers/base/power/domain.c
>> @@ -3,12 +3,16 @@
>>    *
>>    * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>>    *
>> + * Support for Device Tree based power domain providers:
>> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
>> + *
>>    * This file is released under the GPLv2.
>>    */
>>
>>   #include <linux/init.h>
>>   #include <linux/kernel.h>
>>   #include <linux/io.h>
>> +#include <linux/platform_device.h>
>
> Is this still needed?
>

Probably not.

>>   #include <linux/pm_runtime.h>
>>   #include <linux/pm_domain.h>
>>   #include <linux/pm_qos.h>
> [...]
>> +
>> +/*
>> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
>> + *
>> + * The code below registers a notifier for platform bus devices'
>> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
>> + * domains by looking them up using Device Tree.
>> + *
>> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
>> + * domain, since it no longer supports runtime PM without any driver bound
>> + * to it.
>
> This looks outdated.
>

Oops, missed this one. Thanks for pointing out.

Best regards,
Tomasz

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05 11:53       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 11:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 04.03.2014 19:23, Stephen Boyd wrote:
> On 03/03, Tomasz Figa wrote:
>> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
>> index dc127e5..006b455 100644
>> --- a/drivers/base/power/domain.c
>> +++ b/drivers/base/power/domain.c
>> @@ -3,12 +3,16 @@
>>    *
>>    * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>>    *
>> + * Support for Device Tree based power domain providers:
>> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
>> + *
>>    * This file is released under the GPLv2.
>>    */
>>
>>   #include <linux/init.h>
>>   #include <linux/kernel.h>
>>   #include <linux/io.h>
>> +#include <linux/platform_device.h>
>
> Is this still needed?
>

Probably not.

>>   #include <linux/pm_runtime.h>
>>   #include <linux/pm_domain.h>
>>   #include <linux/pm_qos.h>
> [...]
>> +
>> +/*
>> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
>> + *
>> + * The code below registers a notifier for platform bus devices'
>> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
>> + * domains by looking them up using Device Tree.
>> + *
>> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
>> + * domain, since it no longer supports runtime PM without any driver bound
>> + * to it.
>
> This looks outdated.
>

Oops, missed this one. Thanks for pointing out.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-05 11:47       ` Tomasz Figa
  (?)
@ 2014-03-05 12:44         ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 12:44 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Marek Szyprowski

On 05.03.2014 12:47, Tomasz Figa wrote:
> Hi Ulf,
>
> On 05.03.2014 08:19, Ulf Hansson wrote:
>>> @@ -2177,3 +2181,297 @@ 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
>>
>> Do we need a new config for this? Can't we just use CONFIG_OF?
>>
>
> I guess we could, but initially it would have to be CONFIG_OF &&
> !CONFIG_ARCH_EXYNOS until patch 03/11 converts Exynos to use the common
> code.
>
>>> +       if (ret < 0) {
>>> +               dev_err(dev, "failed to add to power domain %s: %d",
>>> +                       pd->name, ret);
>>> +               return ret;
>>> +       }
>>> +
>>> +       pm_genpd_dev_need_restore(dev, true);
>>
>> So this will reflect the device as being inactive, which I think is
>> the wrong approach.
>>
>> Usually we should expect drivers that's being probed successfully to
>> leave their devices in active state, right?
>
> It depends on domain power state, but actually it seems to be already
> handled in __pm_genpd_add_device(), so this line might be not needed
> indeed.
>
> Strangely enough, it seemed to be needed on Exynos for correct
> operation, but maybe in the meantime some fixes in genpd code showed up.
> This will need some extra testing.

Hmm, after removing this line, power domains no longer work correctly on 
Exynos (thanks Marek for testing). Unfortunately I'm on a sick leave 
right now and I won't be able to debug this issue on Exynos for some 
time, but I'll see if I can reproduce it on s3c64xx board I have here at 
home.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05 12:44         ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 12:44 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd, Loren

On 05.03.2014 12:47, Tomasz Figa wrote:
> Hi Ulf,
>
> On 05.03.2014 08:19, Ulf Hansson wrote:
>>> @@ -2177,3 +2181,297 @@ 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
>>
>> Do we need a new config for this? Can't we just use CONFIG_OF?
>>
>
> I guess we could, but initially it would have to be CONFIG_OF &&
> !CONFIG_ARCH_EXYNOS until patch 03/11 converts Exynos to use the common
> code.
>
>>> +       if (ret < 0) {
>>> +               dev_err(dev, "failed to add to power domain %s: %d",
>>> +                       pd->name, ret);
>>> +               return ret;
>>> +       }
>>> +
>>> +       pm_genpd_dev_need_restore(dev, true);
>>
>> So this will reflect the device as being inactive, which I think is
>> the wrong approach.
>>
>> Usually we should expect drivers that's being probed successfully to
>> leave their devices in active state, right?
>
> It depends on domain power state, but actually it seems to be already
> handled in __pm_genpd_add_device(), so this line might be not needed
> indeed.
>
> Strangely enough, it seemed to be needed on Exynos for correct
> operation, but maybe in the meantime some fixes in genpd code showed up.
> This will need some extra testing.

Hmm, after removing this line, power domains no longer work correctly on 
Exynos (thanks Marek for testing). Unfortunately I'm on a sick leave 
right now and I won't be able to debug this issue on Exynos for some 
time, but I'll see if I can reproduce it on s3c64xx board I have here at 
home.

Best regards,
Tomasz

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05 12:44         ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 12:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 05.03.2014 12:47, Tomasz Figa wrote:
> Hi Ulf,
>
> On 05.03.2014 08:19, Ulf Hansson wrote:
>>> @@ -2177,3 +2181,297 @@ 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
>>
>> Do we need a new config for this? Can't we just use CONFIG_OF?
>>
>
> I guess we could, but initially it would have to be CONFIG_OF &&
> !CONFIG_ARCH_EXYNOS until patch 03/11 converts Exynos to use the common
> code.
>
>>> +       if (ret < 0) {
>>> +               dev_err(dev, "failed to add to power domain %s: %d",
>>> +                       pd->name, ret);
>>> +               return ret;
>>> +       }
>>> +
>>> +       pm_genpd_dev_need_restore(dev, true);
>>
>> So this will reflect the device as being inactive, which I think is
>> the wrong approach.
>>
>> Usually we should expect drivers that's being probed successfully to
>> leave their devices in active state, right?
>
> It depends on domain power state, but actually it seems to be already
> handled in __pm_genpd_add_device(), so this line might be not needed
> indeed.
>
> Strangely enough, it seemed to be needed on Exynos for correct
> operation, but maybe in the meantime some fixes in genpd code showed up.
> This will need some extra testing.

Hmm, after removing this line, power domains no longer work correctly on 
Exynos (thanks Marek for testing). Unfortunately I'm on a sick leave 
right now and I won't be able to debug this issue on Exynos for some 
time, but I'll see if I can reproduce it on s3c64xx board I have here at 
home.

Best regards,
Tomasz

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

* Re: [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05 16:15     ` Bartlomiej Zolnierkiewicz
  -1 siblings, 0 replies; 103+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-03-05 16:15 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Stephen Warren,
	Tomasz Figa, Mark Brown, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski


Hi Tomek,

On Monday, March 03, 2014 05:02:08 PM Tomasz Figa wrote:
> This patch moves Exynos power domain code to use the new generic power
> domain look-up framework introduced by previous patch, allowing the new
> code to be compiled with CONFIG_ARCH_EXYNOS selected as well.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  .../bindings/arm/exynos/power_domain.txt           | 12 ++--
>  arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
>  kernel/power/Kconfig                               |  2 +-
>  3 files changed, 7 insertions(+), 87 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
> index 5216b41..60f26a8 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.
>  
>  Node of a device using power domains must have a samsung,power-domain property
>  defined with a phandle to respective power domain.
> @@ -17,12 +19,8 @@ Example:
>  	lcd0: power-domain-lcd0 {
>  		compatible = "samsung,exynos4210-pd";
>  		reg = <0x10023C00 0x10>;
> +		#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 8fd2488..48ee6c9 100644
> --- a/arch/arm/mach-exynos/pm_domains.c
> +++ b/arch/arm/mach-exynos/pm_domains.c
> @@ -75,78 +75,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);

This removes "samsung,power-domain" phandle handling but I cannot find
in your patch series updates to existing EXYNOS dts files converting
them to use the new "power-domain" property.  Am I missing something?

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> -	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;
> @@ -156,8 +84,6 @@ static __init int exynos4_pm_init_power_domain(void)
>  		struct exynos_pm_domain *pd;
>  		int on;
>  
> -		pdev = of_find_device_by_node(np);
> -
>  		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
>  		if (!pd) {
>  			pr_err("%s: failed to allocate memory for domain\n",
> @@ -170,17 +96,13 @@ 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;
> -
> -		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 45aa98e..b17588c 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -308,7 +308,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


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

* [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
@ 2014-03-05 16:15     ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 103+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-03-05 16:15 UTC (permalink / raw)
  To: linux-arm-kernel


Hi Tomek,

On Monday, March 03, 2014 05:02:08 PM Tomasz Figa wrote:
> This patch moves Exynos power domain code to use the new generic power
> domain look-up framework introduced by previous patch, allowing the new
> code to be compiled with CONFIG_ARCH_EXYNOS selected as well.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  .../bindings/arm/exynos/power_domain.txt           | 12 ++--
>  arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
>  kernel/power/Kconfig                               |  2 +-
>  3 files changed, 7 insertions(+), 87 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
> index 5216b41..60f26a8 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.
>  
>  Node of a device using power domains must have a samsung,power-domain property
>  defined with a phandle to respective power domain.
> @@ -17,12 +19,8 @@ Example:
>  	lcd0: power-domain-lcd0 {
>  		compatible = "samsung,exynos4210-pd";
>  		reg = <0x10023C00 0x10>;
> +		#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 8fd2488..48ee6c9 100644
> --- a/arch/arm/mach-exynos/pm_domains.c
> +++ b/arch/arm/mach-exynos/pm_domains.c
> @@ -75,78 +75,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);

This removes "samsung,power-domain" phandle handling but I cannot find
in your patch series updates to existing EXYNOS dts files converting
them to use the new "power-domain" property.  Am I missing something?

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> -	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;
> @@ -156,8 +84,6 @@ static __init int exynos4_pm_init_power_domain(void)
>  		struct exynos_pm_domain *pd;
>  		int on;
>  
> -		pdev = of_find_device_by_node(np);
> -
>  		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
>  		if (!pd) {
>  			pr_err("%s: failed to allocate memory for domain\n",
> @@ -170,17 +96,13 @@ 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;
> -
> -		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 45aa98e..b17588c 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -308,7 +308,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

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

* Re: [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
  2014-03-05 16:15     ` Bartlomiej Zolnierkiewicz
@ 2014-03-05 16:20       ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 16:20 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Stephen Warren,
	Tomasz Figa, Mark Brown, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski

Hi Bartek,

On 05.03.2014 17:15, Bartlomiej Zolnierkiewicz wrote:
>
> Hi Tomek,
>
> On Monday, March 03, 2014 05:02:08 PM Tomasz Figa wrote:
>> This patch moves Exynos power domain code to use the new generic power
>> domain look-up framework introduced by previous patch, allowing the new
>> code to be compiled with CONFIG_ARCH_EXYNOS selected as well.
>>
>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>> ---
>>   .../bindings/arm/exynos/power_domain.txt           | 12 ++--
>>   arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
>>   kernel/power/Kconfig                               |  2 +-
>>   3 files changed, 7 insertions(+), 87 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
>> index 5216b41..60f26a8 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.
>>
>>   Node of a device using power domains must have a samsung,power-domain property
>>   defined with a phandle to respective power domain.
>> @@ -17,12 +19,8 @@ Example:
>>   	lcd0: power-domain-lcd0 {
>>   		compatible = "samsung,exynos4210-pd";
>>   		reg = <0x10023C00 0x10>;
>> +		#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 8fd2488..48ee6c9 100644
>> --- a/arch/arm/mach-exynos/pm_domains.c
>> +++ b/arch/arm/mach-exynos/pm_domains.c
>> @@ -75,78 +75,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);
>
> This removes "samsung,power-domain" phandle handling but I cannot find
> in your patch series updates to existing EXYNOS dts files converting
> them to use the new "power-domain" property.  Am I missing something?

Patch 01/11 adds generic parsing code along with fallback to the legacy 
"samsung,power-domain" property, if the generic one is not present, as 
it was pretty straightforward to implement it there.

Best regards,
Tomasz

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

* [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
@ 2014-03-05 16:20       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-05 16:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bartek,

On 05.03.2014 17:15, Bartlomiej Zolnierkiewicz wrote:
>
> Hi Tomek,
>
> On Monday, March 03, 2014 05:02:08 PM Tomasz Figa wrote:
>> This patch moves Exynos power domain code to use the new generic power
>> domain look-up framework introduced by previous patch, allowing the new
>> code to be compiled with CONFIG_ARCH_EXYNOS selected as well.
>>
>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>> ---
>>   .../bindings/arm/exynos/power_domain.txt           | 12 ++--
>>   arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
>>   kernel/power/Kconfig                               |  2 +-
>>   3 files changed, 7 insertions(+), 87 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
>> index 5216b41..60f26a8 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.
>>
>>   Node of a device using power domains must have a samsung,power-domain property
>>   defined with a phandle to respective power domain.
>> @@ -17,12 +19,8 @@ Example:
>>   	lcd0: power-domain-lcd0 {
>>   		compatible = "samsung,exynos4210-pd";
>>   		reg = <0x10023C00 0x10>;
>> +		#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 8fd2488..48ee6c9 100644
>> --- a/arch/arm/mach-exynos/pm_domains.c
>> +++ b/arch/arm/mach-exynos/pm_domains.c
>> @@ -75,78 +75,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);
>
> This removes "samsung,power-domain" phandle handling but I cannot find
> in your patch series updates to existing EXYNOS dts files converting
> them to use the new "power-domain" property.  Am I missing something?

Patch 01/11 adds generic parsing code along with fallback to the legacy 
"samsung,power-domain" property, if the generic one is not present, as 
it was pretty straightforward to implement it there.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
@ 2014-03-05 18:37     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 103+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-05 18:37 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King, Ian Campbell,
	devicetree, Pawel Moll, linux-pm, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki,
	linux-kernel@vger.kernel.org

On Mon, Mar 03, 2014 at 04:02:06PM +0000, Tomasz Figa wrote:

[...]

> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;

Returning 0 (ie success) is deliberate here right ? It is a bit misleading
but I can see why (if a device has no backing DT node, it is up to
platform code to bind it). Probably deserves a comment.

> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;

Same here.

> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);
> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;

And here.

Thanks for posting it,
Lorenzo

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-05 18:37     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 103+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-05 18:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 03, 2014 at 04:02:06PM +0000, Tomasz Figa wrote:

[...]

> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;

Returning 0 (ie success) is deliberate here right ? It is a bit misleading
but I can see why (if a device has no backing DT node, it is up to
platform code to bind it). Probably deserves a comment.

> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;

Same here.

> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);
> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;

And here.

Thanks for posting it,
Lorenzo

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

* Re: [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
  2014-03-05 16:20       ` Tomasz Figa
@ 2014-03-07 13:04         ` Bartlomiej Zolnierkiewicz
  -1 siblings, 0 replies; 103+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-03-07 13:04 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Stephen Warren,
	Tomasz Figa, Mark Brown, Stephen Boyd, Lorenzo Pieralisi,
	Ulf Hansson, Marek Szyprowski


On Wednesday, March 05, 2014 05:20:05 PM Tomasz Figa wrote:
> Hi Bartek,
> 
> On 05.03.2014 17:15, Bartlomiej Zolnierkiewicz wrote:
> >
> > Hi Tomek,
> >
> > On Monday, March 03, 2014 05:02:08 PM Tomasz Figa wrote:
> >> This patch moves Exynos power domain code to use the new generic power
> >> domain look-up framework introduced by previous patch, allowing the new
> >> code to be compiled with CONFIG_ARCH_EXYNOS selected as well.
> >>
> >> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> >> ---
> >>   .../bindings/arm/exynos/power_domain.txt           | 12 ++--
> >>   arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
> >>   kernel/power/Kconfig                               |  2 +-
> >>   3 files changed, 7 insertions(+), 87 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
> >> index 5216b41..60f26a8 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.
> >>
> >>   Node of a device using power domains must have a samsung,power-domain property
> >>   defined with a phandle to respective power domain.
> >> @@ -17,12 +19,8 @@ Example:
> >>   	lcd0: power-domain-lcd0 {
> >>   		compatible = "samsung,exynos4210-pd";
> >>   		reg = <0x10023C00 0x10>;
> >> +		#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 8fd2488..48ee6c9 100644
> >> --- a/arch/arm/mach-exynos/pm_domains.c
> >> +++ b/arch/arm/mach-exynos/pm_domains.c
> >> @@ -75,78 +75,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);
> >
> > This removes "samsung,power-domain" phandle handling but I cannot find
> > in your patch series updates to existing EXYNOS dts files converting
> > them to use the new "power-domain" property.  Am I missing something?
> 
> Patch 01/11 adds generic parsing code along with fallback to the legacy 
> "samsung,power-domain" property, if the generic one is not present, as 
> it was pretty straightforward to implement it there.

Ah, silly me, I should have looked more closely at patch #1.  Anyway,
I tested your patchset on Exynos4412 Trats2 target and it works fine
(BTW it also seems that your patchset fixed the issue of device not
being removed from power domain on ->probe failure).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


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

* [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings
@ 2014-03-07 13:04         ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 103+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-03-07 13:04 UTC (permalink / raw)
  To: linux-arm-kernel


On Wednesday, March 05, 2014 05:20:05 PM Tomasz Figa wrote:
> Hi Bartek,
> 
> On 05.03.2014 17:15, Bartlomiej Zolnierkiewicz wrote:
> >
> > Hi Tomek,
> >
> > On Monday, March 03, 2014 05:02:08 PM Tomasz Figa wrote:
> >> This patch moves Exynos power domain code to use the new generic power
> >> domain look-up framework introduced by previous patch, allowing the new
> >> code to be compiled with CONFIG_ARCH_EXYNOS selected as well.
> >>
> >> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> >> ---
> >>   .../bindings/arm/exynos/power_domain.txt           | 12 ++--
> >>   arch/arm/mach-exynos/pm_domains.c                  | 80 +---------------------
> >>   kernel/power/Kconfig                               |  2 +-
> >>   3 files changed, 7 insertions(+), 87 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
> >> index 5216b41..60f26a8 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.
> >>
> >>   Node of a device using power domains must have a samsung,power-domain property
> >>   defined with a phandle to respective power domain.
> >> @@ -17,12 +19,8 @@ Example:
> >>   	lcd0: power-domain-lcd0 {
> >>   		compatible = "samsung,exynos4210-pd";
> >>   		reg = <0x10023C00 0x10>;
> >> +		#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 8fd2488..48ee6c9 100644
> >> --- a/arch/arm/mach-exynos/pm_domains.c
> >> +++ b/arch/arm/mach-exynos/pm_domains.c
> >> @@ -75,78 +75,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);
> >
> > This removes "samsung,power-domain" phandle handling but I cannot find
> > in your patch series updates to existing EXYNOS dts files converting
> > them to use the new "power-domain" property.  Am I missing something?
> 
> Patch 01/11 adds generic parsing code along with fallback to the legacy 
> "samsung,power-domain" property, if the generic one is not present, as 
> it was pretty straightforward to implement it there.

Ah, silly me, I should have looked more closely at patch #1.  Anyway,
I tested your patchset on Exynos4412 Trats2 target and it works fine
(BTW it also seems that your patchset fixed the issue of device not
being removed from power domain on ->probe failure).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
  (?)
@ 2014-03-14 23:07     ` Kevin Hilman
  -1 siblings, 0 replies; 103+ messages in thread
From: Kevin Hilman @ 2014-03-14 23:07 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar Gala

Tomasz Figa <tomasz.figa@gmail.com> writes:

> 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 <tomasz.figa@gmail.com>

Reviewed-by: Kevin Hilman <khilman@linaro.org>

The approach and binding both look good to me, other than a few minor
nits on comments and question on the locking below...

[...]

> @@ -2177,3 +2181,297 @@ 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

why all caps?

[...]

> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +					struct of_phandle_args *genpdspec)
> +{
> +	struct of_genpd_provider *provider;
> +	struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +	/* Check if we have such a provider in our array */

I think you want to take the mutex here...

> +	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;
> +	}

...and release it here, right?

[...]

> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP

hmm, more yelling?


Otherwise, looks good to me.

Kevin

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-14 23:07     ` Kevin Hilman
  0 siblings, 0 replies; 103+ messages in thread
From: Kevin Hilman @ 2014-03-14 23:07 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar Gala

Tomasz Figa <tomasz.figa@gmail.com> writes:

> 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 <tomasz.figa@gmail.com>

Reviewed-by: Kevin Hilman <khilman@linaro.org>

The approach and binding both look good to me, other than a few minor
nits on comments and question on the locking below...

[...]

> @@ -2177,3 +2181,297 @@ 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

why all caps?

[...]

> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +					struct of_phandle_args *genpdspec)
> +{
> +	struct of_genpd_provider *provider;
> +	struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +	/* Check if we have such a provider in our array */

I think you want to take the mutex here...

> +	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;
> +	}

...and release it here, right?

[...]

> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP

hmm, more yelling?


Otherwise, looks good to me.

Kevin

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-14 23:07     ` Kevin Hilman
  0 siblings, 0 replies; 103+ messages in thread
From: Kevin Hilman @ 2014-03-14 23:07 UTC (permalink / raw)
  To: linux-arm-kernel

Tomasz Figa <tomasz.figa@gmail.com> writes:

> 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 <tomasz.figa@gmail.com>

Reviewed-by: Kevin Hilman <khilman@linaro.org>

The approach and binding both look good to me, other than a few minor
nits on comments and question on the locking below...

[...]

> @@ -2177,3 +2181,297 @@ 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

why all caps?

[...]

> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +					struct of_phandle_args *genpdspec)
> +{
> +	struct of_genpd_provider *provider;
> +	struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +	/* Check if we have such a provider in our array */

I think you want to take the mutex here...

> +	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;
> +	}

...and release it here, right?

[...]

> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP

hmm, more yelling?


Otherwise, looks good to me.

Kevin

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
  (?)
@ 2014-03-19 23:13     ` Sören Brinkmann
  -1 siblings, 0 replies; 103+ messages in thread
From: Sören Brinkmann @ 2014-03-19 23:13 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar Gala

On Mon, 2014-03-03 at 05:02PM +0100, Tomasz Figa wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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".

Does this allow nesting of power domains? E.g. you have a PD which is
represented by some programmable power supply, and within this domain
smaller islands/domains that can be gated independently.

	Thanks,
	Sören



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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-19 23:13     ` Sören Brinkmann
  0 siblings, 0 replies; 103+ messages in thread
From: Sören Brinkmann @ 2014-03-19 23:13 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar

On Mon, 2014-03-03 at 05:02PM +0100, Tomasz Figa wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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".

Does this allow nesting of power domains? E.g. you have a PD which is
represented by some programmable power supply, and within this domain
smaller islands/domains that can be gated independently.

	Thanks,
	Sören

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-19 23:13     ` Sören Brinkmann
  0 siblings, 0 replies; 103+ messages in thread
From: Sören Brinkmann @ 2014-03-19 23:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2014-03-03 at 05:02PM +0100, Tomasz Figa wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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-domain : 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-domain = <&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".

Does this allow nesting of power domains? E.g. you have a PD which is
represented by some programmable power supply, and within this domain
smaller islands/domains that can be gated independently.

	Thanks,
	S?ren

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-19 23:13     ` Sören Brinkmann
  (?)
@ 2014-03-19 23:16       ` Tomasz Figa
  -1 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-19 23:16 UTC (permalink / raw)
  To: Sören Brinkmann
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar Gala

Hi Sören,

On 20.03.2014 00:13, Sören Brinkmann wrote:
> On Mon, 2014-03-03 at 05:02PM +0100, Tomasz Figa wrote:
>> 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 <tomasz.figa@gmail.com>
>> ---
>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>   drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>>   include/linux/pm_domain.h                          |  46 ++++
>>   kernel/power/Kconfig                               |   4 +
>>   4 files changed, 399 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..93be5d9
>> --- /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-domain : 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-domain = <&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".
>
> Does this allow nesting of power domains? E.g. you have a PD which is
> represented by some programmable power supply, and within this domain
> smaller islands/domains that can be gated independently.

These are client-side bindings only, i.e. power domain providers and 
consumers. Registering power domains and relations between them are up 
to platform-specific code, e.g. power controller driver.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-19 23:16       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-19 23:16 UTC (permalink / raw)
  To: Sören Brinkmann
  Cc: linux-pm, Mark Rutland, Ulf Hansson, Stephen Warren, Len Brown,
	Stephen Boyd, Tomasz Figa, Pavel Machek, Kukjin Kim,
	Marek Szyprowski, linux-samsung-soc, Russell King,
	Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi, devicetree,
	Pawel Moll, Ian Campbell, Rob Herring, linux-arm-kernel,
	Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel, Mark Brown,
	Kumar Gala

Hi Sören,

On 20.03.2014 00:13, Sören Brinkmann wrote:
> On Mon, 2014-03-03 at 05:02PM +0100, Tomasz Figa wrote:
>> 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 <tomasz.figa@gmail.com>
>> ---
>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>   drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>>   include/linux/pm_domain.h                          |  46 ++++
>>   kernel/power/Kconfig                               |   4 +
>>   4 files changed, 399 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..93be5d9
>> --- /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-domain : 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-domain = <&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".
>
> Does this allow nesting of power domains? E.g. you have a PD which is
> represented by some programmable power supply, and within this domain
> smaller islands/domains that can be gated independently.

These are client-side bindings only, i.e. power domain providers and 
consumers. Registering power domains and relations between them are up 
to platform-specific code, e.g. power controller driver.

Best regards,
Tomasz

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-03-19 23:16       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-03-19 23:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi S?ren,

On 20.03.2014 00:13, S?ren Brinkmann wrote:
> On Mon, 2014-03-03 at 05:02PM +0100, Tomasz Figa wrote:
>> 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 <tomasz.figa@gmail.com>
>> ---
>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>   drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>>   include/linux/pm_domain.h                          |  46 ++++
>>   kernel/power/Kconfig                               |   4 +
>>   4 files changed, 399 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..93be5d9
>> --- /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-domain : 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-domain = <&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".
>
> Does this allow nesting of power domains? E.g. you have a PD which is
> represented by some programmable power supply, and within this domain
> smaller islands/domains that can be gated independently.

These are client-side bindings only, i.e. power domain providers and 
consumers. Registering power domains and relations between them are up 
to platform-specific code, e.g. power controller driver.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-03-03 16:02   ` Tomasz Figa
  (?)
@ 2014-04-03 12:16     ` Ulf Hansson
  -1 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-04-03 12:16 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Marek Szyprowski

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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.

I am trying to understand if using a value > 1, ever would make sense.
Wouldn't that mean each consumer (device) would actually be a part of
more than one power domain? That won't work, right!?

Additionally, there are no corresponding parsing method (like
of_genpd_xlate_onecell() ) that support more than one cell.

Kind regards
Ulf Hansson

> +
> +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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);
> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-04-03 12:16     ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-04-03 12:16 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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.

I am trying to understand if using a value > 1, ever would make sense.
Wouldn't that mean each consumer (device) would actually be a part of
more than one power domain? That won't work, right!?

Additionally, there are no corresponding parsing method (like
of_genpd_xlate_onecell() ) that support more than one cell.

Kind regards
Ulf Hansson

> +
> +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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);
> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-04-03 12:16     ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-04-03 12:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> 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 <tomasz.figa@gmail.com>
> ---
>  .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>  drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>  include/linux/pm_domain.h                          |  46 ++++
>  kernel/power/Kconfig                               |   4 +
>  4 files changed, 399 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..93be5d9
> --- /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.

I am trying to understand if using a value > 1, ever would make sense.
Wouldn't that mean each consumer (device) would actually be a part of
more than one power domain? That won't work, right!?

Additionally, there are no corresponding parsing method (like
of_genpd_xlate_onecell() ) that support more than one cell.

Kind regards
Ulf Hansson

> +
> +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-domain : 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-domain = <&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 dc127e5..006b455 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -3,12 +3,16 @@
>   *
>   * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
>   *
> + * Support for Device Tree based power domain providers:
> + * Copyright (C) 2014 Tomasz Figa <tomasz.figa@gmail.com>
> + *
>   * This file is released under the GPLv2.
>   */
>
>  #include <linux/init.h>
>  #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>
> @@ -2177,3 +2181,297 @@ 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);
> +
> +/* See of_genpd_get_from_provider(). */
> +static struct generic_pm_domain *__of_genpd_get_from_provider(
> +                                       struct of_phandle_args *genpdspec)
> +{
> +       struct of_genpd_provider *provider;
> +       struct generic_pm_domain *genpd = ERR_PTR(-EPROBE_DEFER);
> +
> +       /* 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;
> +       }
> +
> +       return genpd;
> +}
> +
> +/**
> + * 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;
> +
> +       mutex_lock(&of_genpd_mutex);
> +       genpd = __of_genpd_get_from_provider(genpdspec);
> +       mutex_unlock(&of_genpd_mutex);
> +
> +       return genpd;
> +}
> +
> +/*
> + * DEVICE<->DOMAIN BINDING USING DEVICE TREE LOOK-UP
> + *
> + * The code below registers a notifier for platform bus devices'
> + * BUS_NOTIFY_BIND_DRIVER events and tries to attach devices to their power
> + * domains by looking them up using Device Tree.
> + *
> + * Similarly in BUS_NOTIFY_UNBOUND_DRIVER the device is detached from its
> + * domain, since it no longer supports runtime PM without any driver bound
> + * to it.
> + *
> + * Both generic and legacy Samsung-specific DT bindings are supported to
> + * keep backwards compatibility with existing DTBs.
> + */
> +
> +/**
> + * genpd_bind_domain - Bind device to its power domain using Device Tree.
> + * @dev: Device to bind to its power domain.
> + *
> + * Tries to parse power domain specifier from device's OF node and if succeeds
> + * attaches the device to retrieved power domain.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_bind_domain(struct device *dev)
> +{
> +       struct of_phandle_args pd_args;
> +       struct generic_pm_domain *pd;
> +       int ret;
> +
> +       if (!dev->of_node)
> +               return 0;
> +
> +       ret = of_parse_phandle_with_args(dev->of_node, "power-domain",
> +                                       "#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 0;
> +       }
> +
> +       pd = of_genpd_get_from_provider(&pd_args);
> +       if (IS_ERR(pd)) {
> +               if (PTR_ERR(pd) != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to find power domain: %ld\n",
> +                               PTR_ERR(pd));
> +               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);
> +               return ret;
> +       }
> +
> +       pm_genpd_dev_need_restore(dev, true);
> +
> +       return 0;
> +}
> +
> +/**
> + * genpd_unbind_domain - Unbind device from its power domain.
> + * @dev: Device to unbind from its power domain.
> + *
> + * Unbinds device from power domain previously bound to it.
> + *
> + * Returns 0 on success or negative error code otherwise.
> + */
> +int genpd_unbind_domain(struct device *dev)
> +{
> +       struct generic_pm_domain *pd = dev_to_genpd(dev);
> +       int ret;
> +
> +       if (!dev->of_node || IS_ERR(pd))
> +               return 0;
> +
> +       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;
> +}
> +#endif
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 7c1d252..04473d4 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_bind_domain(struct device *dev);
> +int genpd_unbind_domain(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_bind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +static inline int genpd_unbind_domain(struct device *dev)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
> +
>  #endif /* _LINUX_PM_DOMAIN_H */
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 2fac9cc..45aa98e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -306,6 +306,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.0
>

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-04-03 12:30       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-04-03 12:30 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Marek Szyprowski

Hi Ulf,

On 03.04.2014 14:16, Ulf Hansson wrote:
> On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>> 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 <tomasz.figa@gmail.com>
>> ---
>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>   drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>>   include/linux/pm_domain.h                          |  46 ++++
>>   kernel/power/Kconfig                               |   4 +
>>   4 files changed, 399 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..93be5d9
>> --- /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.
>
> I am trying to understand if using a value > 1, ever would make sense.
> Wouldn't that mean each consumer (device) would actually be a part of
> more than one power domain? That won't work, right!?

Not exactly. Each phandle + #power-domain-cells cells are used just for 
single power domain.

The cells here are used merely as the identifier used by power domain 
driver to translate a power domain specifier from DT to a kernel 
pointer. It's up to driver bindings to select the number of cells to 
properly identify a power domain.

As an example (from different world, but showing the same mechanism), 
let's see a common pattern of GPIO banks on some SoC:

GPA0
GPA1
GPB0
GPB1
GPC0
GPC1

One might assign a single-cell ID to each bank ending with a namespace 
of integers from 0 to 5 that would be used as follows:

#define GPA0 0
#define GPA1 1
#define GPB0 2
#define GPB1 3
#define GPC0 4
#define GPC1 5

reset-gpios = <&gpio GPA0 4>;

However one might also consider assigning one cell to bank set (e.g. 
GPA) and one cell to identify the bank inside of a set, like on the 
following example:

#define GPA 0
#define GPB 1
#define GPC 2

reset-gpios = <&gpio GPA 0 4>;

Good bindings should allow arbitrary identification schemes to let a 
driver developer use the one that suits the hardware he's working on.

>
> Additionally, there are no corresponding parsing method (like
> of_genpd_xlate_onecell() ) that support more than one cell.

There are two generic xlate helpers provided for the most common cases 
that are likely to be reused by most drivers. For more complex cases 
it's up to the driver to implement its own mapping function. It can be 
promoted to a generic one later if such need shows up.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-04-03 12:30       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-04-03 12:30 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Russell King,
	Kukjin Kim, Kumar Gala, Ian Campbell, Mark Rutland, Pawel Moll,
	Rob Herring, Bartlomiej Zolnierkiewicz, Stephen Warren,
	Tomasz Figa, Mark Brown

Hi Ulf,

On 03.04.2014 14:16, Ulf Hansson wrote:
> On 3 March 2014 17:02, Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> 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 <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>   drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>>   include/linux/pm_domain.h                          |  46 ++++
>>   kernel/power/Kconfig                               |   4 +
>>   4 files changed, 399 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..93be5d9
>> --- /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.
>
> I am trying to understand if using a value > 1, ever would make sense.
> Wouldn't that mean each consumer (device) would actually be a part of
> more than one power domain? That won't work, right!?

Not exactly. Each phandle + #power-domain-cells cells are used just for 
single power domain.

The cells here are used merely as the identifier used by power domain 
driver to translate a power domain specifier from DT to a kernel 
pointer. It's up to driver bindings to select the number of cells to 
properly identify a power domain.

As an example (from different world, but showing the same mechanism), 
let's see a common pattern of GPIO banks on some SoC:

GPA0
GPA1
GPB0
GPB1
GPC0
GPC1

One might assign a single-cell ID to each bank ending with a namespace 
of integers from 0 to 5 that would be used as follows:

#define GPA0 0
#define GPA1 1
#define GPB0 2
#define GPB1 3
#define GPC0 4
#define GPC1 5

reset-gpios = <&gpio GPA0 4>;

However one might also consider assigning one cell to bank set (e.g. 
GPA) and one cell to identify the bank inside of a set, like on the 
following example:

#define GPA 0
#define GPB 1
#define GPC 2

reset-gpios = <&gpio GPA 0 4>;

Good bindings should allow arbitrary identification schemes to let a 
driver developer use the one that suits the hardware he's working on.

>
> Additionally, there are no corresponding parsing method (like
> of_genpd_xlate_onecell() ) that support more than one cell.

There are two generic xlate helpers provided for the most common cases 
that are likely to be reused by most drivers. For more complex cases 
it's up to the driver to implement its own mapping function. It can be 
promoted to a generic one later if such need shows up.

Best regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-04-03 12:30       ` Tomasz Figa
  0 siblings, 0 replies; 103+ messages in thread
From: Tomasz Figa @ 2014-04-03 12:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ulf,

On 03.04.2014 14:16, Ulf Hansson wrote:
> On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>> 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 <tomasz.figa@gmail.com>
>> ---
>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>   drivers/base/power/domain.c                        | 298 +++++++++++++++++++++
>>   include/linux/pm_domain.h                          |  46 ++++
>>   kernel/power/Kconfig                               |   4 +
>>   4 files changed, 399 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..93be5d9
>> --- /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.
>
> I am trying to understand if using a value > 1, ever would make sense.
> Wouldn't that mean each consumer (device) would actually be a part of
> more than one power domain? That won't work, right!?

Not exactly. Each phandle + #power-domain-cells cells are used just for 
single power domain.

The cells here are used merely as the identifier used by power domain 
driver to translate a power domain specifier from DT to a kernel 
pointer. It's up to driver bindings to select the number of cells to 
properly identify a power domain.

As an example (from different world, but showing the same mechanism), 
let's see a common pattern of GPIO banks on some SoC:

GPA0
GPA1
GPB0
GPB1
GPC0
GPC1

One might assign a single-cell ID to each bank ending with a namespace 
of integers from 0 to 5 that would be used as follows:

#define GPA0 0
#define GPA1 1
#define GPB0 2
#define GPB1 3
#define GPC0 4
#define GPC1 5

reset-gpios = <&gpio GPA0 4>;

However one might also consider assigning one cell to bank set (e.g. 
GPA) and one cell to identify the bank inside of a set, like on the 
following example:

#define GPA 0
#define GPB 1
#define GPC 2

reset-gpios = <&gpio GPA 0 4>;

Good bindings should allow arbitrary identification schemes to let a 
driver developer use the one that suits the hardware he's working on.

>
> Additionally, there are no corresponding parsing method (like
> of_genpd_xlate_onecell() ) that support more than one cell.

There are two generic xlate helpers provided for the most common cases 
that are likely to be reused by most drivers. For more complex cases 
it's up to the driver to implement its own mapping function. It can be 
promoted to a generic one later if such need shows up.

Best regards,
Tomasz

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
  2014-04-03 12:30       ` Tomasz Figa
  (?)
@ 2014-04-03 13:32         ` Ulf Hansson
  -1 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-04-03 13:32 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown, Stephen Boyd,
	Lorenzo Pieralisi, Marek Szyprowski

On 3 April 2014 14:30, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Ulf,
>
>
> On 03.04.2014 14:16, Ulf Hansson wrote:
>>
>> On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>>>
>>> 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 <tomasz.figa@gmail.com>
>>> ---
>>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>>   drivers/base/power/domain.c                        | 298
>>> +++++++++++++++++++++
>>>   include/linux/pm_domain.h                          |  46 ++++
>>>   kernel/power/Kconfig                               |   4 +
>>>   4 files changed, 399 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..93be5d9
>>> --- /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.
>>
>>
>> I am trying to understand if using a value > 1, ever would make sense.
>> Wouldn't that mean each consumer (device) would actually be a part of
>> more than one power domain? That won't work, right!?
>
>
> Not exactly. Each phandle + #power-domain-cells cells are used just for
> single power domain.
>
> The cells here are used merely as the identifier used by power domain driver
> to translate a power domain specifier from DT to a kernel pointer. It's up
> to driver bindings to select the number of cells to properly identify a
> power domain.
>
> As an example (from different world, but showing the same mechanism), let's
> see a common pattern of GPIO banks on some SoC:
>
> GPA0
> GPA1
> GPB0
> GPB1
> GPC0
> GPC1
>
> One might assign a single-cell ID to each bank ending with a namespace of
> integers from 0 to 5 that would be used as follows:
>
> #define GPA0 0
> #define GPA1 1
> #define GPB0 2
> #define GPB1 3
> #define GPC0 4
> #define GPC1 5
>
> reset-gpios = <&gpio GPA0 4>;
>
> However one might also consider assigning one cell to bank set (e.g. GPA)
> and one cell to identify the bank inside of a set, like on the following
> example:
>
> #define GPA 0
> #define GPB 1
> #define GPC 2
>
> reset-gpios = <&gpio GPA 0 4>;
>
> Good bindings should allow arbitrary identification schemes to let a driver
> developer use the one that suits the hardware he's working on.
>
>
>>
>> Additionally, there are no corresponding parsing method (like
>> of_genpd_xlate_onecell() ) that support more than one cell.
>
>
> There are two generic xlate helpers provided for the most common cases that
> are likely to be reused by most drivers. For more complex cases it's up to
> the driver to implement its own mapping function. It can be promoted to a
> generic one later if such need shows up.
>
> Best regards,
> Tomasz

Tomasz, thanks for the clarification! I still have more to learn about DT. :-)

Not sure if some additional comments would make this more clear though
- or if it's juts my untrained eye that had a few problems
understanding.

Kind regards
Ulf Hansson

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

* Re: [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-04-03 13:32         ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-04-03 13:32 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-pm, linux-kernel, linux-samsung-soc, linux-arm-kernel,
	devicetree, Greg Kroah-Hartman, Rafael J. Wysocki, Pavel Machek,
	Len Brown, Russell King, Kukjin Kim, Kumar Gala, Ian Campbell,
	Mark Rutland, Pawel Moll, Rob Herring, Bartlomiej Zolnierkiewicz,
	Stephen Warren, Tomasz Figa, Mark Brown

On 3 April 2014 14:30, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Ulf,
>
>
> On 03.04.2014 14:16, Ulf Hansson wrote:
>>
>> On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>>>
>>> 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 <tomasz.figa@gmail.com>
>>> ---
>>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>>   drivers/base/power/domain.c                        | 298
>>> +++++++++++++++++++++
>>>   include/linux/pm_domain.h                          |  46 ++++
>>>   kernel/power/Kconfig                               |   4 +
>>>   4 files changed, 399 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..93be5d9
>>> --- /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.
>>
>>
>> I am trying to understand if using a value > 1, ever would make sense.
>> Wouldn't that mean each consumer (device) would actually be a part of
>> more than one power domain? That won't work, right!?
>
>
> Not exactly. Each phandle + #power-domain-cells cells are used just for
> single power domain.
>
> The cells here are used merely as the identifier used by power domain driver
> to translate a power domain specifier from DT to a kernel pointer. It's up
> to driver bindings to select the number of cells to properly identify a
> power domain.
>
> As an example (from different world, but showing the same mechanism), let's
> see a common pattern of GPIO banks on some SoC:
>
> GPA0
> GPA1
> GPB0
> GPB1
> GPC0
> GPC1
>
> One might assign a single-cell ID to each bank ending with a namespace of
> integers from 0 to 5 that would be used as follows:
>
> #define GPA0 0
> #define GPA1 1
> #define GPB0 2
> #define GPB1 3
> #define GPC0 4
> #define GPC1 5
>
> reset-gpios = <&gpio GPA0 4>;
>
> However one might also consider assigning one cell to bank set (e.g. GPA)
> and one cell to identify the bank inside of a set, like on the following
> example:
>
> #define GPA 0
> #define GPB 1
> #define GPC 2
>
> reset-gpios = <&gpio GPA 0 4>;
>
> Good bindings should allow arbitrary identification schemes to let a driver
> developer use the one that suits the hardware he's working on.
>
>
>>
>> Additionally, there are no corresponding parsing method (like
>> of_genpd_xlate_onecell() ) that support more than one cell.
>
>
> There are two generic xlate helpers provided for the most common cases that
> are likely to be reused by most drivers. For more complex cases it's up to
> the driver to implement its own mapping function. It can be promoted to a
> generic one later if such need shows up.
>
> Best regards,
> Tomasz

Tomasz, thanks for the clarification! I still have more to learn about DT. :-)

Not sure if some additional comments would make this more clear though
- or if it's juts my untrained eye that had a few problems
understanding.

Kind regards
Ulf Hansson

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

* [PATCH v2 01/11] base: power: Add generic OF-based power domain look-up
@ 2014-04-03 13:32         ` Ulf Hansson
  0 siblings, 0 replies; 103+ messages in thread
From: Ulf Hansson @ 2014-04-03 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 3 April 2014 14:30, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Ulf,
>
>
> On 03.04.2014 14:16, Ulf Hansson wrote:
>>
>> On 3 March 2014 17:02, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>>>
>>> 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 <tomasz.figa@gmail.com>
>>> ---
>>>   .../devicetree/bindings/power/power_domain.txt     |  51 ++++
>>>   drivers/base/power/domain.c                        | 298
>>> +++++++++++++++++++++
>>>   include/linux/pm_domain.h                          |  46 ++++
>>>   kernel/power/Kconfig                               |   4 +
>>>   4 files changed, 399 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..93be5d9
>>> --- /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.
>>
>>
>> I am trying to understand if using a value > 1, ever would make sense.
>> Wouldn't that mean each consumer (device) would actually be a part of
>> more than one power domain? That won't work, right!?
>
>
> Not exactly. Each phandle + #power-domain-cells cells are used just for
> single power domain.
>
> The cells here are used merely as the identifier used by power domain driver
> to translate a power domain specifier from DT to a kernel pointer. It's up
> to driver bindings to select the number of cells to properly identify a
> power domain.
>
> As an example (from different world, but showing the same mechanism), let's
> see a common pattern of GPIO banks on some SoC:
>
> GPA0
> GPA1
> GPB0
> GPB1
> GPC0
> GPC1
>
> One might assign a single-cell ID to each bank ending with a namespace of
> integers from 0 to 5 that would be used as follows:
>
> #define GPA0 0
> #define GPA1 1
> #define GPB0 2
> #define GPB1 3
> #define GPC0 4
> #define GPC1 5
>
> reset-gpios = <&gpio GPA0 4>;
>
> However one might also consider assigning one cell to bank set (e.g. GPA)
> and one cell to identify the bank inside of a set, like on the following
> example:
>
> #define GPA 0
> #define GPB 1
> #define GPC 2
>
> reset-gpios = <&gpio GPA 0 4>;
>
> Good bindings should allow arbitrary identification schemes to let a driver
> developer use the one that suits the hardware he's working on.
>
>
>>
>> Additionally, there are no corresponding parsing method (like
>> of_genpd_xlate_onecell() ) that support more than one cell.
>
>
> There are two generic xlate helpers provided for the most common cases that
> are likely to be reused by most drivers. For more complex cases it's up to
> the driver to implement its own mapping function. It can be promoted to a
> generic one later if such need shows up.
>
> Best regards,
> Tomasz

Tomasz, thanks for the clarification! I still have more to learn about DT. :-)

Not sure if some additional comments would make this more clear though
- or if it's juts my untrained eye that had a few problems
understanding.

Kind regards
Ulf Hansson

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

end of thread, other threads:[~2014-04-03 13:32 UTC | newest]

Thread overview: 103+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-03 16:02 [PATCH v2 00/11] Generic Device Tree based power domain look-up Tomasz Figa
2014-03-03 16:02 ` Tomasz Figa
2014-03-03 16:02 ` Tomasz Figa
2014-03-03 16:02 ` [PATCH v2 01/11] base: power: Add generic OF-based " Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-04 18:23   ` Stephen Boyd
2014-03-04 18:23     ` Stephen Boyd
2014-03-05 11:53     ` Tomasz Figa
2014-03-05 11:53       ` Tomasz Figa
2014-03-05  4:24   ` Mark Brown
2014-03-05  4:24     ` Mark Brown
2014-03-05  6:41   ` Rob Herring
2014-03-05  6:41     ` Rob Herring
2014-03-05  7:19   ` Ulf Hansson
2014-03-05  7:19     ` Ulf Hansson
2014-03-05  7:19     ` Ulf Hansson
2014-03-05 11:47     ` Tomasz Figa
2014-03-05 11:47       ` Tomasz Figa
2014-03-05 11:47       ` Tomasz Figa
2014-03-05 12:44       ` Tomasz Figa
2014-03-05 12:44         ` Tomasz Figa
2014-03-05 12:44         ` Tomasz Figa
2014-03-05 18:37   ` Lorenzo Pieralisi
2014-03-05 18:37     ` Lorenzo Pieralisi
2014-03-14 23:07   ` Kevin Hilman
2014-03-14 23:07     ` Kevin Hilman
2014-03-14 23:07     ` Kevin Hilman
2014-03-19 23:13   ` Sören Brinkmann
2014-03-19 23:13     ` Sören Brinkmann
2014-03-19 23:13     ` Sören Brinkmann
2014-03-19 23:16     ` Tomasz Figa
2014-03-19 23:16       ` Tomasz Figa
2014-03-19 23:16       ` Tomasz Figa
2014-04-03 12:16   ` Ulf Hansson
2014-04-03 12:16     ` Ulf Hansson
2014-04-03 12:16     ` Ulf Hansson
2014-04-03 12:30     ` Tomasz Figa
2014-04-03 12:30       ` Tomasz Figa
2014-04-03 12:30       ` Tomasz Figa
2014-04-03 13:32       ` Ulf Hansson
2014-04-03 13:32         ` Ulf Hansson
2014-04-03 13:32         ` Ulf Hansson
2014-03-03 16:02 ` [PATCH v2 02/11] drivercore: Bind/unbind power domain on probe/remove Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-04 18:29   ` Stephen Boyd
2014-03-04 18:29     ` Stephen Boyd
2014-03-04 19:17   ` Philipp Zabel
2014-03-04 19:17     ` Philipp Zabel
2014-03-04 19:17     ` Philipp Zabel
2014-03-05  4:26   ` Mark Brown
2014-03-05  4:26     ` Mark Brown
2014-03-05  7:22   ` Ulf Hansson
2014-03-05  7:22     ` Ulf Hansson
2014-03-05  7:22     ` Ulf Hansson
2014-03-03 16:02 ` [PATCH v2 03/11] ARM: exynos: Move to generic power domain bindings Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-05 16:15   ` Bartlomiej Zolnierkiewicz
2014-03-05 16:15     ` Bartlomiej Zolnierkiewicz
2014-03-05 16:20     ` Tomasz Figa
2014-03-05 16:20       ` Tomasz Figa
2014-03-07 13:04       ` Bartlomiej Zolnierkiewicz
2014-03-07 13:04         ` Bartlomiej Zolnierkiewicz
2014-03-03 16:02 ` [PATCH v2 04/11] ARM: s3c64xx: pm: Use name field of generic_pm_domain Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-05  4:28   ` Mark Brown
2014-03-05  4:28     ` Mark Brown
2014-03-03 16:02 ` [PATCH v2 05/11] ARM: s3c64xx: pm: Add always_on field to s3c64xx_pm_domain struct Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-05  4:28   ` Mark Brown
2014-03-05  4:28     ` Mark Brown
2014-03-03 16:02 ` [PATCH v2 06/11] ARM: s3c64xx: pm: Add pwr_stat bit for domain G Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-05  4:28   ` Mark Brown
2014-03-05  4:28     ` Mark Brown
2014-03-03 16:02 ` [PATCH v2 07/11] ARM: s3c64xx: pm: Add device tree based power domain instantiation Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-05  4:29   ` Mark Brown
2014-03-05  4:29     ` Mark Brown
2014-03-05  4:29     ` Mark Brown
2014-03-03 16:02 ` [PATCH v2 08/11] ARM: s3c64xx: dt: Enable SoC-level power management Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-05  4:30   ` Mark Brown
2014-03-05  4:30     ` Mark Brown
2014-03-05  4:30     ` Mark Brown
2014-03-03 16:02 ` [PATCH v2 09/11] ARM: dts: s3c64xx: Add nodes for power domains Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-05  4:31   ` Mark Brown
2014-03-05  4:31     ` Mark Brown
2014-03-03 16:02 ` [PATCH v2 10/11] ARM: dts: s3c64xx: Add node for display controller Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02 ` [PATCH v2 11/11] ARM: dts: s3c6410-mini6410: Add support for LCD screen Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa
2014-03-03 16:02   ` Tomasz Figa

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.