Skip to contentSkip to conversation

ARM: Exynos: Adapt to generic power domain

PATCH Superseded Thomas Abraham 5 participants 13 messages Jan 7, 2012 – Feb 1, 2012

Subsystems (8)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover ARM: Exynos: Adapt to generic power domain

Changes since v1:
- Added a OF wrapper around __pm_genpd_add_device as suggested by Rafael.
- Added cpu_relax and usleep_range during waits for power domain to be enabled/disabled.
- Added static registrations of devices to power domains for non-dt platforms.

The power domains available on Exynos4 are made controllable using the generic power domain infrastructure. The Samsung specific power domain control code for Exynos4 is removed. Support for both DT and non-DT Exynos platforms is added.

The first patch adds device tree support for generic power domain. A device node is added to the generic power domain strucure that represents a power domain node in the device tree. Other device nodes in the device tree can include a property with a phandle of the power domain node which will enable that device to be associated with a power domain.

The second patch registers available power domains to generic power domain framework with support for both dt and non-dt platforms. The Samsung specific power domain control support is removed.

The patchset is based on the following tree
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git for-next

with all patches merged from
http://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next

Thomas Abraham (2):
PM / Domains: Add OF support
ARM: Exynos: Hook up power domains to generic power domain infrastructure

 arch/arm/mach-exynos/Kconfig               |   10 +--
 arch/arm/mach-exynos/Makefile              |    2 +-
 arch/arm/mach-exynos/dev-pd.c              |  139 ---------------------
 arch/arm/mach-exynos/mach-nuri.c           |   11 --
 arch/arm/mach-exynos/mach-origen.c         |   14 --
 arch/arm/mach-exynos/mach-smdkv310.c       |   12 --
 arch/arm/mach-exynos/mach-universal_c210.c |   17 ---
 arch/arm/mach-exynos/pm_domains.c          |  183 ++++++++++++++++++++++++++++
 drivers/base/power/domain.c                |   32 +++++
 include/linux/pm_domain.h                  |   12 ++
 10 files changed, 229 insertions(+), 203 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/dev-pd.c
 create mode 100644 arch/arm/mach-exynos/pm_domains.c
#1 lore raw

PATCH v2 1/2 PM / Domains: Add OF support

A device node pointer is added to generic pm domain structure to associate the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power domain, instantiates the available domains and initializes them by calling pm_genpd_init().

Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain.

pm_genpd_of_add_device() runs through its list of registered power domains and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the matched domain.

Cc Rafael J. Wysocki <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>
---
 drivers/base/power/domain.c |   32 ++++++++++++++++++++++++++++++++
 include/linux/pm_domain.h   |   12 ++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)
drivers/base/power/domain.c +32 -0
index 92e6a90..9ee1f7b 100644
@@ -1171,6 +1171,38 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 }
 
 /**
+ * __pm_genpd_of_add_device - Add a device to an I/O PM domain.
+ * @genpd_node: Device tree node pointer representing a PM domain to which the
+ *   the device is added to.
+ * @dev: Device to be added.
+ * @td: Set of PM QoS timing parameters to attach to the device.
+ */
+int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev,
+			     struct gpd_timing_data *td)
+{
+	struct generic_pm_domain *genpd = NULL, *gpd;
+
+	dev_dbg(dev, "%s()\n", __func__);
+
+	if (IS_ERR_OR_NULL(genpd_node) || IS_ERR_OR_NULL(dev))
+		return -EINVAL;
+
+	mutex_lock(&gpd_list_lock);
+	list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+		if (gpd->of_node == genpd_node) {
+			genpd = gpd;
+			break;
+		}
+	}
+	mutex_unlock(&gpd_list_lock);
+
+	if (!genpd)
+		return -EINVAL;
+
+	return __pm_genpd_add_device(genpd, dev, td);
+}
+
+/**
  * pm_genpd_remove_device - Remove a device from an I/O PM domain.
  * @genpd: PM domain to remove the device from.
  * @dev: Device to be removed.
include/linux/pm_domain.h +12 -0
index a03a0ad..e3ff875 100644
@@ -11,6 +11,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 enum gpd_status {
 	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
@@ -70,6 +71,7 @@ struct generic_pm_domain {
 	s64 break_even_ns;	/* Power break even for the entire domain. */
 	s64 max_off_time_ns;	/* Maximum allowed "suspended" time. */
 	ktime_t power_off_time;
+	struct device_node *of_node; /* Node in device tree */
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
@@ -117,12 +119,22 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
 				 struct device *dev,
 				 struct gpd_timing_data *td);
 
+extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
+				    struct device *dev,
+				    struct gpd_timing_data *td);
+
 static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
 				      struct device *dev)
 {
 	return __pm_genpd_add_device(genpd, dev, NULL);
 }
 
+static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
+					 struct device *dev)
+{
+	return __pm_genpd_of_add_device(genpd_node, dev, NULL);
+}
+
 extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 				  struct device *dev);
 extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
Signature · 1 line
1.6.6.rc2
#2 lore raw

PATCH v2 1/2 PM / Domains: Add OF support

Quoted 17 lines · Thomas Abraham

A device node pointer is added to generic pm domain structure to associate the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power domain, instantiates the available domains and initializes them by calling pm_genpd_init().

Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain.

pm_genpd_of_add_device() runs through its list of registered power domains and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the matched domain.

Quoted 4 lines
Cc Rafael J. Wysocki <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

I can take this patch for 3.4, but your [2/2] depends on it, so I'm not sure how to handle that. If you want me to take the other patch too, it'll need ACKs from the Exynos maintaniers.

Thanks,
Rafael

Quoted 92 lines
---
 drivers/base/power/domain.c |   32 ++++++++++++++++++++++++++++++++
 include/linux/pm_domain.h   |   12 ++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)
drivers/base/power/domain.c +32 -0
index 92e6a90..9ee1f7b 100644
@@ -1171,6 +1171,38 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 }
 
 /**
+ * __pm_genpd_of_add_device - Add a device to an I/O PM domain.
+ * @genpd_node: Device tree node pointer representing a PM domain to which the
+ *   the device is added to.
+ * @dev: Device to be added.
+ * @td: Set of PM QoS timing parameters to attach to the device.
+ */
+int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev,
+			     struct gpd_timing_data *td)
+{
+	struct generic_pm_domain *genpd = NULL, *gpd;
+
+	dev_dbg(dev, "%s()\n", __func__);
+
+	if (IS_ERR_OR_NULL(genpd_node) || IS_ERR_OR_NULL(dev))
+		return -EINVAL;
+
+	mutex_lock(&gpd_list_lock);
+	list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+		if (gpd->of_node == genpd_node) {
+			genpd = gpd;
+			break;
+		}
+	}
+	mutex_unlock(&gpd_list_lock);
+
+	if (!genpd)
+		return -EINVAL;
+
+	return __pm_genpd_add_device(genpd, dev, td);
+}
+
+/**
  * pm_genpd_remove_device - Remove a device from an I/O PM domain.
  * @genpd: PM domain to remove the device from.
  * @dev: Device to be removed.
include/linux/pm_domain.h +12 -0
index a03a0ad..e3ff875 100644
@@ -11,6 +11,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 enum gpd_status {
 	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
@@ -70,6 +71,7 @@ struct generic_pm_domain {
 	s64 break_even_ns;	/* Power break even for the entire domain. */
 	s64 max_off_time_ns;	/* Maximum allowed "suspended" time. */
 	ktime_t power_off_time;
+	struct device_node *of_node; /* Node in device tree */
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
@@ -117,12 +119,22 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
 				 struct device *dev,
 				 struct gpd_timing_data *td);
 
+extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
+				    struct device *dev,
+				    struct gpd_timing_data *td);
+
 static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
 				      struct device *dev)
 {
 	return __pm_genpd_add_device(genpd, dev, NULL);
 }
 
+static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
+					 struct device *dev)
+{
+	return __pm_genpd_of_add_device(genpd_node, dev, NULL);
+}
+
 extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 				  struct device *dev);
 extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
#3 lore raw

PATCH v2 1/2 PM / Domains: Add OF support

Hi Rafael,

2012/1/9 Rafael J. Wysocki <[email protected]>:

Quoted 18 lines · Thomas Abraham
Quoted 17 lines

A device node pointer is added to generic pm domain structure to associate the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power domain, instantiates the available domains and initializes them by calling pm_genpd_init().

Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain.

pm_genpd_of_add_device() runs through its list of registered power domains and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the matched domain.

Quoted 8 lines
Quoted 4 lines
Cc Rafael J. Wysocki <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

I can take this patch for 3.4, but your [2/2] depends on it, so I'm not sure how to handle that. ?If you want me to take the other patch too, it'll need ACKs from the Exynos maintaniers.

Thanks. There are some comments on the [2/2] patch which I will work on. I will complete the rework and try to get the ack for the patch.

Regards,
Thomas.

Quoted 3 lines

Thanks,
Rafael

[...]

#4 lore raw

PATCH v2 1/2 PM / Domains: Add OF support

In reply to Rafael J. Wysocki
Quoted 23 lines · Rafael J. Wysocki
Quoted 1 line · Thomas Abraham

A device node pointer is added to generic pm domain structure to

associate

Quoted 2 lines

the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power

domain,

Quoted 10 lines

instantiates the available domains and initializes them by calling pm_genpd_init().

Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain.

pm_genpd_of_add_device() runs through its list of registered power

domains

Quoted 2 lines

and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the

matched

Quoted 2 lines

domain.

Quoted 9 lines
Quoted 4 lines
Cc Rafael J. Wysocki <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

I can take this patch for 3.4, but your [2/2] depends on it, so I'm not sure how to handle that. If you want me to take the other patch too, it'll need ACKs from the Exynos maintaniers.

Hi Rafael,

Basically, looks ok to me.

But it would be good if [v3 2/2] patch of this series (this patch) could be applied in samsung tree to avoid conflicts as it modifies many files. I don't want to make a trouble when sending my tree to upstream. Of course, as you said, this have a dependency with [v2 1/2]. So if you're ok, let me create topic branch will have both(1/2 and 2/2) to merge in your tree.

How do you think?

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

#5 lore raw

PATCH v2 1/2 PM / Domains: Add OF support

Quoted 37 lines · Kukjin Kim
Quoted 23 lines · Rafael J. Wysocki
Quoted 1 line · Thomas Abraham

A device node pointer is added to generic pm domain structure to

associate

Quoted 2 lines

the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power

domain,

Quoted 10 lines

instantiates the available domains and initializes them by calling pm_genpd_init().

Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain.

pm_genpd_of_add_device() runs through its list of registered power

domains

Quoted 2 lines

and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the

matched

Quoted 2 lines

domain.

Quoted 9 lines
Quoted 4 lines
Cc Rafael J. Wysocki <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

I can take this patch for 3.4, but your [2/2] depends on it, so I'm not sure how to handle that. If you want me to take the other patch too, it'll need ACKs from the Exynos maintaniers.

Hi Rafael,

Basically, looks ok to me.

Quoted 7 lines

But it would be good if [v3 2/2] patch of this series (this patch) could be applied in samsung tree to avoid conflicts as it modifies many files. I don't want to make a trouble when sending my tree to upstream. Of course, as you said, this have a dependency with [v2 1/2]. So if you're ok, let me create topic branch will have both(1/2 and 2/2) to merge in your tree.

How do you think?

That would work for me too.

Thanks,
Rafael

#6 lore raw

PATCH v2 1/2 PM / Domains: Add OF support

Quoted 45 lines · Rafael J. Wysocki
Quoted 43 lines · Kukjin Kim
Quoted 23 lines · Rafael J. Wysocki
Quoted 1 line · Thomas Abraham

A device node pointer is added to generic pm domain structure to

associate

Quoted 2 lines

the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power

domain,

Quoted 10 lines

instantiates the available domains and initializes them by calling pm_genpd_init().

Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain.

pm_genpd_of_add_device() runs through its list of registered power

domains

Quoted 2 lines

and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the

matched

Quoted 2 lines

domain.

Quoted 9 lines
Quoted 4 lines
Cc Rafael J. Wysocki <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

I can take this patch for 3.4, but your [2/2] depends on it, so I'm not sure how to handle that. If you want me to take the other patch too, it'll need ACKs from the Exynos maintaniers.

Hi Rafael,

Basically, looks ok to me.

But it would be good if [v3 2/2] patch of this series (this patch) could be applied in samsung tree to avoid conflicts as it modifies many files. I don't want to make a trouble when sending my tree to upstream. Of course, as you said, this have a dependency with [v2 1/2]. So if you're ok, let me create topic branch will have both(1/2 and 2/2) to merge in your tree.

Quoted 4 lines
Quoted 1 line

How do you think?

That would work for me too.

Hi Rafael,

I created topic branch for you with your ack.
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git v3.4-for-rafael

Please merge that in your tree and if any problems, please kindly let me know.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

#7 lore raw

PATCH v2 1/2 PM / Domains: Add OF support

Quoted 48 lines · Kukjin Kim
Quoted 47 lines · Rafael J. Wysocki
Quoted 44 lines · Kukjin Kim
Quoted 23 lines · Rafael J. Wysocki
Quoted 1 line · Thomas Abraham

A device node pointer is added to generic pm domain structure to

associate

Quoted 2 lines

the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power

domain,

Quoted 10 lines

instantiates the available domains and initializes them by calling pm_genpd_init().

Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain.

pm_genpd_of_add_device() runs through its list of registered power

domains

Quoted 2 lines

and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the

matched

Quoted 2 lines

domain.

Quoted 9 lines
Quoted 4 lines
Cc Rafael J. Wysocki <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

I can take this patch for 3.4, but your [2/2] depends on it, so I'm not sure how to handle that. If you want me to take the other patch too, it'll need ACKs from the Exynos maintaniers.

Hi Rafael,

Basically, looks ok to me.

But it would be good if [v3 2/2] patch of this series (this patch) could be applied in samsung tree to avoid conflicts as it modifies many files. I don't want to make a trouble when sending my tree to upstream. Of course, as you said, this have a dependency with [v2 1/2]. So if you're ok, let me create topic branch will have both(1/2 and 2/2) to merge in your tree.

How do you think?

Quoted 8 lines
Quoted 2 lines

That would work for me too.

Hi Rafael,

I created topic branch for you with your ack.
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git v3.4-for-rafael

Please merge that in your tree and if any problems, please kindly let me know.

Merged into linux-pm/pm-domains and into linux-pm/linux-next and pushed back.

Thanks,
Rafael

#8 lore raw

PATCH v2 2/2 ARM: Exynos: Hook up power domains to generic power domain infrastructure

In reply to Thomas Abraham

Add support for generic power domain for Exynos4 platforms and remove the Samsung specific power domain control for Exynos4.

The generic power domain infrastructure is used to control the power domains available on Exynos4. For non-dt platforms, the power domains are statically instantiated. For dt platforms, the power domain nodes found in the device tree are instantiated.

Cc Rafael J. Wysocki <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Kyungmin Park <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

---
This patch is mainly derived from Mark Brown's work on generic power domain support for s3c64xx platforms.

 arch/arm/mach-exynos/Kconfig               |   10 +--
 arch/arm/mach-exynos/Makefile              |    2 +-
 arch/arm/mach-exynos/dev-pd.c              |  139 ---------------------
 arch/arm/mach-exynos/mach-nuri.c           |   11 --
 arch/arm/mach-exynos/mach-origen.c         |   14 --
 arch/arm/mach-exynos/mach-smdkv310.c       |   12 --
 arch/arm/mach-exynos/mach-universal_c210.c |   17 ---
 arch/arm/mach-exynos/pm_domains.c          |  183 ++++++++++++++++++++++++++++
 8 files changed, 185 insertions(+), 203 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/dev-pd.c
 create mode 100644 arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/Kconfig +1 -9
index e931924..5dec134 100644
@@ -32,6 +32,7 @@ config CPU_EXYNOS4210
 	select ARM_CPU_SUSPEND if PM
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
+	select PM_GENERIC_DOMAINS
 	help
 	  Enable EXYNOS4210 CPU support
 
@@ -72,11 +73,6 @@ config EXYNOS4_SETUP_FIMD0
 	help
 	  Common setup code for FIMD0.
 
-config EXYNOS4_DEV_PD
-	bool
-	help
-	  Compile in platform device definitions for Power Domain
-
 config EXYNOS4_DEV_SYSMMU
 	bool
 	help
@@ -194,7 +190,6 @@ config MACH_SMDKV310
 	select EXYNOS4_DEV_AHCI
 	select SAMSUNG_DEV_KEYPAD
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select SAMSUNG_DEV_PWM
 	select EXYNOS4_DEV_USB_OHCI
 	select EXYNOS4_DEV_SYSMMU
@@ -243,7 +238,6 @@ config MACH_UNIVERSAL_C210
 	select S5P_DEV_ONENAND
 	select S5P_DEV_TV
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_I2C3
@@ -277,7 +271,6 @@ config MACH_NURI
 	select S5P_DEV_USB_EHCI
 	select S5P_SETUP_MIPIPHY
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_SETUP_FIMC
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
@@ -310,7 +303,6 @@ config MACH_ORIGEN
 	select SAMSUNG_DEV_BACKLIGHT
 	select SAMSUNG_DEV_PWM
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_USB_OHCI
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_SDHCI
arch/arm/mach-exynos/Makefile +1 -1
index db527ab..b7e4eca 100644
@@ -17,6 +17,7 @@ obj-$(CONFIG_ARCH_EXYNOS4)	+= irq-eint.o pmu.o
 obj-$(CONFIG_CPU_EXYNOS4210)	+= clock-exynos4210.o
 obj-$(CONFIG_SOC_EXYNOS4212)	+= clock-exynos4212.o
 obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_PM_GENERIC_DOMAINS)	+= pm_domains.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
@@ -43,7 +44,6 @@ obj-$(CONFIG_MACH_EXYNOS4_DT)		+= mach-exynos4-dt.o
 
 obj-$(CONFIG_ARCH_EXYNOS4)		+= dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI)		+= dev-ahci.o
-obj-$(CONFIG_EXYNOS4_DEV_PD)		+= dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)	+= dev-sysmmu.o
 obj-$(CONFIG_EXYNOS4_DEV_DWMCI)		+= dev-dwmci.o
 obj-$(CONFIG_EXYNOS4_DEV_DMA)		+= dma.o
arch/arm/mach-exynos/dev-pd.c deleted +0 -139

139 lines not on this page · raw message

arch/arm/mach-exynos/mach-nuri.c +0 -11
index 3df8bf4..179a992 100644
@@ -1266,9 +1266,6 @@ static struct platform_device *nuri_devices[] __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_CAM],
 	&s5p_device_fimc_md,
 
 	/* NURI Devices */
@@ -1319,14 +1316,6 @@ static void __init nuri_machine_init(void)
 
 	/* Last */
 	platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
 }
 
 MACHINE_START(NURI, "NURI")
arch/arm/mach-exynos/mach-origen.c +0 -14
index 23fc5cb..da871b9 100644
@@ -639,13 +639,6 @@ static struct platform_device *origen_devices[] __initdata = {
 	&s5p_device_mfc_r,
 	&s5p_device_mixer,
 	&exynos4_device_ohci,
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_TV],
-	&exynos4_device_pd[PD_G3D],
-	&exynos4_device_pd[PD_LCD1],
-	&exynos4_device_pd[PD_CAM],
-	&exynos4_device_pd[PD_GPS],
-	&exynos4_device_pd[PD_MFC],
 	&origen_device_gpiokeys,
 	&origen_lcd_hv070wsa,
 	&origen_device_bluetooth,
@@ -724,13 +717,6 @@ static void __init origen_machine_init(void)
 
 	platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
 
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
-
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-
 	samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data);
 
 	origen_bt_setup();
arch/arm/mach-exynos/mach-smdkv310.c +0 -12
index bf2094e..88d1a30 100644
@@ -275,13 +275,6 @@ static struct platform_device *smdkv310_devices[] __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_G3D],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_LCD1],
-	&exynos4_device_pd[PD_CAM],
-	&exynos4_device_pd[PD_TV],
-	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_spdif,
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
@@ -334,10 +327,6 @@ static void s5p_tv_setup(void)
 	WARN_ON(gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug"));
 	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
 	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-
-	/* setup dependencies between TV devices */
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
 }
 
 static void __init smdkv310_map_io(void)
@@ -377,7 +366,6 @@ static void __init smdkv310_machine_init(void)
 	clk_xusbxti.rate = 24000000;
 
 	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
arch/arm/mach-exynos/mach-universal_c210.c +0 -17
index c38e18d..28d8f02 100644
@@ -968,7 +968,6 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s3c_device_i2c5,
 	&s5p_device_i2c_hdmiphy,
 	&hdmi_fixed_voltage,
-	&exynos4_device_pd[PD_TV],
 	&s5p_device_hdmi,
 	&s5p_device_sdo,
 	&s5p_device_mixer,
@@ -981,9 +980,6 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_CAM],
 	&cam_i_core_fixed_reg_dev,
 	&cam_s_if_fixed_reg_dev,
 	&s5p_device_fimc_md,
@@ -1002,10 +998,6 @@ void s5p_tv_setup(void)
 	gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
 	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
 	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-
-	/* setup dependencies between TV devices */
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
 }
 
 static void __init universal_reserve(void)
@@ -1039,15 +1031,6 @@ static void __init universal_machine_init(void)
 
 	/* Last */
 	platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
-
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
 }
 
 MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
arch/arm/mach-exynos/pm_domains.c new file +183 -0

183 lines not on this page · raw message

Signature · 1 line
1.6.6.rc2
#9 lore raw

PATCH v2 2/2 ARM: Exynos: Hook up power domains to generic power domain infrastructure

Hi Thomas,

thank you for working on this. I have a few comments below..

Quoted 42 lines · Thomas Abraham

Add support for generic power domain for Exynos4 platforms and remove the Samsung specific power domain control for Exynos4.

The generic power domain infrastructure is used to control the power domains available on Exynos4. For non-dt platforms, the power domains are statically instantiated. For dt platforms, the power domain nodes found in the device tree are instantiated.

Cc Rafael J. Wysocki<[email protected]>
Cc Kukjin Kim<[email protected]>
Cc Kyungmin Park<[email protected]>
Cc Rob Herring<[email protected]>
Cc Grant Likely<[email protected]>

---
This patch is mainly derived from Mark Brown's work on generic power domain support for s3c64xx platforms.

  arch/arm/mach-exynos/Kconfig               |   10 +--
  arch/arm/mach-exynos/Makefile              |    2 +-
  arch/arm/mach-exynos/dev-pd.c              |  139 ---------------------
  arch/arm/mach-exynos/mach-nuri.c           |   11 --
  arch/arm/mach-exynos/mach-origen.c         |   14 --
  arch/arm/mach-exynos/mach-smdkv310.c       |   12 --
  arch/arm/mach-exynos/mach-universal_c210.c |   17 ---
  arch/arm/mach-exynos/pm_domains.c          |  183 ++++++++++++++++++++++++++++
  8 files changed, 185 insertions(+), 203 deletions(-)

delete mode 100644 arch/arm/mach-exynos/dev-pd.c create mode 100644 arch/arm/mach-exynos/pm_domains.c

arch/arm/mach-exynos/Kconfig +1 -0
index e931924..5dec134 100644
@@ -32,6 +32,7 @@ config CPU_EXYNOS4210
  	select ARM_CPU_SUSPEND if PM
  	select S5P_PM if PM
  	select S5P_SLEEP if PM
+	select PM_GENERIC_DOMAINS
  	help
  	  Enable EXYNOS4210 CPU support
 

...

arch/arm/mach-exynos/pm_domains.c line 4

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +4 -0
new file mode 100644
index 0000000..95a7c55
@@ -0,0 +1,183 @@
+/*
+ * Exynos4 Generic power domain support.
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.

2012 ?

Quoted 32 lines
arch/arm/mach-exynos/pm_domains.c new file +32 -0
+ *		http://www.samsung.com
+ *
+ * Implementation of Exynos4 specific power domain control which is used in
+ * conjunction with runtime-pm. Support for both device-tree and non-device-tree
+ * based power domain support is included.
+ *
+ * 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.
+*/
+
+#include<linux/io.h>
+#include<linux/err.h>
+#include<linux/slab.h>
+#include<linux/pm_domain.h>
+#include<linux/delay.h>
+#include<linux/of_address.h>
+
+#include<mach/regs-pmu.h>
+#include<plat/devs.h>
+
+/*
+ * Exynos4 specific wrapper around the generic power domain
+ */
+struct exynos4_pm_domain {
+	void __iomem *base;
+	char const *name;
+	bool is_off;
+	struct generic_pm_domain pd;
+};
+
+static int exynos4_pd_power(struct generic_pm_domain *domain, bool power_on)

arch/arm/mach-exynos/pm_domains.c line 46

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+{
+	struct exynos4_pm_domain *pd;
+	void __iomem *base;
+	u32 timeout, pwr;
+	char *op;
+
+	pd = container_of(domain, struct exynos4_pm_domain, pd);
+	base = pd->base;
+
+	pwr = (power_on) ? S5P_INT_LOCAL_PWR_EN : 0;

Is there any value in parentheses around 'power_on' ?

arch/arm/mach-exynos/pm_domains.c line 55

Quoted 9 lines
arch/arm/mach-exynos/pm_domains.c new file +9 -0
+	__raw_writel(pwr, base);
+
+	/* Wait max 1ms */
+	timeout = 10;
+
+	while ((__raw_readl(base + 0x4)&  S5P_INT_LOCAL_PWR_EN)	!= pwr) {
+		if (!timeout) {
+			op = (power_on) ? "enable" : "disable";
+			pr_err("Power domain %s %s failed\n", op, domain->name);

How about just:
pr_err("%s power domain state change (%d) failed\n",
domain->name, power_on);
?

arch/arm/mach-exynos/pm_domains.c line 59

Quoted 4 lines
arch/arm/mach-exynos/pm_domains.c new file +4 -0
+			return -ETIMEDOUT;
+		}
+		timeout--;
+		cpu_relax();

Does cpu_relax() make any difference here ?

Quoted 50 lines
arch/arm/mach-exynos/pm_domains.c new file +50 -0
+		usleep_range(80, 100);
+	}
+	return 0;
+}
+
+static int exynos4_pd_power_on(struct generic_pm_domain *domain)
+{
+	return exynos4_pd_power(domain, true);
+}
+
+static int exynos4_pd_power_off(struct generic_pm_domain *domain)
+{
+	return exynos4_pd_power(domain, false);
+}
+
+
+#define EXYNOS4_GPD(PD, BASE, NAME)			\
+static struct exynos4_pm_domain PD = {			\
+	.base = (void __iomem *)BASE,			\
+	.name = NAME,					\
+	.pd = {						\
+		.power_off = exynos4_pd_power_off,	\
+		.power_on = exynos4_pd_power_on,	\
+	},						\
+}
+
+EXYNOS4_GPD(exynos4_pd_mfc, S5P_PMU_MFC_CONF, "pd-mfc");
+EXYNOS4_GPD(exynos4_pd_g3d, S5P_PMU_G3D_CONF, "pd-g3d");
+EXYNOS4_GPD(exynos4_pd_lcd0, S5P_PMU_LCD0_CONF, "pd-lcd0");
+EXYNOS4_GPD(exynos4_pd_lcd1, S5P_PMU_LCD1_CONF, "pd-lcd1");
+EXYNOS4_GPD(exynos4_pd_tv, S5P_PMU_TV_CONF, "pd-tv");
+EXYNOS4_GPD(exynos4_pd_cam, S5P_PMU_CAM_CONF, "pd-cam");
+EXYNOS4_GPD(exynos4_pd_gps, S5P_PMU_GPS_CONF, "pd-gps");
+
+static struct exynos4_pm_domain *exynos4_pm_domains[] = {
+	&exynos4_pd_mfc,
+	&exynos4_pd_g3d,
+	&exynos4_pd_lcd0,
+	&exynos4_pd_lcd1,
+	&exynos4_pd_tv,
+	&exynos4_pd_cam,
+	&exynos4_pd_gps,
+};
+
+static __init int exynos4_pm_init_power_domain(void)
+{
+	int idx;
+	struct device_node *np;
+
+#ifdef CONFIG_OF

arch/arm/mach-exynos/pm_domains.c line 119

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+	if (!of_have_populated_dt())
+		goto no_dt;
+
+	for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+		struct exynos4_pm_domain *pd;
+
+		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+		if (!pd) {
+			pr_err("exynos4_pm_init_power_domain: failed to "
+					"allocate memory for domain\n");

nit: what about:

			pr_err("%s: failed to allocate memory for domain\n",
				__func__);

?

Quoted 44 lines
arch/arm/mach-exynos/pm_domains.c new file +44 -0
+			return -ENOMEM;
+		}
+
+		if (of_get_property(np, "samsung,exynos4210-pd-off", NULL))
+			pd->is_off = true;
+		pd->name = np->name;
+		pd->base = of_iomap(np, 0);
+		pd->pd.power_off = exynos4_pd_power_off;
+		pd->pd.power_on = exynos4_pd_power_on;
+		pd->pd.of_node = np;
+		pm_genpd_init(&pd->pd, NULL, false);
+	}
+	return 0;
+#endif /* CONFIG_OF */
+
+ no_dt:
+	for (idx = 0; idx<  ARRAY_SIZE(exynos4_pm_domains); idx++)
+		pm_genpd_init(&exynos4_pm_domains[idx]->pd, NULL,
+				exynos4_pm_domains[idx]->is_off);
+
+#ifdef CONFIG_S5P_DEV_FIMD0
+	if (pm_genpd_add_device(&exynos4_pd_lcd0.pd,&s5p_device_fimd0.dev))
+		pr_info("error in adding fimd0 to lcd0 power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_TV
+	if (pm_genpd_add_device(&exynos4_pd_tv.pd,&s5p_device_hdmi.dev))
+		pr_info("error in adding hdmi to tv power domain\n");
+	if (pm_genpd_add_device(&exynos4_pd_tv.pd,&s5p_device_mixer.dev))
+		pr_info("error in adding mixer to tv power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_MFC
+	if (pm_genpd_add_device(&exynos4_pd_mfc.pd,&s5p_device_mfc.dev))
+		pr_info("error in adding mfc to mfc power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC0
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd,&s5p_device_fimc0.dev))
+		pr_info("error in adding fimc0 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC1
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd,&s5p_device_fimc1.dev))
+		pr_info("error in adding fimc1 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC2
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd,&s5p_device_fimc2.dev))

arch/arm/mach-exynos/pm_domains.c line 173

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+		pr_info("error in adding fimc2 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC3
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd,&s5p_device_fimc3.dev))
+		pr_info("error in adding fimc3 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_CSIS0
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd,&s5p_device_mipi_csis0.dev))
+		pr_info("error in adding csis0 to cam power domain\n");
+#endif

Could you add CSIS1 as well ? Some boards will be using both MIPI-CSI receivers.

arch/arm/mach-exynos/pm_domains.c line 183

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+	return 0;
+}
+arch_initcall(exynos4_pm_init_power_domain);
+
+static __init int exynos4_pm_late_initcall(void)
+{
+	pm_genpd_poweroff_unused();
+	return 0;
+}
+late_initcall(exynos4_pm_late_initcall);

--

Regards,
Sylwester

#10 lore raw

PATCH v2 2/2 ARM: Exynos: Hook up power domains to generic power domain infrastructure

Hi Sylwester.

On 7 January 2012 20:14, Sylwester Nawrocki <[email protected]> wrote:
[...]

Quoted 4 lines
Quoted 4 lines
arch/arm/mach-exynos/pm_domains.c new file +0 -1
new file mode 100644
index 0000000..95a7c55
--- /dev/null
Quoted 8 lines

arch/arm/mach-exynos/pm_domains.c line 4

Quoted 6 lines

+++ b/arch/arm/mach-exynos/pm_domains.c

arch/arm/mach-exynos/pm_domains.c new file +4 -0
@@ -0,0 +1,183 @@
+/*
+ * Exynos4 Generic power domain support.
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.

2012 ?

Ok. I will change this.

Quoted 2 lines
Quoted 2 lines
arch/arm/mach-exynos/pm_domains.c new file +1 -0
+ * ? ? ? ? ? http://www.samsung.com

[...]

Quoted 5 lines
Quoted 5 lines
arch/arm/mach-exynos/pm_domains.c new file +5 -0
+static int exynos4_pd_power(struct generic_pm_domain *domain, bool power_on)
+{
+ ? ? struct exynos4_pm_domain *pd;
+ ? ? void __iomem *base;
+ ? ? u32 timeout, pwr;
Quoted 8 lines

arch/arm/mach-exynos/pm_domains.c

Quoted 6 lines

+ ? ? char *op;

arch/arm/mach-exynos/pm_domains.c new file +5 -0
+
+ ? ? pd = container_of(domain, struct exynos4_pm_domain, pd);
+ ? ? base = pd->base;
+
+ ? ? pwr = (power_on) ? S5P_INT_LOCAL_PWR_EN : 0;

Is there any value in parentheses around 'power_on' ?

No. I will remove the parentheses around 'power_on'.

Quoted 16 lines

arch/arm/mach-exynos/pm_domains.c

Quoted 10 lines

+ ? ? __raw_writel(pwr, base);

arch/arm/mach-exynos/pm_domains.c new file +8 -0
+
+ ? ? /* Wait max 1ms */
+ ? ? timeout = 10;
+
+ ? ? while ((__raw_readl(base + 0x4)& ?S5P_INT_LOCAL_PWR_EN) != pwr) {
+ ? ? ? ? ? ? if (!timeout) {
+ ? ? ? ? ? ? ? ? ? ? op = (power_on) ? "enable" : "disable";
+ ? ? ? ? ? ? ? ? ? ? pr_err("Power domain %s %s failed\n", op, domain->name);

How about just:
? ? ? pr_err("%s power domain state change (%d) failed\n", ? ? ? ? ? ? ?domain->name, power_on);
?

Quoted 1 line

From the message it will not be clear which state change failed. The

state (enable/disable) would be helpful.

Quoted 6 lines
Quoted 4 lines

+ ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
+ ? ? ? ? ? ? }
+ ? ? ? ? ? ? timeout--;
+ ? ? ? ? ? ? cpu_relax();

Does cpu_relax() make any difference here ?

I need to check on this.

Quoted 6 lines
Quoted 6 lines

+ ? ? ? ? ? ? usleep_range(80, 100);
+ ? ? }
+ ? ? return 0;

arch/arm/mach-exynos/pm_domains.c new file +2 -0
+}
+

[...]

Quoted 9 lines
Quoted 4 lines

+ ? ? ? ? ? ? pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ ? ? ? ? ? ? if (!pd) {
+ ? ? ? ? ? ? ? ? ? ? pr_err("exynos4_pm_init_power_domain: failed to "
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "allocate memory for domain\n");

nit: what about:
? ? ? ? ? ? ? ? ? ? ? ?pr_err("%s: failed to allocate memory for domain\n", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__func__);
?

Yes. This is better. I will change this.

Quoted 3 lines
Quoted 3 lines

+ ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
+ ? ? ? ? ? ? }
+

[...]

Quoted 6 lines

arch/arm/mach-exynos/pm_domains.c line 173

Quoted 4 lines
arch/arm/mach-exynos/pm_domains.c new file +4 -0
+#ifdef CONFIG_S5P_DEV_CSIS0
+ ? ? if (pm_genpd_add_device(&exynos4_pd_cam.pd,&s5p_device_mipi_csis0.dev))
+ ? ? ? ? ? ? pr_info("error in adding csis0 to cam power domain\n");
+#endif

Could you add CSIS1 as well ? Some boards will be using both MIPI-CSI receivers.

Ok. I will add CSIS1 here.

Thanks for your review.

Regards,
Thomas.

[...]

#11 lore raw

PATCH v2 2/2 ARM: Exynos: Hook up power domains to generic power domain infrastructure

In reply to Thomas Abraham
Quoted 440 lines · Thomas Abraham

Add support for generic power domain for Exynos4 platforms and remove the Samsung specific power domain control for Exynos4.

The generic power domain infrastructure is used to control the power domains available on Exynos4. For non-dt platforms, the power domains are statically instantiated. For dt platforms, the power domain nodes found in the device tree are instantiated.

Cc Rafael J. Wysocki <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Kyungmin Park <[email protected]>
Cc Rob Herring <[email protected]>
Cc Grant Likely <[email protected]>

---
This patch is mainly derived from Mark Brown's work on generic power domain support for s3c64xx platforms.

 arch/arm/mach-exynos/Kconfig               |   10 +--
 arch/arm/mach-exynos/Makefile              |    2 +-
 arch/arm/mach-exynos/dev-pd.c              |  139 ---------------------
 arch/arm/mach-exynos/mach-nuri.c           |   11 --
 arch/arm/mach-exynos/mach-origen.c         |   14 --
 arch/arm/mach-exynos/mach-smdkv310.c       |   12 --
 arch/arm/mach-exynos/mach-universal_c210.c |   17 ---
 arch/arm/mach-exynos/pm_domains.c          |  183
++++++++++++++++++++++++++++
 8 files changed, 185 insertions(+), 203 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/dev-pd.c
 create mode 100644 arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/Kconfig +1 -9
index e931924..5dec134 100644
@@ -32,6 +32,7 @@ config CPU_EXYNOS4210
 	select ARM_CPU_SUSPEND if PM
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
+	select PM_GENERIC_DOMAINS
 	help
 	  Enable EXYNOS4210 CPU support
 
@@ -72,11 +73,6 @@ config EXYNOS4_SETUP_FIMD0
 	help
 	  Common setup code for FIMD0.
 
-config EXYNOS4_DEV_PD
-	bool
-	help
-	  Compile in platform device definitions for Power Domain
-
 config EXYNOS4_DEV_SYSMMU
 	bool
 	help
@@ -194,7 +190,6 @@ config MACH_SMDKV310
 	select EXYNOS4_DEV_AHCI
 	select SAMSUNG_DEV_KEYPAD
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select SAMSUNG_DEV_PWM
 	select EXYNOS4_DEV_USB_OHCI
 	select EXYNOS4_DEV_SYSMMU
@@ -243,7 +238,6 @@ config MACH_UNIVERSAL_C210
 	select S5P_DEV_ONENAND
 	select S5P_DEV_TV
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_I2C3
@@ -277,7 +271,6 @@ config MACH_NURI
 	select S5P_DEV_USB_EHCI
 	select S5P_SETUP_MIPIPHY
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_SETUP_FIMC
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
@@ -310,7 +303,6 @@ config MACH_ORIGEN
 	select SAMSUNG_DEV_BACKLIGHT
 	select SAMSUNG_DEV_PWM
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_USB_OHCI
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_SDHCI
arch/arm/mach-exynos/Makefile +1 -1
index db527ab..b7e4eca 100644
@@ -17,6 +17,7 @@ obj-$(CONFIG_ARCH_EXYNOS4)	+= irq-eint.o pmu.o
 obj-$(CONFIG_CPU_EXYNOS4210)	+= clock-exynos4210.o
 obj-$(CONFIG_SOC_EXYNOS4212)	+= clock-exynos4212.o
 obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_PM_GENERIC_DOMAINS)	+= pm_domains.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
@@ -43,7 +44,6 @@ obj-$(CONFIG_MACH_EXYNOS4_DT)		+= mach-exynos4-dt.o
 
 obj-$(CONFIG_ARCH_EXYNOS4)		+= dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI)		+= dev-ahci.o
-obj-$(CONFIG_EXYNOS4_DEV_PD)		+= dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)	+= dev-sysmmu.o
 obj-$(CONFIG_EXYNOS4_DEV_DWMCI)		+= dev-dwmci.o
 obj-$(CONFIG_EXYNOS4_DEV_DMA)		+= dma.o
arch/arm/mach-exynos/dev-pd.c deleted +0 -139
deleted file mode 100644
index 3273f25..0000000
@@ -1,139 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-pd.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4 - Power Domain support
- *
- * 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.
-*/
-
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-
-#include <mach/regs-pmu.h>
-
-#include <plat/pd.h>
-
-static int exynos4_pd_enable(struct device *dev)
-{
-	struct samsung_pd_info *pdata =  dev->platform_data;
-	u32 timeout;
-
-	__raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
-
-	/* Wait max 1ms */
-	timeout = 10;
-	while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
-		!= S5P_INT_LOCAL_PWR_EN) {
-		if (timeout == 0) {
-			printk(KERN_ERR "Power domain %s enable failed.\n",
-				dev_name(dev));
-			return -ETIMEDOUT;
-		}
-		timeout--;
-		udelay(100);
-	}
-
-	return 0;
-}
-
-static int exynos4_pd_disable(struct device *dev)
-{
-	struct samsung_pd_info *pdata =  dev->platform_data;
-	u32 timeout;
-
-	__raw_writel(0, pdata->base);
-
-	/* Wait max 1ms */
-	timeout = 10;
-	while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
-		if (timeout == 0) {
-			printk(KERN_ERR "Power domain %s disable failed.\n",
-				dev_name(dev));
-			return -ETIMEDOUT;
-		}
-		timeout--;
-		udelay(100);
-	}
-
-	return 0;
-}
-
-struct platform_device exynos4_device_pd[] = {
-	{
-		.name		= "samsung-pd",
-		.id		= 0,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_MFC_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 1,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_G3D_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 2,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_LCD0_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 3,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_LCD1_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 4,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_TV_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 5,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_CAM_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 6,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_GPS_CONF,
-			},
-		},
-	},
-};
arch/arm/mach-exynos/mach-nuri.c +0 -3
index 3df8bf4..179a992 100644
@@ -1266,9 +1266,6 @@ static struct platform_device *nuri_devices[]
 __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_CAM],
 	&s5p_device_fimc_md,
 
arch/arm/mach-exynos/mach-nuri.c +0 -8
 	/* NURI Devices */
@@ -1319,14 +1316,6 @@ static void __init nuri_machine_init(void)
 
 	/* Last */
 	platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
 }
 
 MACHINE_START(NURI, "NURI")
arch/arm/mach-exynos/mach-origen.c +0 -7
index 23fc5cb..da871b9 100644
@@ -639,13 +639,6 @@ static struct platform_device *origen_devices[]
 __initdata = {
 	&s5p_device_mfc_r,
 	&s5p_device_mixer,
 	&exynos4_device_ohci,
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_TV],
-	&exynos4_device_pd[PD_G3D],
-	&exynos4_device_pd[PD_LCD1],
-	&exynos4_device_pd[PD_CAM],
-	&exynos4_device_pd[PD_GPS],
-	&exynos4_device_pd[PD_MFC],
 	&origen_device_gpiokeys,
 	&origen_lcd_hv070wsa,
arch/arm/mach-exynos/mach-origen.c +0 -7
 	&origen_device_bluetooth,
@@ -724,13 +717,6 @@ static void __init origen_machine_init(void)
 
 	platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
 
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
-
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-
 	samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data);
 
 	origen_bt_setup();
arch/arm/mach-exynos/mach-smdkv310.c +0 -7
index bf2094e..88d1a30 100644
@@ -275,13 +275,6 @@ static struct platform_device *smdkv310_devices[]
 __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_G3D],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_LCD1],
-	&exynos4_device_pd[PD_CAM],
-	&exynos4_device_pd[PD_TV],
-	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_spdif,
 	&exynos4_device_sysmmu,
arch/arm/mach-exynos/mach-smdkv310.c +0 -5
 	&samsung_asoc_dma,
@@ -334,10 +327,6 @@ static void s5p_tv_setup(void)
 	WARN_ON(gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug"));
 	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
 	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-
-	/* setup dependencies between TV devices */
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
 }
 
 static void __init smdkv310_map_io(void)
@@ -377,7 +366,6 @@ static void __init smdkv310_machine_init(void)
 	clk_xusbxti.rate = 24000000;
 
 	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
arch/arm/mach-exynos/mach-universal_c210.c +0 -1
index c38e18d..28d8f02 100644
@@ -968,7 +968,6 @@ static struct platform_device *universal_devices[]
 __initdata = {
 	&s3c_device_i2c5,
 	&s5p_device_i2c_hdmiphy,
 	&hdmi_fixed_voltage,
-	&exynos4_device_pd[PD_TV],
 	&s5p_device_hdmi,
 	&s5p_device_sdo,
arch/arm/mach-exynos/mach-universal_c210.c +0 -3
 	&s5p_device_mixer,
@@ -981,9 +980,6 @@ static struct platform_device *universal_devices[]
 __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_CAM],
 	&cam_i_core_fixed_reg_dev,
 	&cam_s_if_fixed_reg_dev,
arch/arm/mach-exynos/mach-universal_c210.c +0 -13
 	&s5p_device_fimc_md,
@@ -1002,10 +998,6 @@ void s5p_tv_setup(void)
 	gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
 	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
 	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-
-	/* setup dependencies between TV devices */
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
 }
 
 static void __init universal_reserve(void)
@@ -1039,15 +1031,6 @@ static void __init universal_machine_init(void)
 
 	/* Last */
 	platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
-
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
 }
 
 MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
arch/arm/mach-exynos/pm_domains.c new file +8 -0
new file mode 100644
index 0000000..95a7c55
@@ -0,0 +1,183 @@
+/*
+ * Exynos4 Generic power domain support.
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Implementation of Exynos4 specific power domain control which is used in
+ * conjunction with runtime-pm. Support for both device-tree and

non-device-tree
+ * based power domain support is included.
+ *
+ * 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.

arch/arm/mach-exynos/pm_domains.c new file +11 -0
+*/
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/pm_domain.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+
+#include <mach/regs-pmu.h>
+#include <plat/devs.h>

arch/arm/mach-exynos/pm_domains.c line 34

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+
+/*
+ * Exynos4 specific wrapper around the generic power domain
+ */
+struct exynos4_pm_domain {
+	void __iomem *base;
+	char const *name;
+	bool is_off;
+	struct generic_pm_domain pd;
+};

Even though you tested it at exynos4, we already know exynos5 will be used soon. so start to use the exynos prefix if possible.

Quoted 3 lines
arch/arm/mach-exynos/pm_domains.c new file +2 -0
+
+static int exynos4_pd_power(struct generic_pm_domain *domain, bool

power_on)

exynos_pd_power

Quoted 27 lines
arch/arm/mach-exynos/pm_domains.c new file +27 -0
+{
+	struct exynos4_pm_domain *pd;
+	void __iomem *base;
+	u32 timeout, pwr;
+	char *op;
+
+	pd = container_of(domain, struct exynos4_pm_domain, pd);
+	base = pd->base;
+
+	pwr = (power_on) ? S5P_INT_LOCAL_PWR_EN : 0;
+	__raw_writel(pwr, base);
+
+	/* Wait max 1ms */
+	timeout = 10;
+
+	while ((__raw_readl(base + 0x4) & S5P_INT_LOCAL_PWR_EN)	!= pwr) {
+		if (!timeout) {
+			op = (power_on) ? "enable" : "disable";
+			pr_err("Power domain %s %s failed\n", op, domain->name);
+			return -ETIMEDOUT;
+		}
+		timeout--;
+		cpu_relax();
+		usleep_range(80, 100);
+	}
+	return 0;
+}

arch/arm/mach-exynos/pm_domains.c line 73

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+
+static int exynos4_pd_power_on(struct generic_pm_domain *domain)
+{
+	return exynos4_pd_power(domain, true);
+}
+
+static int exynos4_pd_power_off(struct generic_pm_domain *domain)
+{
+	return exynos4_pd_power(domain, false);
+}

ditto

arch/arm/mach-exynos/pm_domains.c line 86

Quoted 13 lines
arch/arm/mach-exynos/pm_domains.c new file +13 -0
+
+
+#define EXYNOS4_GPD(PD, BASE, NAME)			\
+static struct exynos4_pm_domain PD = {			\
+	.base = (void __iomem *)BASE,			\
+	.name = NAME,					\
+	.pd = {						\
+		.power_off = exynos4_pd_power_off,	\
+		.power_on = exynos4_pd_power_on,	\
+	},						\
+}
+
+EXYNOS4_GPD(exynos4_pd_mfc, S5P_PMU_MFC_CONF, "pd-mfc");

In this case, it's right to use the exynos4_pd_* as you wrote.

arch/arm/mach-exynos/pm_domains.c line 89

Quoted 3 lines
arch/arm/mach-exynos/pm_domains.c new file +3 -0
+EXYNOS4_GPD(exynos4_pd_g3d, S5P_PMU_G3D_CONF, "pd-g3d");
+EXYNOS4_GPD(exynos4_pd_lcd0, S5P_PMU_LCD0_CONF, "pd-lcd0");
+EXYNOS4_GPD(exynos4_pd_lcd1, S5P_PMU_LCD1_CONF, "pd-lcd1");

As you know, it's exynos4 series only now.

Quoted 8 lines
arch/arm/mach-exynos/pm_domains.c new file +8 -0
+EXYNOS4_GPD(exynos4_pd_tv, S5P_PMU_TV_CONF, "pd-tv");
+EXYNOS4_GPD(exynos4_pd_cam, S5P_PMU_CAM_CONF, "pd-cam");
+EXYNOS4_GPD(exynos4_pd_gps, S5P_PMU_GPS_CONF, "pd-gps");
+
+static struct exynos4_pm_domain *exynos4_pm_domains[] = {
+	&exynos4_pd_mfc,
+	&exynos4_pd_g3d,
+	&exynos4_pd_lcd0,

arch/arm/mach-exynos/pm_domains.c line 107

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+	&exynos4_pd_lcd1,
+	&exynos4_pd_tv,
+	&exynos4_pd_cam,
+	&exynos4_pd_gps,
+};
+
+static __init int exynos4_pm_init_power_domain(void)
+{
+	int idx;
+	struct device_node *np;

The np is only used at CONFIG_ON.

Quoted 18 lines
arch/arm/mach-exynos/pm_domains.c new file +18 -0
+
+#ifdef CONFIG_OF
+	if (!of_have_populated_dt())
+		goto no_dt;
+
+	for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+		struct exynos4_pm_domain *pd;
+
+		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+		if (!pd) {
+			pr_err("exynos4_pm_init_power_domain: failed to "
+					"allocate memory for domain\n");
+			return -ENOMEM;
+		}
+
+		if (of_get_property(np, "samsung,exynos4210-pd-off", NULL))
+			pd->is_off = true;
+		pd->name = np->name;

arch/arm/mach-exynos/pm_domains.c line 135

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+		pd->base = of_iomap(np, 0);
+		pd->pd.power_off = exynos4_pd_power_off;
+		pd->pd.power_on = exynos4_pd_power_on;
+		pd->pd.of_node = np;
+		pm_genpd_init(&pd->pd, NULL, false);
+	}
+	return 0;
+#endif /* CONFIG_OF */
+
+ no_dt:

You should add the "#endif /* CONFIG_OF */ since no_dt is used at CONFIG_OF case.

Quoted 28 lines
arch/arm/mach-exynos/pm_domains.c new file +28 -0
+	for (idx = 0; idx < ARRAY_SIZE(exynos4_pm_domains); idx++)
+		pm_genpd_init(&exynos4_pm_domains[idx]->pd, NULL,
+				exynos4_pm_domains[idx]->is_off);
+
+#ifdef CONFIG_S5P_DEV_FIMD0
+	if (pm_genpd_add_device(&exynos4_pd_lcd0.pd, &s5p_device_fimd0.dev))
+		pr_info("error in adding fimd0 to lcd0 power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_TV
+	if (pm_genpd_add_device(&exynos4_pd_tv.pd, &s5p_device_hdmi.dev))
+		pr_info("error in adding hdmi to tv power domain\n");
+	if (pm_genpd_add_device(&exynos4_pd_tv.pd, &s5p_device_mixer.dev))
+		pr_info("error in adding mixer to tv power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_MFC
+	if (pm_genpd_add_device(&exynos4_pd_mfc.pd, &s5p_device_mfc.dev))
+		pr_info("error in adding mfc to mfc power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC0
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd, &s5p_device_fimc0.dev))
+		pr_info("error in adding fimc0 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC1
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd, &s5p_device_fimc1.dev))
+		pr_info("error in adding fimc1 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC2
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd, &s5p_device_fimc2.dev))

arch/arm/mach-exynos/pm_domains.c line 173

Quoted 10 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -0
+		pr_info("error in adding fimc2 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC3
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd, &s5p_device_fimc3.dev))
+		pr_info("error in adding fimc3 to cam power domain\n");
+#endif
+#ifdef CONFIG_S5P_DEV_CSIS0
+	if (pm_genpd_add_device(&exynos4_pd_cam.pd, &s5p_device_mipi_csis0.dev))
+		pr_info("error in adding csis0 to cam power domain\n");
+#endif

Also need to add CSIS1 as Sylwester mentioned.

Quoted 19 lines
arch/arm/mach-exynos/pm_domains.c new file +10 -1
+	return 0;
+}
+arch_initcall(exynos4_pm_init_power_domain);
+
+static __init int exynos4_pm_late_initcall(void)
+{
+	pm_genpd_poweroff_unused();
+	return 0;
+}
+late_initcall(exynos4_pm_late_initcall);
--

1.6.6.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#12 lore raw

PATCH v2 2/2 ARM: Exynos: Hook up power domains to generic power domain infrastructure

Dear Mr. Park.

On 9 January 2012 05:57, Kyungmin Park <[email protected]> wrote:
[...]

Quoted 10 lines

Review

Quoted 8 lines

+ * Exynos4 specific wrapper around the generic power domain
+ */

(quoted diff) +6 -0
+struct exynos4_pm_domain {
+ ? ? void __iomem *base;
+ ? ? char const *name;
+ ? ? bool is_off;
+ ? ? struct generic_pm_domain pd;
+};

Even though you tested it at exynos4, we already know exynos5 will be used soon. so start to use the exynos prefix if possible.

Ok. I will change exynos4 to exynos.

[...]

Quoted 6 lines

arch/arm/mach-exynos/pm_domains.c

Quoted 5 lines
arch/arm/mach-exynos/pm_domains.c new file +5 -0
+
+static __init int exynos4_pm_init_power_domain(void)
+{
+ ? ? int idx;
+ ? ? struct device_node *np;

The np is only used at CONFIG_ON.

Ok. I will rework this.

Quoted 22 lines
Quoted 22 lines
(quoted diff) +22 -0
+
+#ifdef CONFIG_OF
+ ? ? if (!of_have_populated_dt())
+ ? ? ? ? ? ? goto no_dt;
+
+ ? ? for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+ ? ? ? ? ? ? struct exynos4_pm_domain *pd;
+
+ ? ? ? ? ? ? pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ ? ? ? ? ? ? if (!pd) {
+ ? ? ? ? ? ? ? ? ? ? pr_err("exynos4_pm_init_power_domain: failed to "
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "allocate memory for domain\n");
+ ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
+ ? ? ? ? ? ? }
+
+ ? ? ? ? ? ? if (of_get_property(np, "samsung,exynos4210-pd-off", NULL))
+ ? ? ? ? ? ? ? ? ? ? pd->is_off = true;
+ ? ? ? ? ? ? pd->name = np->name;
+ ? ? ? ? ? ? pd->base = of_iomap(np, 0);
+ ? ? ? ? ? ? pd->pd.power_off = exynos4_pd_power_off;
+ ? ? ? ? ? ? pd->pd.power_on = exynos4_pd_power_on;
+ ? ? ? ? ? ? pd->pd.of_node = np;
Quoted 8 lines

arch/arm/mach-exynos/pm_domains.c line 135

Quoted 6 lines

+ ? ? ? ? ? ? pm_genpd_init(&pd->pd, NULL, false);
+ ? ? }
+ ? ? return 0;

arch/arm/mach-exynos/pm_domains.c new file +3 -0
+#endif /* CONFIG_OF */
+
+ no_dt:

You should add the "#endif /* CONFIG_OF */ since no_dt is used at CONFIG_OF case.

Ok.

Quoted 4 lines
Quoted 4 lines

+ ? ? for (idx = 0; idx < ARRAY_SIZE(exynos4_pm_domains); idx++)
+ ? ? ? ? ? ? pm_genpd_init(&exynos4_pm_domains[idx]->pd, NULL,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? exynos4_pm_domains[idx]->is_off); +

[...]

Quoted 5 lines

arch/arm/mach-exynos/pm_domains.c line 173

Quoted 4 lines
arch/arm/mach-exynos/pm_domains.c new file +4 -0
+#ifdef CONFIG_S5P_DEV_CSIS0
+ ? ? if (pm_genpd_add_device(&exynos4_pd_cam.pd, &s5p_device_mipi_csis0.dev))
+ ? ? ? ? ? ? pr_info("error in adding csis0 to cam power domain\n");
+#endif

Also need to add CSIS1 as Sylwester mentioned.

Ok. I will add CSIS1.

Thanks for your review.

Regards,
Thomas.