ARM: EXYNOS: Hook up power domains to generic power domain infrastructure
authorThomas Abraham <thomas.abraham@linaro.org>
Fri, 27 Jan 2012 06:25:00 +0000 (15:25 +0900)
committerKukjin Kim <kgene.kim@samsung.com>
Fri, 27 Jan 2012 06:25:49 +0000 (15:25 +0900)
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: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Documentation/devicetree/bindings/arm/exynos/power_domain.txt [new file with mode: 0644]
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/Makefile
arch/arm/mach-exynos/dev-pd.c [deleted file]
arch/arm/mach-exynos/mach-nuri.c
arch/arm/mach-exynos/mach-origen.c
arch/arm/mach-exynos/mach-smdkv310.c
arch/arm/mach-exynos/mach-universal_c210.c
arch/arm/mach-exynos/pm_domains.c [new file with mode: 0644]

diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
new file mode 100644 (file)
index 0000000..6528e21
--- /dev/null
@@ -0,0 +1,21 @@
+* Samsung Exynos Power Domains
+
+Exynos processors include support for multiple power domains which are used
+to gate power to one or more peripherals on the processor.
+
+Required Properties:
+- compatiable: should be one of the following.
+    * samsung,exynos4210-pd - for exynos4210 type power domain.
+- reg: physical base address of the controller and length of memory mapped
+    region.
+
+Optional Properties:
+- samsung,exynos4210-pd-off: Specifies that the power domain is in turned-off
+    state during boot and remains to be turned-off until explicitly turned-on.
+
+Example:
+
+       lcd0: power-domain-lcd0 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10023C00 0x10>;
+       };
index 5d602f68a0e88735d5cee2bf0e2b7f3da4fc95f2..dfad6538b2737f5acdc4c2644342627d2d6010f2 100644 (file)
@@ -34,6 +34,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
 
@@ -74,11 +75,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
@@ -195,7 +191,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
index 5fc202cdfdb668483a227f1348dd12be77cf7f40..d9191f9a7af8560c69d60f39a703e687cd9bfca6 100644 (file)
@@ -17,6 +17,7 @@ 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_ARCH_EXYNOS4)     += pmu.o
@@ -45,7 +46,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
diff --git a/arch/arm/mach-exynos/dev-pd.c b/arch/arm/mach-exynos/dev-pd.c
deleted file mode 100644 (file)
index 3273f25..0000000
+++ /dev/null
@@ -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,
-                       },
-               },
-       },
-};
index b895ec0311057698dab4883c4d77099971af7a14..df705db08b0666561066297599cc3d9c75204e11 100644 (file)
@@ -1263,9 +1263,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 */
@@ -1315,14 +1312,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")
index 0679b8ad2d1e1a4263521f805d7afd246334a037..fa5c4a59b0aadfcd3022c304c5d0cb49fe7fa5ad 100644 (file)
@@ -621,13 +621,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,
 };
@@ -695,13 +688,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);
 }
 
index b2c5557f50e42e1c39c3b0d2f7cfc8f4035a44fd..5258b85636765bd24e9e5e478ec7fb586bf55cc9 100644 (file)
@@ -277,13 +277,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,
@@ -336,10 +329,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)
@@ -379,7 +368,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")
index 37ac93e8d6d9ef44940dabb5f1d916301012ee54..026241737919082c922d17f9f0ffeae4c71c64af 100644 (file)
@@ -969,7 +969,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,
@@ -982,9 +981,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,
@@ -1003,10 +999,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)
@@ -1040,15 +1032,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")
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
new file mode 100644 (file)
index 0000000..0b04af2
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Exynos Generic power domain support.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Implementation of Exynos 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>
+
+/*
+ * Exynos specific wrapper around the generic power domain
+ */
+struct exynos_pm_domain {
+       void __iomem *base;
+       char const *name;
+       bool is_off;
+       struct generic_pm_domain pd;
+};
+
+static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
+{
+       struct exynos_pm_domain *pd;
+       void __iomem *base;
+       u32 timeout, pwr;
+       char *op;
+
+       pd = container_of(domain, struct exynos_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", domain->name, op);
+                       return -ETIMEDOUT;
+               }
+               timeout--;
+               cpu_relax();
+               usleep_range(80, 100);
+       }
+       return 0;
+}
+
+static int exynos_pd_power_on(struct generic_pm_domain *domain)
+{
+       return exynos_pd_power(domain, true);
+}
+
+static int exynos_pd_power_off(struct generic_pm_domain *domain)
+{
+       return exynos_pd_power(domain, false);
+}
+
+#define EXYNOS_GPD(PD, BASE, NAME)                     \
+static struct exynos_pm_domain PD = {                  \
+       .base = (void __iomem *)BASE,                   \
+       .name = NAME,                                   \
+       .pd = {                                         \
+               .power_off = exynos_pd_power_off,       \
+               .power_on = exynos_pd_power_on, \
+       },                                              \
+}
+
+#ifdef CONFIG_OF
+static __init int exynos_pm_dt_parse_domains(void)
+{
+       struct device_node *np;
+
+       for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+               struct exynos_pm_domain *pd;
+
+               pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+               if (!pd) {
+                       pr_err("%s: failed to allocate memory for domain\n",
+                                       __func__);
+                       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 = exynos_pd_power_off;
+               pd->pd.power_on = exynos_pd_power_on;
+               pd->pd.of_node = np;
+               pm_genpd_init(&pd->pd, NULL, false);
+       }
+       return 0;
+}
+#else
+static __init int exynos_pm_dt_parse_domains(void)
+{
+       return 0;
+}
+#endif /* CONFIG_OF */
+
+static __init void exynos_pm_add_dev_to_genpd(struct platform_device *pdev,
+                                               struct exynos_pm_domain *pd)
+{
+       if (pdev->dev.bus) {
+               if (pm_genpd_add_device(&pd->pd, &pdev->dev))
+                       pr_info("%s: error in adding %s device to %s power"
+                               "domain\n", __func__, dev_name(&pdev->dev),
+                               pd->name);
+       }
+}
+
+EXYNOS_GPD(exynos4_pd_mfc, S5P_PMU_MFC_CONF, "pd-mfc");
+EXYNOS_GPD(exynos4_pd_g3d, S5P_PMU_G3D_CONF, "pd-g3d");
+EXYNOS_GPD(exynos4_pd_lcd0, S5P_PMU_LCD0_CONF, "pd-lcd0");
+EXYNOS_GPD(exynos4_pd_lcd1, S5P_PMU_LCD1_CONF, "pd-lcd1");
+EXYNOS_GPD(exynos4_pd_tv, S5P_PMU_TV_CONF, "pd-tv");
+EXYNOS_GPD(exynos4_pd_cam, S5P_PMU_CAM_CONF, "pd-cam");
+EXYNOS_GPD(exynos4_pd_gps, S5P_PMU_GPS_CONF, "pd-gps");
+
+static struct exynos_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;
+
+       if (of_have_populated_dt())
+               return exynos_pm_dt_parse_domains();
+
+       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
+       exynos_pm_add_dev_to_genpd(&s5p_device_fimd0, &exynos4_pd_lcd0);
+#endif
+#ifdef CONFIG_S5P_DEV_TV
+       exynos_pm_add_dev_to_genpd(&s5p_device_hdmi, &exynos4_pd_tv);
+       exynos_pm_add_dev_to_genpd(&s5p_device_mixer, &exynos4_pd_tv);
+#endif
+#ifdef CONFIG_S5P_DEV_MFC
+       exynos_pm_add_dev_to_genpd(&s5p_device_mfc, &exynos4_pd_mfc);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC0
+       exynos_pm_add_dev_to_genpd(&s5p_device_fimc0, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC1
+       exynos_pm_add_dev_to_genpd(&s5p_device_fimc1, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC2
+       exynos_pm_add_dev_to_genpd(&s5p_device_fimc2, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC3
+       exynos_pm_add_dev_to_genpd(&s5p_device_fimc3, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_CSIS0
+       exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis0, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_CSIS1
+       exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam);
+#endif
+       return 0;
+}
+arch_initcall(exynos4_pm_init_power_domain);
+
+static __init int exynos_pm_late_initcall(void)
+{
+       pm_genpd_poweroff_unused();
+       return 0;
+}
+late_initcall(exynos_pm_late_initcall);