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
Reviewed-by: Mark Brown
Reviewed-by: Kevin Hilman
Reviewed-by: Philipp Zabel
[on i.MX6 GK802]
Tested-by: Philipp Zabel
---
.../devicetree/bindings/power/power_domain.txt | 51
drivers/base/power/domain.c| 283 +
include/linux/pm_domain.h | 46
kernel/power/Kconfig | 4 +
4 files changed, 384 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 000..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@1234 {
+ compatible = "foo,power-controller";
+ reg = <0x1234 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@1235 {
+ compatible = "foo,i-leak-current";
+ reg = <0x1235 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 ae098a2..7677744 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
#include
#include
@@ -2189,3 +2190,285 @@ 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;
+