linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags
@ 2010-07-19  8:30 MyungJoo Ham
  2010-07-19  8:30 ` [PATCH 1/4] ARM: SAMSUNG SoC: Powerdomain/Block-gating Support MyungJoo Ham
  2010-07-20  1:04 ` [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags Kukjin Kim
  0 siblings, 2 replies; 12+ messages in thread
From: MyungJoo Ham @ 2010-07-19  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

This patches add support for powerdomain, block-gating, and flags in struct clk.

Blockgating re-uses powerdomain support scheme and depends on powerdomain support.

Flags support is independent from powerdomain; however, powerdomain support is NOT stable without flags support. Without flags support, powerdomain may lock up the system with some conditions although they are rare. Thus, when powerdomain or block-gating is used, flags support should be turned on for the system stability. (and that's why I'm sending flags support with powerdomain/block-gating support).

Although powerdomain support is requred for blockgating, blockgating is NOT required for powerdomain. Besides, powerdomain support is observed to reduce power consumption significantly (with 2.6.29 kernel); however, blockgating support didn't show any significant improvement.


MyungJoo Ham (4):
  ARM: SAMSUNG SoC: Powerdomain/Block-gating Support
  ARM: S5PV210: Powerdomain/Clock-gating Support
  ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
  ARM: S5PV210: Clock Framework: Flag Support for struct clk.

 arch/arm/mach-s5pv210/Kconfig              |   17 +
 arch/arm/mach-s5pv210/clock.c              |  906 ++++++++++++++++++++++------
 arch/arm/plat-samsung/Kconfig              |   19 +
 arch/arm/plat-samsung/clock.c              |  146 +++++-
 arch/arm/plat-samsung/include/plat/clock.h |   44 ++
 5 files changed, 935 insertions(+), 197 deletions(-)

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

* [PATCH 1/4] ARM: SAMSUNG SoC: Powerdomain/Block-gating Support
  2010-07-19  8:30 [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags MyungJoo Ham
@ 2010-07-19  8:30 ` MyungJoo Ham
  2010-07-19  8:30   ` [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support MyungJoo Ham
  2010-07-20  1:04 ` [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags Kukjin Kim
  1 sibling, 1 reply; 12+ messages in thread
From: MyungJoo Ham @ 2010-07-19  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

Even when all the clocks of a domain are turned off, turning off the
power for the domain saves (leakage) current. Thus, we need to control
powerdomain accordingly to save even more power when we do clock gating.

Block-gating is a similar feature with powerdomain, but, it controls
"block", which is smaller than power-domain, and the saved current is
not so significant.

This patch enables powerdomain/block-gating support for Samsung SoC.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/plat-samsung/Kconfig              |   19 +++++++
 arch/arm/plat-samsung/clock.c              |   76 ++++++++++++++++++++++++++-
 arch/arm/plat-samsung/include/plat/clock.h |   32 ++++++++++++
 3 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index bd007e3..1fddb04 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -298,4 +298,23 @@ config SAMSUNG_WAKEMASK
 	  and above. This code allows a set of interrupt to wakeup-mask
 	  mappings. See <plat/wakeup-mask.h>
 
+config SAMSUNG_POWERDOMAIN
+	bool "Powerdomain Control Support"
+	depends on CPU_S5PV210
+	select S5PV210_POWERDOMAIN
+	help
+	  Compile support for powerdomain controls. This code allows
+	  enabling and diabling powerdomain according to its clocks,
+	  which often saves significant amount of power.
+
+config SAMSUNG_BLOCKGATING
+	bool "Block Gating Control Support"
+	depends on SAMSUNG_POWERDOMAIN && CPU_S5PV210
+	select S5PV210_BLOCKGATING
+	help
+	  Compile support for block gating controls. This code allows
+	  enabling and diabling blocks according to its clocks.
+	  However, at least in S5PV210, this is not as effective as
+	  powerdomain control.
+
 endif
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 8bf79f3..f8a30f7 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -113,6 +113,10 @@ void clk_put(struct clk *clk)
 
 int clk_enable(struct clk *clk)
 {
+#if defined(CONFIG_SAMSUNG_BLOCKGATING) || defined(CONFIG_SAMSUNG_POWERDOMAIN)
+	struct clk *p;
+#endif
+
 	if (IS_ERR(clk) || clk == NULL)
 		return -EINVAL;
 
@@ -120,8 +124,38 @@ int clk_enable(struct clk *clk)
 
 	spin_lock(&clocks_lock);
 
-	if ((clk->usage++) == 0)
-		(clk->enable)(clk, 1);
+	if ((clk->usage++) == 0) {
+#ifdef CONFIG_SAMSUNG_BLOCKGATING
+		if (clk->bd && clk->bd->ref_count == 0) {
+			if (clk->bd->pd_set)
+				clk->bd->pd_set(clk->bd, 1);
+			clk->bd->ref_count++;
+		}
+#endif
+#ifdef CONFIG_SAMSUNG_POWERDOMAIN
+		if (clk->pd) {
+			if (clk->pd->ref_count == 0 &&
+					clk->pd->num_clks_boot_on <= 0) {
+				list_for_each_entry(p, &clk->pd->clocks,
+						powerdomain_list) {
+					if (p->enable)
+						p->enable(p, 1);
+				}
+
+				clk->pd->pd_set(clk->pd, 1);
+
+				list_for_each_entry(p, &clk->pd->clocks,
+						powerdomain_list) {
+					if (p->enable)
+						p->enable(p, 0);
+				}
+			}
+			clk->pd->ref_count++;
+		}
+#endif
+		if (clk->enable)
+			(clk->enable)(clk, 1);
+	}
 
 	spin_unlock(&clocks_lock);
 	return 0;
@@ -134,8 +168,29 @@ void clk_disable(struct clk *clk)
 
 	spin_lock(&clocks_lock);
 
-	if ((--clk->usage) == 0)
+	if ((--clk->usage) == 0) {
 		(clk->enable)(clk, 0);
+#ifdef CONFIG_SAMSUNG_POWERDOMAIN
+		if (clk->pd) {
+			if (clk->pd->ref_count == 1 &&
+					clk->pd->num_clks_boot_on <= 0 &&
+					clk->pd->pd_set)
+				clk->pd->pd_set(clk->pd, 0);
+			if (clk->pd->ref_count > 0)
+				clk->pd->ref_count--;
+		}
+#endif
+#ifdef CONFIG_SAMSUNG_BLOCKGATING
+		if (clk->bd) {
+			if (clk->bd->ref_count == 1 &&
+					clk->bd->num_clks_boot_on <= 0 &&
+					clk->bd->pd_set)
+				clk->bd->pd_set(clk->bd, 0);
+			if (clk->bd->ref_count > 0)
+				clk->bd->ref_count--;
+		}
+#endif
+	}
 
 	spin_unlock(&clocks_lock);
 	clk_disable(clk->parent);
@@ -327,6 +382,21 @@ int s3c24xx_register_clock(struct clk *clk)
 	list_add(&clk->list, &clocks);
 	spin_unlock(&clocks_lock);
 
+#ifdef CONFIG_SAMSUNG_POWERDOMAIN
+	if (clk->pd) {
+		spin_lock(&clocks_lock);
+		list_add(&clk->powerdomain_list, &clk->pd->clocks);
+		spin_unlock(&clocks_lock);
+	}
+#endif
+#ifdef CONFIG_SAMSUNG_BLOCKGATING
+	if (clk->bd) {
+		spin_lock(&clocks_lock);
+		list_add(&clk->blockgating_list, &clk->bd->clocks);
+		spin_unlock(&clocks_lock);
+	}
+#endif
+
 	return 0;
 }
 
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 0fbcd0e..bf851e1 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -11,6 +11,30 @@
 
 #include <linux/spinlock.h>
 
+#ifdef CONFIG_SAMSUNG_POWERDOMAIN
+struct register_save {
+	unsigned int		addr;
+	unsigned int		data;
+};
+
+struct powerdomain {
+	/* The number of clks that are never-disabled and "BOOT_ON" */
+	int			num_clks_boot_on;
+	struct list_head	clocks;
+
+	unsigned long	*pd_reg;
+	unsigned long	*pd_stable_reg;
+	unsigned long		pd_ctrlbit;
+	unsigned long		pd_stable_ctrlbit;
+	int			ref_count;
+
+	int			(*pd_set)(struct powerdomain *, int enable);
+	bool			normal_ff_saved;
+	struct register_save	*normal_ff;
+	unsigned int		num_normal_ff;
+};
+#endif
+
 struct clk;
 
 /**
@@ -47,6 +71,14 @@ struct clk {
 
 	struct clk_ops		*ops;
 	int		    (*enable)(struct clk *, int enable);
+#ifdef CONFIG_SAMSUNG_POWERDOMAIN
+	struct powerdomain	*pd;
+	struct list_head	powerdomain_list;
+#endif
+#ifdef CONFIG_SAMSUNG_BLOCKGATING
+	struct powerdomain	*bd;
+	struct list_head	blockgating_list;
+#endif
 };
 
 /* other clocks which may be registered by board support */
-- 
1.6.3.3

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

* [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support
  2010-07-19  8:30 ` [PATCH 1/4] ARM: SAMSUNG SoC: Powerdomain/Block-gating Support MyungJoo Ham
@ 2010-07-19  8:30   ` MyungJoo Ham
  2010-07-19  8:30     ` [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk MyungJoo Ham
  2010-07-19  9:02     ` [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support Russell King - ARM Linux
  0 siblings, 2 replies; 12+ messages in thread
From: MyungJoo Ham @ 2010-07-19  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

S5PV210 Machine specific code for powerdomain/clock-gating support

Powerdomains and Blocks are defined for each corresponding clk.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig |   17 ++
 arch/arm/mach-s5pv210/clock.c |  461 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 478 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 631019a..92f6b74 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -101,4 +101,21 @@ config MACH_SMDKC110
 	  Machine support for Samsung SMDKC110
 	  S5PC110(MCP) is one of package option of S5PV210
 
+config S5PV210_POWERDOMAIN
+	bool "Use Powerdomain control for S5PV210"
+	depends on SAMSUNG_POWERDOMAIN && CPU_S5PV210
+	help
+	  Compile support for powerdomain controls in S5PV210.
+	  This code allows enabling and diabling powerdomain
+	  according to its clocks, which often saves significant
+	  amount of power. Note that BLOCKGATING code depends on
+	  POWERDOMAIN in S5PV210 code.
+
+config S5PV210_BLOCKGATING
+	bool "Use Block Gating for S5PV210"
+	depends on SAMSUNG_POWERDOMAIN && S5PV210_POWERDOMAIN &&\
+		SAMSUNG_BLOCKGATING
+	help
+	  Compile support for block gating controls in S5PV210.
+
 endif
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 04a0ef9..af2af5e 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/sysdev.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
 
 #include <mach/map.h>
 
@@ -31,6 +32,392 @@
 #include <plat/clock-clksrc.h>
 #include <plat/s5pv210.h>
 
+#ifdef CONFIG_S5PV210_POWERDOMAIN
+#include <linux/delay.h>
+#define PD_SET(x)		.pd = &pd_##x,
+
+#ifdef CONFIG_S5PV210_BLOCKGATING
+#define BD_SET(x)		.bd = &bd_##x,
+#else
+#define BD_SET(x)
+#endif
+
+#else
+#define PD_SET(x)
+#define BD_SET(x)
+#endif
+
+#ifdef CONFIG_S5PV210_POWERDOMAIN
+static void normal_ff_save(struct register_save *regs, unsigned int num_regs)
+{
+	int i;
+	for (i = 0; i < num_regs; i++)
+		regs[i].data = __raw_readl(regs[i].addr);
+}
+
+static void normal_ff_restore(struct register_save *regs, unsigned int num_regs)
+{
+	int i;
+	for (i = 0; i < num_regs; i++) {
+		__raw_writel(regs[i].data, regs[i].addr);
+#ifdef CONFIG_S5PC110_EVT0_WORKAROUND
+		__raw_readl(regs[i].addr);
+#endif
+	}
+}
+
+DEFINE_SPINLOCK(powerdomain_lock);
+
+static int powerdomain_set(struct powerdomain *pd, int enable)
+{
+	unsigned long ctrlbit;
+	void __iomem *reg;
+	void __iomem *stable_reg;
+	unsigned long reg_dat;
+
+	if (pd == NULL)
+		return -EINVAL;
+
+	ctrlbit = pd->pd_ctrlbit;
+	reg = (void __iomem *)pd->pd_reg;
+	stable_reg = (void __iomem *)pd->pd_stable_reg;
+
+	spin_lock(&powerdomain_lock);
+	reg_dat = __raw_readl(reg);
+
+	if (enable) {
+		__raw_writel(reg_dat|ctrlbit, reg);
+		spin_unlock(&powerdomain_lock);
+
+		if (pd->pd_stable_ctrlbit && stable_reg) {
+			do { } while (!(__raw_readl(stable_reg) &
+						pd->pd_stable_ctrlbit));
+		}
+
+		if (pd->normal_ff_saved && pd->normal_ff) {
+			normal_ff_restore(pd->normal_ff, pd->num_normal_ff);
+			pd->normal_ff_saved = 0;
+		}
+	} else {
+		if (pd->normal_ff) {
+			normal_ff_save(pd->normal_ff, pd->num_normal_ff);
+			pd->normal_ff_saved = 1;
+		}
+		__raw_writel(reg_dat & ~(ctrlbit), reg);
+		spin_unlock(&powerdomain_lock);
+	}
+
+	return 0;
+}
+
+static struct powerdomain pd_lcd = {
+	/* L-block: G2D, FIMD, MIE, DSIM */
+	.pd_reg			= S5P_NORMAL_CFG,
+	.pd_stable_reg		= S5P_BLK_PWR_STAT,
+	.pd_ctrlbit		= (0x1 << 3),
+	.pd_stable_ctrlbit	= (0x1 << 3),
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(pd_lcd.clocks),
+};
+
+static struct powerdomain pd_tv = {
+	/* T-block: VP, MIXER, TVENC, HDMI */
+	.pd_reg			= S5P_NORMAL_CFG,
+	.pd_stable_reg		= S5P_BLK_PWR_STAT,
+	.pd_ctrlbit		= (0x1 << 4),
+	.pd_stable_ctrlbit	= (0x1 << 4),
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(pd_tv.clocks),
+};
+
+static struct powerdomain pd_mfc = {
+	/* F-block: MFC */
+	.pd_reg			= S5P_NORMAL_CFG,
+	.pd_stable_reg		= S5P_BLK_PWR_STAT,
+	.pd_ctrlbit		= (0x1 << 1),
+	.pd_stable_ctrlbit	= (0x1 << 1),
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(pd_mfc.clocks),
+};
+
+static struct powerdomain pd_cam = {
+	/* X-block: FIMC0, FIMC1, FIMC2, CSIS, JPEG, Rotator,
+	 * MIE(Deprecated) */
+	.pd_reg			= S5P_NORMAL_CFG,
+	.pd_stable_reg		= S5P_BLK_PWR_STAT,
+	.pd_ctrlbit		= (0x1 << 5),
+	.pd_stable_ctrlbit	= (0x1 << 5),
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(pd_cam.clocks),
+};
+
+static struct powerdomain pd_audio = {
+	/* Audio sub-block: I2S0, Audio buffer RAM */
+	.pd_reg			= S5P_NORMAL_CFG,
+	.pd_stable_reg		= S5P_BLK_PWR_STAT,
+	.pd_ctrlbit		= (0x1 << 7),
+	.pd_stable_ctrlbit	= (0x1 << 7),
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(pd_audio.clocks),
+};
+
+static struct powerdomain pd_irom = {
+	.pd_reg			= S5P_NORMAL_CFG,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= (0x1 << 20),
+	.pd_stable_ctrlbit	= (0x0), /* not avaiable */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(pd_irom.clocks),
+};
+
+static struct powerdomain pd_g3d = {
+	/* G3D Block */
+	.pd_reg			= S5P_NORMAL_CFG,
+	.pd_stable_reg		= S5P_BLK_PWR_STAT,
+	.pd_ctrlbit		= (0x1 << 2),
+	.pd_stable_ctrlbit	= (0x1 << 2),
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(pd_g3d.clocks),
+};
+
+static struct powerdomain *pd_list[] = {
+	&pd_lcd,
+	&pd_tv,
+	&pd_mfc,
+	&pd_cam,
+	&pd_audio,
+	&pd_irom,
+	&pd_g3d,
+};
+
+/* Support for Deep-Idle:
+ * AUDIO block is not turned off with top-off (deep-idle) */
+static struct powerdomain *pd_backup_topoff[] = {
+	&pd_lcd,
+	&pd_tv,
+	&pd_mfc,
+	&pd_cam,
+	&pd_irom,
+	&pd_g3d,
+};
+
+unsigned int powerdomain_backup_topoff(void)
+{
+	int pdset = 0;
+	int i;
+	for (i = 0; i < ARRAY_SIZE(pd_backup_topoff); i++) {
+		if (__raw_readl(pd_backup_topoff[i]->pd_reg) &
+				pd_backup_topoff[i]->pd_ctrlbit) {
+			/* powerdomain alive. back it up */
+			normal_ff_save(pd_backup_topoff[i]->normal_ff,
+					pd_backup_topoff[i]->num_normal_ff);
+			pdset |= pd_backup_topoff[i]->pd_ctrlbit;
+		}
+	}
+	return pdset;
+}
+
+void powerdomain_restore_topoff(unsigned int pdset)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pd_backup_topoff); i++) {
+		if (pdset & pd_backup_topoff[i]->pd_ctrlbit) {
+			/* powerdomain backuped. restore it */
+			normal_ff_restore(pd_backup_topoff[i]->normal_ff,
+					pd_backup_topoff[i]->num_normal_ff);
+		}
+	}
+}
+#endif
+
+#ifdef CONFIG_S5PV210_BLOCKGATING
+static struct powerdomain bd_intc = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 10,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_intc.clocks),
+};
+
+static struct powerdomain bd_hsmmc = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 9,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_hsmmc.clocks),
+};
+
+static struct powerdomain bd_debug = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 8,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_debug.clocks),
+};
+
+static struct powerdomain bd_security = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 7,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_security.clocks),
+};
+
+static struct powerdomain bd_memory = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 6,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_memory.clocks),
+};
+
+static struct powerdomain bd_usb = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 5,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_usb.clocks),
+};
+
+static struct powerdomain bd_tv = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 4,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_tv.clocks),
+};
+
+static struct powerdomain bd_lcd = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 3,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_lcd.clocks),
+};
+
+static struct powerdomain bd_img = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 2,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_img.clocks),
+};
+
+static struct powerdomain bd_mfc = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 1,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_mfc.clocks),
+};
+
+static struct powerdomain bd_g3d = {
+	.pd_reg			= S5P_CLKGATE_BLOCK,
+	.pd_stable_reg		= NULL,
+	.pd_ctrlbit		= 1 << 0,
+	.pd_stable_ctrlbit	= (0x0), /* not available */
+	.ref_count		= 0,
+	.pd_set			= powerdomain_set,
+	.normal_ff_saved	= 0,
+	.normal_ff		= NULL,
+	.num_normal_ff		= 0,
+	.clocks			= LIST_HEAD_INIT(bd_g3d.clocks),
+};
+
+static struct powerdomain *bd_list[] = {
+	&bd_intc,
+	&bd_hsmmc,
+	&bd_debug,
+	&bd_security,
+	&bd_memory,
+	&bd_usb,
+	&bd_tv,
+	&bd_lcd,
+	&bd_img,
+	&bd_mfc,
+	&bd_g3d,
+};
+#endif
+
 static struct clksrc_clk clk_mout_apll = {
 	.clk	= {
 		.name		= "mout_apll",
@@ -280,138 +667,173 @@ static struct clk init_clocks_disable[] = {
 		.parent		= &clk_pclk_dsys.clk,
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1 << 31),
+		PD_SET(cam)
+		BD_SET(img)
 	}, {
 		.name		= "rot",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1<<29),
+		PD_SET(cam)
+		BD_SET(img)
 	}, {
 		.name		= "jpeg",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1 << 28),
+		PD_SET(cam)
+		BD_SET(img)
 	}, {
 		.name		= "fimc",
 		.id		= 0,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1 << 24),
+		PD_SET(cam)
+		BD_SET(img)
 	}, {
 		.name		= "fimc",
 		.id		= 1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1 << 25),
+		PD_SET(cam)
+		BD_SET(img)
 	}, {
 		.name		= "fimc",
 		.id		= 2,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1 << 26),
+		PD_SET(cam)
+		BD_SET(img)
 	}, {
 		.name		= "nfcon",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 28),
+		BD_SET(memory)
 	}, {
 		.name		= "tvenc",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 10),
+		PD_SET(tv)
+		BD_SET(tv)
 	}, {
 		.name		= "hdmi",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 11),
+		PD_SET(tv)
+		BD_SET(tv)
 	}, {
 		.name		= "mixer",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 9),
+		PD_SET(tv)
+		BD_SET(tv)
 	}, {
 		.name		= "otg",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1<<16),
+		BD_SET(usb)
 	}, {
 		.name		= "usb-host",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1<<17),
+		BD_SET(usb)
 	}, {
 		.name		= "lcd",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1<<0),
+		PD_SET(lcd)
+		BD_SET(lcd)
 	}, {
 		.name		= "cfcon",
 		.id		= 0,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1<<25),
+		BD_SET(memory)
 	}, {
 		.name		= "vp",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 8),
+		PD_SET(tv)
+		BD_SET(tv)
 	}, {
 		.name		= "dsim",
 		.id		= -1,
 		.parent		= &clk_hclk_dsys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 2),
+		PD_SET(lcd)
+		BD_SET(lcd)
 	}, {
 		.name		= "hsmmc",
 		.id		= 0,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<16),
+		BD_SET(hsmmc)
 	}, {
 		.name		= "hsmmc",
 		.id		= 1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<17),
+		BD_SET(hsmmc)
 	}, {
 		.name		= "hsmmc",
 		.id		= 2,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<18),
+		BD_SET(hsmmc)
 	}, {
 		.name		= "hsmmc",
 		.id		= 3,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<19),
+		BD_SET(hsmmc)
 	}, {
 		.name		= "tsi",
 		.id		= -1,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 20),
+		BD_SET(hsmmc)
 	}, {
 		.name		= "hostif",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 10),
+		BD_SET(debug)
 	}, {
 		.name		= "modem",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 9),
+		BD_SET(debug)
 	}, {
 		.name		= "pcm",
 		.id		= 0,
@@ -520,6 +942,8 @@ static struct clk init_clocks_disable[] = {
 		.parent		= &clk_p,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<4),
+		/* Note that only i2s-0 is connected to pd_audio */
+		PD_SET(audio)
 	}, {
 		.name		= "i2s_v32",
 		.id		= 0,
@@ -614,72 +1038,84 @@ static struct clk init_clocks[] = {
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 24),
+		BD_SET(memory)
 	}, {
 		.name		= "sromc",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 26),
+		BD_SET(memory)
 	}, {
 		.name		= "tzic",
 		.id		= 0,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 28),
+		BD_SET(intc)
 	}, {
 		.name		= "tzic",
 		.id		= 1,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 29),
+		BD_SET(intc)
 	}, {
 		.name		= "tzic",
 		.id		= 2,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 30),
+		BD_SET(intc)
 	}, {
 		.name		= "tzic",
 		.id		= 3,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 31),
+		BD_SET(intc)
 	}, {
 		.name		= "vic",
 		.id		= 0,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 24),
+		BD_SET(intc)
 	}, {
 		.name		= "vic",
 		.id		= 1,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 25),
+		BD_SET(intc)
 	}, {
 		.name		= "vic",
 		.id		= 2,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 26),
+		BD_SET(intc)
 	}, {
 		.name		= "vic",
 		.id		= 3,
 		.parent		= &clk_hclk_msys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 27),
+		BD_SET(intc)
 	}, {
 		.name		= "secjtag",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 11),
+		BD_SET(debug)
 	}, {
 		.name		= "coresight",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 8),
+		BD_SET(debug)
 	}, {
 		.name		= "sdm",
 		.id		= -1,
@@ -691,6 +1127,7 @@ static struct clk init_clocks[] = {
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 0),
+		BD_SET(security)
 	}, {
 		.name		= "syscon",
 		.id		= -1,
@@ -1344,5 +1781,29 @@ void __init s5pv210_register_clocks(void)
 		(clkp->enable)(clkp, 0);
 	}
 
+#ifdef CONFIG_S5PV210_POWERDOMAIN
+	/* According to the state of the members, turn on/off power domains
+	 * and blocks. */
+	for (ptr = 0; ptr < ARRAY_SIZE(pd_list); ptr++) {
+		if (pd_list[ptr]->pd_set) {
+			if (pd_list[ptr]->num_clks_boot_on > 0)
+				pd_list[ptr]->pd_set(pd_list[ptr], 1);
+			else
+				pd_list[ptr]->pd_set(pd_list[ptr], 0);
+		}
+	}
+#endif /* CONFIG_S5PV210_POWERDOMAIN */
+
+#ifdef CONFIG_S5PV210_BLOCKGATING
+	for (ptr = 0; ptr < ARRAY_SIZE(bd_list); ptr++) {
+		if (bd_list[ptr]->pd_set) {
+			if (bd_list[ptr]->num_clks_boot_on > 0)
+				bd_list[ptr]->pd_set(bd_list[ptr], 1);
+			else
+				bd_list[ptr]->pd_set(bd_list[ptr], 0);
+		}
+	}
+#endif /* CONFIG_S5PV210_BLOCKGATING */
+
 	s3c_pwmclk_init();
 }
-- 
1.6.3.3

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

* [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
  2010-07-19  8:30   ` [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support MyungJoo Ham
@ 2010-07-19  8:30     ` MyungJoo Ham
  2010-07-19  8:30       ` [PATCH 4/4] ARM: S5PV210: " MyungJoo Ham
                         ` (2 more replies)
  2010-07-19  9:02     ` [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support Russell King - ARM Linux
  1 sibling, 3 replies; 12+ messages in thread
From: MyungJoo Ham @ 2010-07-19  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add a .flag property to the struct clk. The flag can have the following
information:

	The clock is enabled at the boot time.
	The clock cannot be disabled.
	The clock is enabled at the boot time and cannot be disabled.
	The clock is disabled at the boot time. Note that both
CLKFLAGS_BOOT_ON and CLKFLAGS_CANNOT_DISABLE can override
CLKFLAGS_BOOT_OFF.
	Please stop using this clock. When a DEPRECATED clock is
clk_get'd, clk_get function will printk a warning message.

The previous patch related with powerdomain / blcok-gating control
requires this patch for the stability related with clocks that are
turned on at the boot time.

Note that clocks without both BOOT_ON and BOOT_OFF keep the previous
states; however, powerdomain / block-gating controls do NOT have any
information about the states of such clocks, which in turn, may incur
instable kernel behaviors. For example, a powerdomain may be turned off
while a clock of the domain is still being used. With the flag support
feature, we highly recommend to define .flag fields fully for clocks
related to powerdomain and block-gating. Clocks not connected to
powerdomain and block-gating are ok without flag field.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/plat-samsung/clock.c              |   70 ++++++++++++++++++++++++++-
 arch/arm/plat-samsung/include/plat/clock.h |   12 +++++
 2 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index f8a30f7..9ff9d63 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -103,6 +103,14 @@ struct clk *clk_get(struct device *dev, const char *id)
 	}
 
 	spin_unlock(&clocks_lock);
+
+	if (!IS_ERR(clk) && clk)
+		if (clk->flags & CLKFLAGS_DEPRECATED)
+			printk(KERN_WARNING "[%s:%d] clk %s:%d is deprecated. "
+					"Please reconsider using it.\n",
+					__FILE__, __LINE__, clk->name,
+					clk->id);
+
 	return clk;
 }
 
@@ -169,7 +177,25 @@ void clk_disable(struct clk *clk)
 	spin_lock(&clocks_lock);
 
 	if ((--clk->usage) == 0) {
-		(clk->enable)(clk, 0);
+#ifdef CONFIG_SAMSUNG_POWERDOMAIN
+		if ((clk->flags | CLKFLAGS_BOOT_ON) &&
+				!(clk->flags | CLKFLAGS_CANNOT_DISABLE)) {
+			/* BOOT_ON became NO EFFECT. Let PD/BD be able
+			 * to turn themselves off */
+
+			if (clk->pd)
+				clk->pd->num_clks_boot_on--;
+#ifdef CONFIG_SAMSUNG_BLOCKGATING
+			if (clk->bd)
+				clk->bd->num_clks_boot_on--;
+#endif
+			clk->flags &= ~CLKFLAGS_BOOT_ON;
+		}
+#endif
+
+		if (clk->enable && !(clk->flags | CLKFLAGS_CANNOT_DISABLE))
+			(clk->enable)(clk, 0);
+
 #ifdef CONFIG_SAMSUNG_POWERDOMAIN
 		if (clk->pd) {
 			if (clk->pd->ref_count == 1 &&
@@ -193,7 +219,9 @@ void clk_disable(struct clk *clk)
 	}
 
 	spin_unlock(&clocks_lock);
-	clk_disable(clk->parent);
+
+	if (!(clk->flags | CLKFLAGS_CANNOT_DISABLE))
+		clk_disable(clk->parent);
 }
 
 
@@ -370,6 +398,13 @@ struct clk s3c24xx_uclk = {
  */
 int s3c24xx_register_clock(struct clk *clk)
 {
+	int ret = 0;
+
+	if (clk == NULL)
+		return -EINVAL;
+	if (clk->name == NULL)
+		return -EINVAL;
+
 	if (clk->enable == NULL)
 		clk->enable = clk_null_enable;
 
@@ -382,6 +417,21 @@ int s3c24xx_register_clock(struct clk *clk)
 	list_add(&clk->list, &clocks);
 	spin_unlock(&clocks_lock);
 
+	if (clk->flags & CLKFLAGS_BOOT_ON) {
+		/* Use clk_enable, not clk->enable as clk's parent is
+		 * also required to be turned on */
+		clk_enable(clk);
+
+#ifdef CONFIG_SAMSUNG_POWERDOMAIN
+		if (clk->pd)
+			clk->pd->num_clks_boot_on++;
+#endif
+#ifdef CONFIG_SAMSUNG_BLOCKGATING
+		if (clk->bd)
+			clk->bd->num_clks_boot_on++;
+#endif
+	}
+
 #ifdef CONFIG_SAMSUNG_POWERDOMAIN
 	if (clk->pd) {
 		spin_lock(&clocks_lock);
@@ -397,7 +447,21 @@ int s3c24xx_register_clock(struct clk *clk)
 	}
 #endif
 
-	return 0;
+	if (clk->flags & CLKFLAGS_BOOT_OFF) {
+		if ((clk->flags & CLKFLAGS_BOOT_ON) ||
+				(clk->flags & CLKFLAGS_CANNOT_DISABLE)) {
+			printk(KERN_WARNING "[%s:%d] clk %s:%d has incompatible"
+					" initilization flags: %x.\n",
+					__FILE__, __LINE__, clk->name, clk->id,
+					clk->flags);
+			ret = -EINVAL;
+		} else
+			/* Do NOT use clk_disable(clk) because clk_disable
+			 * may disable clk's parent */
+			ret = (clk->enable)(clk, 0);
+	}
+
+	return ret;
 }
 
 /**
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index bf851e1..0f7d556 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -59,6 +59,17 @@ struct clk_ops {
 	int		    (*set_parent)(struct clk *c, struct clk *parent);
 };
 
+/* Note that when BOOT_ON and OFF are both not set, the kernel
+ * keeps the state initialized by the boot-loader or cpu.
+ */
+#define CLKFLAGS_BOOT_ON	(0x1)
+#define CLKFLAGS_CANNOT_DISABLE	(0x2)
+#define CLKFLAGS_ALWAYS_ON	(CLKFLAGS_BOOT_ON | CLKFLAGS_CANNOT_DISABLE)
+#define CLKFLAGS_BOOT_OFF	(0x4) /* Force off when boot */
+#define CLKFLAGS_DEPRECATED	(0x8) /* Warn when clk_get'd */
+/* Note that CLKFLAGS_BOOT_ON and CLKFLAGS_CANNOT_DISABLE overrides
+ * CLKFLAGS_BOOT_OFF */
+
 struct clk {
 	struct list_head      list;
 	struct module        *owner;
@@ -79,6 +90,7 @@ struct clk {
 	struct powerdomain	*bd;
 	struct list_head	blockgating_list;
 #endif
+	unsigned int		flags;
 };
 
 /* other clocks which may be registered by board support */
-- 
1.6.3.3

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

* [PATCH 4/4] ARM: S5PV210: Clock Framework: Flag Support for struct clk.
  2010-07-19  8:30     ` [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk MyungJoo Ham
@ 2010-07-19  8:30       ` MyungJoo Ham
  2010-07-19  8:57       ` [PATCH 3/4] ARM: SAMSUNG SoC: " Russell King - ARM Linux
  2010-07-19 10:07       ` Maurus Cuelenaere
  2 siblings, 0 replies; 12+ messages in thread
From: MyungJoo Ham @ 2010-07-19  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

Added .flags property to struct clk init_clocks[] and removed
init_clocks_disabled[], which became useless by BOOT_OFF bit of .flags.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/clock.c |  477 +++++++++++++++++++++++------------------
 1 files changed, 270 insertions(+), 207 deletions(-)

diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index af2af5e..bafba6f 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -660,8 +660,51 @@ static struct clk_ops clk_hclk_imem_ops = {
 	.get_rate	= s5pv210_clk_imem_get_rate,
 };
 
-static struct clk init_clocks_disable[] = {
+static struct clk init_clocks[] = {
 	{
+		.name		= "hclk_imem",
+		.id		= -1,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip0_ctrl,
+		.ctrlbit	= (1 << 5),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+		.ops		= &clk_hclk_imem_ops,
+	}, {
+		.name		= "pdma",
+		.id		= 0,
+		.parent		= &clk_hclk_psys.clk,
+		.enable		= s5pv210_clk_ip0_ctrl,
+		.ctrlbit	= (1 << 3),
+		.flags		= CLKFLAGS_BOOT_ON,
+	}, {
+		.name		= "pdma",
+		.id		= 1,
+		.parent		= &clk_hclk_psys.clk,
+		.enable		= s5pv210_clk_ip0_ctrl,
+		.ctrlbit	= (1 << 4),
+		.flags		= CLKFLAGS_BOOT_ON,
+	}, {
+		.name		= "mdma",
+		.id		= -1,
+		.parent		= &clk_hclk_dsys.clk,
+		.enable		= s5pv210_clk_ip0_ctrl,
+		.ctrlbit	= (1 << 2),
+		.flags		= CLKFLAGS_BOOT_OFF,
+	}, {
+		.name		= "dmc",
+		.id		= 0,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip0_ctrl,
+		.ctrlbit	= (1 << 0),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "dmc",
+		.id		= 1,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip0_ctrl,
+		.ctrlbit	= (1 << 1),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
 		.name		= "csis",
 		.id		= -1,
 		.parent		= &clk_pclk_dsys.clk,
@@ -669,6 +712,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 31),
 		PD_SET(cam)
 		BD_SET(img)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "rot",
 		.id		= -1,
@@ -677,6 +721,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1<<29),
 		PD_SET(cam)
 		BD_SET(img)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "jpeg",
 		.id		= -1,
@@ -685,6 +730,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 28),
 		PD_SET(cam)
 		BD_SET(img)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "fimc",
 		.id		= 0,
@@ -693,6 +739,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 24),
 		PD_SET(cam)
 		BD_SET(img)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "fimc",
 		.id		= 1,
@@ -701,6 +748,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 25),
 		PD_SET(cam)
 		BD_SET(img)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "fimc",
 		.id		= 2,
@@ -709,6 +757,15 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 26),
 		PD_SET(cam)
 		BD_SET(img)
+		.flags		= CLKFLAGS_BOOT_OFF,
+	}, {
+		.name		= "nandxl",
+		.id		= -1,
+		.parent		= &clk_hclk_psys.clk,
+		.enable		= s5pv210_clk_ip1_ctrl,
+		.ctrlbit	= (1 << 24),
+		BD_SET(memory)
+		.flags		= CLKFLAGS_BOOT_ON,
 	}, {
 		.name		= "nfcon",
 		.id		= -1,
@@ -716,6 +773,15 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1 << 28),
 		BD_SET(memory)
+		.flags		= CLKFLAGS_BOOT_OFF,
+	}, {
+		.name		= "sromc",
+		.id		= -1,
+		.parent		= &clk_hclk_psys.clk,
+		.enable		= s5pv210_clk_ip1_ctrl,
+		.ctrlbit	= (1 << 26),
+		BD_SET(memory)
+		.flags		= CLKFLAGS_BOOT_ON,
 	}, {
 		.name		= "tvenc",
 		.id		= -1,
@@ -724,6 +790,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 10),
 		PD_SET(tv)
 		BD_SET(tv)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "hdmi",
 		.id		= -1,
@@ -732,6 +799,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 11),
 		PD_SET(tv)
 		BD_SET(tv)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "mixer",
 		.id		= -1,
@@ -740,6 +808,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 9),
 		PD_SET(tv)
 		BD_SET(tv)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "otg",
 		.id		= -1,
@@ -747,6 +816,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1<<16),
 		BD_SET(usb)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "usb-host",
 		.id		= -1,
@@ -754,6 +824,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1<<17),
 		BD_SET(usb)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "lcd",
 		.id		= -1,
@@ -762,6 +833,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1<<0),
 		PD_SET(lcd)
 		BD_SET(lcd)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "cfcon",
 		.id		= 0,
@@ -769,6 +841,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip1_ctrl,
 		.ctrlbit	= (1<<25),
 		BD_SET(memory)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "vp",
 		.id		= -1,
@@ -777,6 +850,7 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 8),
 		PD_SET(tv)
 		BD_SET(tv)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "dsim",
 		.id		= -1,
@@ -785,6 +859,100 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1 << 2),
 		PD_SET(lcd)
 		BD_SET(lcd)
+		.flags		= CLKFLAGS_BOOT_OFF,
+	}, {
+		.name		= "tzic",
+		.id		= 0,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 28),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+		BD_SET(intc)
+	}, {
+		.name		= "tzic",
+		.id		= 1,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 29),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+		BD_SET(intc)
+	}, {
+		.name		= "tzic",
+		.id		= 2,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 30),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+		BD_SET(intc)
+	}, {
+		.name		= "tzic",
+		.id		= 3,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 31),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+		BD_SET(intc)
+	}, {
+		.name		= "vic",
+		.id		= 0,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 24),
+		BD_SET(intc)
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "vic",
+		.id		= 1,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 25),
+		BD_SET(intc)
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "vic",
+		.id		= 2,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 26),
+		BD_SET(intc)
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "vic",
+		.id		= 3,
+		.parent		= &clk_hclk_msys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 27),
+		BD_SET(intc)
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "secjtag",
+		.id		= -1,
+		.parent		= &clk_hclk_psys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 11),
+		BD_SET(debug)
+	}, {
+		.name		= "coresight",
+		.id		= -1,
+		.parent		= &clk_hclk_psys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 8),
+		BD_SET(debug)
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "sdm",
+		.id		= -1,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 1),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "secss",
+		.id		= -1,
+		.parent		= &clk_hclk_psys.clk,
+		.enable		= s5pv210_clk_ip2_ctrl,
+		.ctrlbit	= (1 << 0),
+		BD_SET(security)
+		.flags		= CLKFLAGS_ALWAYS_ON,
 	}, {
 		.name		= "hsmmc",
 		.id		= 0,
@@ -792,6 +960,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<16),
 		BD_SET(hsmmc)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "hsmmc",
 		.id		= 1,
@@ -799,6 +968,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<17),
 		BD_SET(hsmmc)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "hsmmc",
 		.id		= 2,
@@ -806,6 +976,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<18),
 		BD_SET(hsmmc)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "hsmmc",
 		.id		= 3,
@@ -813,6 +984,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1<<19),
 		BD_SET(hsmmc)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "tsi",
 		.id		= -1,
@@ -820,6 +992,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 20),
 		BD_SET(hsmmc)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "hostif",
 		.id		= -1,
@@ -827,6 +1000,7 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 10),
 		BD_SET(debug)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "modem",
 		.id		= -1,
@@ -834,108 +1008,168 @@ static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip2_ctrl,
 		.ctrlbit	= (1 << 9),
 		BD_SET(debug)
+		.flags		= CLKFLAGS_BOOT_OFF,
+	}, {
+		.name		= "syscon",
+		.id		= -1,
+		.parent		= &clk_pclk_psys.clk,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1 << 27),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_pclk_psys.clk,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1 << 26),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_pclk_psys.clk,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1 << 17),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_pclk_psys.clk,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1 << 18),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_pclk_psys.clk,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1 << 19),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_pclk_psys.clk,
+		.enable		= s5pv210_clk_ip3_ctrl,
+		.ctrlbit	= (1 << 20),
+		.flags		= CLKFLAGS_ALWAYS_ON,
 	}, {
 		.name		= "pcm",
 		.id		= 0,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 28),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "pcm",
 		.id		= 1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 29),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "pcm",
 		.id		= 2,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 30),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "systimer",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<16),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "watchdog",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<22),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "rtc",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<15),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2c",
 		.id		= 0,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<7),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2c",
 		.id		= 1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<8),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2c",
 		.id		= 2,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<9),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "spi",
 		.id		= 0,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<12),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "spi",
 		.id		= 1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<13),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "spi",
 		.id		= 2,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<14),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "timers",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<23),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "adc",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<24),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "keypad",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1<<21),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2c_hdmi_phy",
 		.id		= -1,
 		.parent		= &clk_pclk_dsys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 11),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2c_hdmi_ddc",
 		.id		= -1,
 		.parent		= &clk_pclk_dsys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 10),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2s_v50",
 		.id		= 0,
@@ -944,248 +1178,88 @@ static struct clk init_clocks_disable[] = {
 		.ctrlbit	= (1<<4),
 		/* Note that only i2s-0 is connected to pd_audio */
 		PD_SET(audio)
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2s_v32",
 		.id		= 0,
 		.parent		= &clk_p,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 5),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "i2s_v32",
 		.id		= 1,
 		.parent		= &clk_p,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 6),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "ac97",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 1),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "spdif",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip3_ctrl,
 		.ctrlbit	= (1 << 0),
+		.flags		= CLKFLAGS_BOOT_OFF,
+	}, {
+		.name		= "tzpc",
+		.id		= 0,
+		.parent		= &clk_pclk_msys.clk,
+		.enable		= s5pv210_clk_ip4_ctrl,
+		.ctrlbit	= (1 << 5),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "tzpc",
+		.id		= 1,
+		.parent		= &clk_pclk_psys.clk,
+		.enable		= s5pv210_clk_ip4_ctrl,
+		.ctrlbit	= (1 << 6),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "tzpc",
+		.id		= 2,
+		.enable		= s5pv210_clk_ip4_ctrl,
+		.ctrlbit	= (1 << 7),
+		.flags		= CLKFLAGS_ALWAYS_ON,
+	}, {
+		.name		= "tzpc",
+		.id		= 3,
+		.enable		= s5pv210_clk_ip4_ctrl,
+		.ctrlbit	= (1 << 8),
+		.flags		= CLKFLAGS_ALWAYS_ON,
 	}, {
 		.name		= "seckey",
 		.id		= -1,
 		.enable		= s5pv210_clk_ip4_ctrl,
 		.ctrlbit	= (1 << 3),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "iem_apc",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip4_ctrl,
 		.ctrlbit	= (1 << 2),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "iem_iec",
 		.id		= -1,
 		.parent		= &clk_pclk_psys.clk,
 		.enable		= s5pv210_clk_ip4_ctrl,
 		.ctrlbit	= (1 << 1),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	}, {
 		.name		= "chip_id",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
 		.enable		= s5pv210_clk_ip4_ctrl,
 		.ctrlbit	= (1 << 0),
-	},
-};
-
-static struct clk init_clocks[] = {
-	{
-		.name		= "hclk_imem",
-		.id		= -1,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 5),
-		.ops		= &clk_hclk_imem_ops,
-	}, {
-		.name		= "pdma",
-		.id		= 0,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 3),
-	}, {
-		.name		= "pdma",
-		.id		= 1,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 4),
-	}, {
-		.name		= "mdma",
-		.id		= -1,
-		.parent		= &clk_hclk_dsys.clk,
-		.enable		= s5pv210_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 2),
-	}, {
-		.name		= "dmc",
-		.id		= 0,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 0),
-	}, {
-		.name		= "dmc",
-		.id		= 1,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 1),
-	}, {
-		.name		= "nandxl",
-		.id		= -1,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip1_ctrl,
-		.ctrlbit	= (1 << 24),
-		BD_SET(memory)
-	}, {
-		.name		= "sromc",
-		.id		= -1,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip1_ctrl,
-		.ctrlbit	= (1 << 26),
-		BD_SET(memory)
-	}, {
-		.name		= "tzic",
-		.id		= 0,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 28),
-		BD_SET(intc)
-	}, {
-		.name		= "tzic",
-		.id		= 1,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 29),
-		BD_SET(intc)
-	}, {
-		.name		= "tzic",
-		.id		= 2,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 30),
-		BD_SET(intc)
-	}, {
-		.name		= "tzic",
-		.id		= 3,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 31),
-		BD_SET(intc)
-	}, {
-		.name		= "vic",
-		.id		= 0,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 24),
-		BD_SET(intc)
-	}, {
-		.name		= "vic",
-		.id		= 1,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 25),
-		BD_SET(intc)
-	}, {
-		.name		= "vic",
-		.id		= 2,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 26),
-		BD_SET(intc)
-	}, {
-		.name		= "vic",
-		.id		= 3,
-		.parent		= &clk_hclk_msys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 27),
-		BD_SET(intc)
-	}, {
-		.name		= "secjtag",
-		.id		= -1,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 11),
-		BD_SET(debug)
-	}, {
-		.name		= "coresight",
-		.id		= -1,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 8),
-		BD_SET(debug)
-	}, {
-		.name		= "sdm",
-		.id		= -1,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 1),
-	}, {
-		.name		= "secss",
-		.id		= -1,
-		.parent		= &clk_hclk_psys.clk,
-		.enable		= s5pv210_clk_ip2_ctrl,
-		.ctrlbit	= (1 << 0),
-		BD_SET(security)
-	}, {
-		.name		= "syscon",
-		.id		= -1,
-		.parent		= &clk_pclk_psys.clk,
-		.enable		= s5pv210_clk_ip3_ctrl,
-		.ctrlbit	= (1 << 27),
-	}, {
-		.name		= "gpio",
-		.id		= -1,
-		.parent		= &clk_pclk_psys.clk,
-		.enable		= s5pv210_clk_ip3_ctrl,
-		.ctrlbit	= (1 << 26),
-	}, {
-		.name		= "uart",
-		.id		= 0,
-		.parent		= &clk_pclk_psys.clk,
-		.enable		= s5pv210_clk_ip3_ctrl,
-		.ctrlbit	= (1 << 17),
-	}, {
-		.name		= "uart",
-		.id		= 1,
-		.parent		= &clk_pclk_psys.clk,
-		.enable		= s5pv210_clk_ip3_ctrl,
-		.ctrlbit	= (1 << 18),
-	}, {
-		.name		= "uart",
-		.id		= 2,
-		.parent		= &clk_pclk_psys.clk,
-		.enable		= s5pv210_clk_ip3_ctrl,
-		.ctrlbit	= (1 << 19),
-	}, {
-		.name		= "uart",
-		.id		= 3,
-		.parent		= &clk_pclk_psys.clk,
-		.enable		= s5pv210_clk_ip3_ctrl,
-		.ctrlbit	= (1 << 20),
-	}, {
-		.name		= "tzpc",
-		.id		= 0,
-		.parent		= &clk_pclk_msys.clk,
-		.enable		= s5pv210_clk_ip4_ctrl,
-		.ctrlbit	= (1 << 5),
-	}, {
-		.name		= "tzpc",
-		.id		= 1,
-		.parent		= &clk_pclk_psys.clk,
-		.enable		= s5pv210_clk_ip4_ctrl,
-		.ctrlbit	= (1 << 6),
-	}, {
-		.name		= "tzpc",
-		.id		= 2,
-		.enable		= s5pv210_clk_ip4_ctrl,
-		.ctrlbit	= (1 << 7),
-	}, {
-		.name		= "tzpc",
-		.id		= 3,
-		.enable		= s5pv210_clk_ip4_ctrl,
-		.ctrlbit	= (1 << 8),
+		.flags		= CLKFLAGS_BOOT_OFF,
 	},
 };
 
@@ -1757,7 +1831,6 @@ static struct clk *clks[] __initdata = {
 
 void __init s5pv210_register_clocks(void)
 {
-	struct clk *clkp;
 	int ret;
 	int ptr;
 
@@ -1771,16 +1844,6 @@ void __init s5pv210_register_clocks(void)
 	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
 	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-		(clkp->enable)(clkp, 0);
-	}
-
 #ifdef CONFIG_S5PV210_POWERDOMAIN
 	/* According to the state of the members, turn on/off power domains
 	 * and blocks. */
-- 
1.6.3.3

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

* [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
  2010-07-19  8:30     ` [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk MyungJoo Ham
  2010-07-19  8:30       ` [PATCH 4/4] ARM: S5PV210: " MyungJoo Ham
@ 2010-07-19  8:57       ` Russell King - ARM Linux
  2010-07-19 10:07       ` Maurus Cuelenaere
  2 siblings, 0 replies; 12+ messages in thread
From: Russell King - ARM Linux @ 2010-07-19  8:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 19, 2010 at 05:30:35PM +0900, MyungJoo Ham wrote:
> +#ifdef CONFIG_SAMSUNG_POWERDOMAIN
> +		if ((clk->flags | CLKFLAGS_BOOT_ON) &&

This is always true if CLKFLAGS_BOOT_ON is non-zero.

> +				!(clk->flags | CLKFLAGS_CANNOT_DISABLE)) {

This is always false if CLKFLAGS_CANNOT_DISABLE is non-zero.

> +		if (clk->enable && !(clk->flags | CLKFLAGS_CANNOT_DISABLE))

Always false...

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

* [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support
  2010-07-19  8:30   ` [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support MyungJoo Ham
  2010-07-19  8:30     ` [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk MyungJoo Ham
@ 2010-07-19  9:02     ` Russell King - ARM Linux
  1 sibling, 0 replies; 12+ messages in thread
From: Russell King - ARM Linux @ 2010-07-19  9:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 19, 2010 at 05:30:34PM +0900, MyungJoo Ham wrote:
> +static int powerdomain_set(struct powerdomain *pd, int enable)
> +{
> +	unsigned long ctrlbit;
> +	void __iomem *reg;
> +	void __iomem *stable_reg;
> +	unsigned long reg_dat;
> +
> +	if (pd == NULL)
> +		return -EINVAL;

If someone calls this function with a NULL pd argument, is it better
to ignore it, or better to use WARN_ON and get a backtrace so it can
be fixed?  I don't see much reason for this function to ever be called
with a NULL powerdomain argument.

> +
> +	ctrlbit = pd->pd_ctrlbit;
> +	reg = (void __iomem *)pd->pd_reg;
> +	stable_reg = (void __iomem *)pd->pd_stable_reg;

Why not ensure that the element in the structure is correctly typed to
start with?

It's good practice to avoid casts whenever-possible - they hide bugs.

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

* [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
  2010-07-19  8:30     ` [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk MyungJoo Ham
  2010-07-19  8:30       ` [PATCH 4/4] ARM: S5PV210: " MyungJoo Ham
  2010-07-19  8:57       ` [PATCH 3/4] ARM: SAMSUNG SoC: " Russell King - ARM Linux
@ 2010-07-19 10:07       ` Maurus Cuelenaere
  2 siblings, 0 replies; 12+ messages in thread
From: Maurus Cuelenaere @ 2010-07-19 10:07 UTC (permalink / raw)
  To: linux-arm-kernel

 Op 19-07-10 10:30, MyungJoo Ham schreef:
> Add a .flag property to the struct clk. The flag can have the following
> information:
>
> 	The clock is enabled at the boot time.
> 	The clock cannot be disabled.
> 	The clock is enabled at the boot time and cannot be disabled.
> 	The clock is disabled at the boot time. Note that both
> CLKFLAGS_BOOT_ON and CLKFLAGS_CANNOT_DISABLE can override
> CLKFLAGS_BOOT_OFF.
> 	Please stop using this clock. When a DEPRECATED clock is
> clk_get'd, clk_get function will printk a warning message.
>
> The previous patch related with powerdomain / blcok-gating control
> requires this patch for the stability related with clocks that are
> turned on at the boot time.
>
> Note that clocks without both BOOT_ON and BOOT_OFF keep the previous
> states; however, powerdomain / block-gating controls do NOT have any
> information about the states of such clocks, which in turn, may incur
> instable kernel behaviors. For example, a powerdomain may be turned off
> while a clock of the domain is still being used. With the flag support
> feature, we highly recommend to define .flag fields fully for clocks
> related to powerdomain and block-gating. Clocks not connected to
> powerdomain and block-gating are ok without flag field.
>
> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  arch/arm/plat-samsung/clock.c              |   70 ++++++++++++++++++++++++++-
>  arch/arm/plat-samsung/include/plat/clock.h |   12 +++++
>  2 files changed, 79 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
> index f8a30f7..9ff9d63 100644
> --- a/arch/arm/plat-samsung/clock.c
> +++ b/arch/arm/plat-samsung/clock.c
> @@ -103,6 +103,14 @@ struct clk *clk_get(struct device *dev, const char *id)
>  	}
>  
>  	spin_unlock(&clocks_lock);
> +
> +	if (!IS_ERR(clk) && clk)
> +		if (clk->flags & CLKFLAGS_DEPRECATED)
> +			printk(KERN_WARNING "[%s:%d] clk %s:%d is deprecated. "
> +					"Please reconsider using it.\n",
> +					__FILE__, __LINE__, clk->name,
> +					clk->id);

What's the use of __FILE__ and __LINE__? If you wanted to print the caller you
could do something like pr_warn("[%pS]: ...", __builtin_return_address(0), ...).

Also, pr_warn(...)

> +
>  	return clk;
>  }
>  
> @@ -169,7 +177,25 @@ void clk_disable(struct clk *clk)
>  	spin_lock(&clocks_lock);
>  
>  	if ((--clk->usage) == 0) {
> -		(clk->enable)(clk, 0);
> +#ifdef CONFIG_SAMSUNG_POWERDOMAIN
> +		if ((clk->flags | CLKFLAGS_BOOT_ON) &&
> +				!(clk->flags | CLKFLAGS_CANNOT_DISABLE)) {

Russel already mentioned this, did you wanted to do (clk->flags & CLKFLAGS_*)?

> +			/* BOOT_ON became NO EFFECT. Let PD/BD be able
> +			 * to turn themselves off */
> +
> +			if (clk->pd)
> +				clk->pd->num_clks_boot_on--;
> +#ifdef CONFIG_SAMSUNG_BLOCKGATING
> +			if (clk->bd)
> +				clk->bd->num_clks_boot_on--;
> +#endif
> +			clk->flags &= ~CLKFLAGS_BOOT_ON;
> +		}
> +#endif
> +
> +		if (clk->enable && !(clk->flags | CLKFLAGS_CANNOT_DISABLE))
> +			(clk->enable)(clk, 0);
> +
>  #ifdef CONFIG_SAMSUNG_POWERDOMAIN
>  		if (clk->pd) {
>  			if (clk->pd->ref_count == 1 &&
> @@ -193,7 +219,9 @@ void clk_disable(struct clk *clk)
>  	}
>  
>  	spin_unlock(&clocks_lock);
> -	clk_disable(clk->parent);
> +
> +	if (!(clk->flags | CLKFLAGS_CANNOT_DISABLE))
> +		clk_disable(clk->parent);
>  }
>  
>  
> @@ -370,6 +398,13 @@ struct clk s3c24xx_uclk = {
>   */
>  int s3c24xx_register_clock(struct clk *clk)
>  {
> +	int ret = 0;
> +
> +	if (clk == NULL)
> +		return -EINVAL;
> +	if (clk->name == NULL)
> +		return -EINVAL;
> +
>  	if (clk->enable == NULL)
>  		clk->enable = clk_null_enable;
>  
> @@ -382,6 +417,21 @@ int s3c24xx_register_clock(struct clk *clk)
>  	list_add(&clk->list, &clocks);
>  	spin_unlock(&clocks_lock);
>  
> +	if (clk->flags & CLKFLAGS_BOOT_ON) {
> +		/* Use clk_enable, not clk->enable as clk's parent is
> +		 * also required to be turned on */
> +		clk_enable(clk);
> +
> +#ifdef CONFIG_SAMSUNG_POWERDOMAIN
> +		if (clk->pd)
> +			clk->pd->num_clks_boot_on++;
> +#endif
> +#ifdef CONFIG_SAMSUNG_BLOCKGATING
> +		if (clk->bd)
> +			clk->bd->num_clks_boot_on++;
> +#endif
> +	}
> +
>  #ifdef CONFIG_SAMSUNG_POWERDOMAIN
>  	if (clk->pd) {
>  		spin_lock(&clocks_lock);
> @@ -397,7 +447,21 @@ int s3c24xx_register_clock(struct clk *clk)
>  	}
>  #endif
>  
> -	return 0;
> +	if (clk->flags & CLKFLAGS_BOOT_OFF) {
> +		if ((clk->flags & CLKFLAGS_BOOT_ON) ||
> +				(clk->flags & CLKFLAGS_CANNOT_DISABLE)) {
> +			printk(KERN_WARNING "[%s:%d] clk %s:%d has incompatible"
> +					" initilization flags: %x.\n",
> +					__FILE__, __LINE__, clk->name, clk->id,
> +					clk->flags);

Same comment, also s/initilization/initialization/.

> +			ret = -EINVAL;
> +		} else
> +			/* Do NOT use clk_disable(clk) because clk_disable
> +			 * may disable clk's parent */
> +			ret = (clk->enable)(clk, 0);
> +	}
> +
> +	return ret;
>  }
>  
>  /**
> diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
> index bf851e1..0f7d556 100644
> --- a/arch/arm/plat-samsung/include/plat/clock.h
> +++ b/arch/arm/plat-samsung/include/plat/clock.h
> @@ -59,6 +59,17 @@ struct clk_ops {
>  	int		    (*set_parent)(struct clk *c, struct clk *parent);
>  };
>  
> +/* Note that when BOOT_ON and OFF are both not set, the kernel
> + * keeps the state initialized by the boot-loader or cpu.
> + */
> +#define CLKFLAGS_BOOT_ON	(0x1)
> +#define CLKFLAGS_CANNOT_DISABLE	(0x2)
> +#define CLKFLAGS_ALWAYS_ON	(CLKFLAGS_BOOT_ON | CLKFLAGS_CANNOT_DISABLE)
> +#define CLKFLAGS_BOOT_OFF	(0x4) /* Force off when boot */
> +#define CLKFLAGS_DEPRECATED	(0x8) /* Warn when clk_get'd */
> +/* Note that CLKFLAGS_BOOT_ON and CLKFLAGS_CANNOT_DISABLE overrides
> + * CLKFLAGS_BOOT_OFF */
> +
>  struct clk {
>  	struct list_head      list;
>  	struct module        *owner;
> @@ -79,6 +90,7 @@ struct clk {
>  	struct powerdomain	*bd;
>  	struct list_head	blockgating_list;
>  #endif
> +	unsigned int		flags;
>  };
>  
>  /* other clocks which may be registered by board support */


-- 
Maurus Cuelenaere

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

* [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags
  2010-07-19  8:30 [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags MyungJoo Ham
  2010-07-19  8:30 ` [PATCH 1/4] ARM: SAMSUNG SoC: Powerdomain/Block-gating Support MyungJoo Ham
@ 2010-07-20  1:04 ` Kukjin Kim
  2010-07-20  3:05   ` MyungJoo Ham
  1 sibling, 1 reply; 12+ messages in thread
From: Kukjin Kim @ 2010-07-20  1:04 UTC (permalink / raw)
  To: linux-arm-kernel

MyungJoo Ham wrote:
> 
> This patches add support for powerdomain, block-gating, and flags in
struct clk.
> 
> Blockgating re-uses powerdomain support scheme and depends on powerdomain
> support.
> 
> Flags support is independent from powerdomain; however, powerdomain
support
> is NOT stable without flags support. Without flags support, powerdomain
may lock
> up the system with some conditions although they are rare. Thus, when
> powerdomain or block-gating is used, flags support should be turned on for
the
> system stability. (and that's why I'm sending flags support with
> powerdomain/block-gating support).
> 
> Although powerdomain support is requred for blockgating, blockgating is
NOT
> required for powerdomain. Besides, powerdomain support is observed to
reduce
> power consumption significantly (with 2.6.29 kernel); however, blockgating
support
> didn't show any significant improvement.
> 
> 
> MyungJoo Ham (4):
>   ARM: SAMSUNG SoC: Powerdomain/Block-gating Support
>   ARM: S5PV210: Powerdomain/Clock-gating Support
>   ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
>   ARM: S5PV210: Clock Framework: Flag Support for struct clk.
> 
>  arch/arm/mach-s5pv210/Kconfig              |   17 +
>  arch/arm/mach-s5pv210/clock.c              |  906
> ++++++++++++++++++++++------
>  arch/arm/plat-samsung/Kconfig              |   19 +
>  arch/arm/plat-samsung/clock.c              |  146 +++++-
>  arch/arm/plat-samsung/include/plat/clock.h |   44 ++
>  5 files changed, 935 insertions(+), 197 deletions(-)

Already we discussed about power domain...
And actually your code is similar with my member's 2.6.29 powerdomain
scheme.
So Ben's code review about that is available to your this patch.

Following is from Ben Dooks note.

===

Powerdomain control notes
=========================

Copyright 2010 Simtec Electronics
Ben Dooks <ben@simtec.co.uk>

Code Review
-----------

The current implementation makes a number of #ifdef based additions to
the clock.c which currently lies in plat-s3c/clock.c (but to be moved
to plat-samsung/clock.c). The following are the observations from reviewing
the code as presented:

1) The use of #ifdef is not recommended, as noted before in reviews it
   makes the code hard to read, allows bugs to creep in due to code
   either being skipped, and problems when we get to the stage several
   conflicting configurations could live in the kernel.

2) The code is changing the functionality of the clk_enable() and the
   clk_disable() calls, which is bad for the following reasons:

   A) Anyone reading or modifying a driver using this API may not see
      what is going on underneath.

   B) It ties the clock to the powerdomain, if any of the current drivers
      wish to temporarily stop the clock to reduce the dynamic power
      consumption they cannot (see part A, if all drivers are resting
      in the power domain the whole domain may shutdown with a resulting
      cost to the work resumption).

   C) It ties the drivers to the specific clock implementation and thus
      restricts future use of standard drivers on future devices.

   D) It ties policy into the kernel, as it forces the power domains to
      shut down if the driver is not in use. The developer or end user
      may want to change this depending on either a device wide or usage
      case. Policy decisions are best left out of the kernel.


Part (1) is a definite barrier to merging, the code whilst functional is
both ugly and the use of #ifdefs like that are contrary to a number of
developers beliefs.

The second part is also a stumbling block, as it is likely to be commented
upon by a number of interested parties if it did come up for review. I am
certainly not happy to see this sort of invasive change to the clock system
merged. I expect others would also raise objections.

...

===

So need to another approach for it.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

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

* [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags
  2010-07-20  1:04 ` [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags Kukjin Kim
@ 2010-07-20  3:05   ` MyungJoo Ham
  2010-07-21  0:33     ` Ben Dooks
  0 siblings, 1 reply; 12+ messages in thread
From: MyungJoo Ham @ 2010-07-20  3:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 20, 2010 at 10:04 AM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> MyungJoo Ham wrote:
>>
>> This patches add support for powerdomain, block-gating, and flags in
> struct clk.
>>
>> Blockgating re-uses powerdomain support scheme and depends on powerdomain
>> support.
>>
>> Flags support is independent from powerdomain; however, powerdomain
> support
>> is NOT stable without flags support. Without flags support, powerdomain
> may lock
>> up the system with some conditions although they are rare. Thus, when
>> powerdomain or block-gating is used, flags support should be turned on for
> the
>> system stability. (and that's why I'm sending flags support with
>> powerdomain/block-gating support).
>>
>> Although powerdomain support is requred for blockgating, blockgating is
> NOT
>> required for powerdomain. Besides, powerdomain support is observed to
> reduce
>> power consumption significantly (with 2.6.29 kernel); however, blockgating
> support
>> didn't show any significant improvement.
>>
>>
>> MyungJoo Ham (4):
>> ? ARM: SAMSUNG SoC: Powerdomain/Block-gating Support
>> ? ARM: S5PV210: Powerdomain/Clock-gating Support
>> ? ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
>> ? ARM: S5PV210: Clock Framework: Flag Support for struct clk.
>>
>> ?arch/arm/mach-s5pv210/Kconfig ? ? ? ? ? ? ?| ? 17 +
>> ?arch/arm/mach-s5pv210/clock.c ? ? ? ? ? ? ?| ?906
>> ++++++++++++++++++++++------
>> ?arch/arm/plat-samsung/Kconfig ? ? ? ? ? ? ?| ? 19 +
>> ?arch/arm/plat-samsung/clock.c ? ? ? ? ? ? ?| ?146 +++++-
>> ?arch/arm/plat-samsung/include/plat/clock.h | ? 44 ++
>> ?5 files changed, 935 insertions(+), 197 deletions(-)
>
> Already we discussed about power domain...
> And actually your code is similar with my member's 2.6.29 powerdomain
> scheme.
> So Ben's code review about that is available to your this patch.
>
> Following is from Ben Dooks note.
>
> ===
>
> Powerdomain control notes
> =========================
>
> Copyright 2010 Simtec Electronics
> Ben Dooks <ben@simtec.co.uk>
>
> Code Review
> -----------
>
> The current implementation makes a number of #ifdef based additions to
> the clock.c which currently lies in plat-s3c/clock.c (but to be moved
> to plat-samsung/clock.c). The following are the observations from reviewing
> the code as presented:
>
> 1) The use of #ifdef is not recommended, as noted before in reviews it
> ? makes the code hard to read, allows bugs to creep in due to code
> ? either being skipped, and problems when we get to the stage several
> ? conflicting configurations could live in the kernel.

I've been using #ifdef's for enabling/disabling powerdomain and
blockgating control (especially for machines that do not have support
for powerdomain/blockgating). However, it seems to be reasonable that
the #ifdef's are not needed and to be removed.

>
> 2) The code is changing the functionality of the clk_enable() and the
> ? clk_disable() calls, which is bad for the following reasons:
>
> ? A) Anyone reading or modifying a driver using this API may not see
> ? ? ?what is going on underneath.
>
> ? B) It ties the clock to the powerdomain, if any of the current drivers
> ? ? ?wish to temporarily stop the clock to reduce the dynamic power
> ? ? ?consumption they cannot (see part A, if all drivers are resting
> ? ? ?in the power domain the whole domain may shutdown with a resulting
> ? ? ?cost to the work resumption).
>
> ? C) It ties the drivers to the specific clock implementation and thus
> ? ? ?restricts future use of standard drivers on future devices.
>
> ? D) It ties policy into the kernel, as it forces the power domains to
> ? ? ?shut down if the driver is not in use. The developer or end user
> ? ? ?may want to change this depending on either a device wide or usage
> ? ? ?case. Policy decisions are best left out of the kernel.
>

Um... yes, putting powerdomain/blockgating code at clk_* code is too
invasive to the clk_* code. And it'd be more problematic if we move on
to the common struct clk.

I'll implement powerdomain/blockgating control code
 at arch/arm/mach-s5pv210/clock.c:s5pv210_clk_*_ctrl.

For B) and D), we may need to leave an option not to control
powerdomain. How about leaving an option at sysfs if not using
#ifdef's?


>
> Part (1) is a definite barrier to merging, the code whilst functional is
> both ugly and the use of #ifdefs like that are contrary to a number of
> developers beliefs.
>
> The second part is also a stumbling block, as it is likely to be commented
> upon by a number of interested parties if it did come up for review. I am
> certainly not happy to see this sort of invasive change to the clock system
> merged. I expect others would also raise objections.
>
> ...
>
> ===
>
> So need to another approach for it.
>
> Thanks.
>
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
>



-- 
MyungJoo Ham (???), Ph.D.
Mobile Software Platform Lab,
Digital Media and Communications (DMC) Business
Samsung Electronics
cell: 82-10-6714-2858

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

* [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags
  2010-07-20  3:05   ` MyungJoo Ham
@ 2010-07-21  0:33     ` Ben Dooks
  2010-07-21  7:23       ` MyungJoo Ham
  0 siblings, 1 reply; 12+ messages in thread
From: Ben Dooks @ 2010-07-21  0:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/20/10 04:05, MyungJoo Ham wrote:
> On Tue, Jul 20, 2010 at 10:04 AM, Kukjin Kim<kgene.kim@samsung.com>  wrote:
>> MyungJoo Ham wrote:
>>>
>>> This patches add support for powerdomain, block-gating, and flags in
>> struct clk.
>>>
>>> Blockgating re-uses powerdomain support scheme and depends on powerdomain
>>> support.
>>>
>>> Flags support is independent from powerdomain; however, powerdomain
>> support
>>> is NOT stable without flags support. Without flags support, powerdomain
>> may lock
>>> up the system with some conditions although they are rare. Thus, when
>>> powerdomain or block-gating is used, flags support should be turned on for
>> the
>>> system stability. (and that's why I'm sending flags support with
>>> powerdomain/block-gating support).
>>>
>>> Although powerdomain support is requred for blockgating, blockgating is
>> NOT
>>> required for powerdomain. Besides, powerdomain support is observed to
>> reduce
>>> power consumption significantly (with 2.6.29 kernel); however, blockgating
>> support
>>> didn't show any significant improvement.
>>>
>>>
>>> MyungJoo Ham (4):
>>>    ARM: SAMSUNG SoC: Powerdomain/Block-gating Support
>>>    ARM: S5PV210: Powerdomain/Clock-gating Support
>>>    ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
>>>    ARM: S5PV210: Clock Framework: Flag Support for struct clk.
>>>
>>>   arch/arm/mach-s5pv210/Kconfig              |   17 +
>>>   arch/arm/mach-s5pv210/clock.c              |  906
>>> ++++++++++++++++++++++------
>>>   arch/arm/plat-samsung/Kconfig              |   19 +
>>>   arch/arm/plat-samsung/clock.c              |  146 +++++-
>>>   arch/arm/plat-samsung/include/plat/clock.h |   44 ++
>>>   5 files changed, 935 insertions(+), 197 deletions(-)
>>
>> Already we discussed about power domain...
>> And actually your code is similar with my member's 2.6.29 powerdomain
>> scheme.
>> So Ben's code review about that is available to your this patch.
>>
>> Following is from Ben Dooks note.
>>
>> ===

My powers of psychic prediction are legendary now :0)

>> Powerdomain control notes
>> =========================
>>
>> Copyright 2010 Simtec Electronics
>> Ben Dooks<ben@simtec.co.uk>
>>
>> Code Review
>> -----------
>>
>> The current implementation makes a number of #ifdef based additions to
>> the clock.c which currently lies in plat-s3c/clock.c (but to be moved
>> to plat-samsung/clock.c). The following are the observations from reviewing
>> the code as presented:
>>
>> 1) The use of #ifdef is not recommended, as noted before in reviews it
>>    makes the code hard to read, allows bugs to creep in due to code
>>    either being skipped, and problems when we get to the stage several
>>    conflicting configurations could live in the kernel.
>
> I've been using #ifdef's for enabling/disabling powerdomain and
> blockgating control (especially for machines that do not have support
> for powerdomain/blockgating). However, it seems to be reasonable that
> the #ifdef's are not needed and to be removed.
>
>>
>> 2) The code is changing the functionality of the clk_enable() and the
>>    clk_disable() calls, which is bad for the following reasons:
>>
>>    A) Anyone reading or modifying a driver using this API may not see
>>       what is going on underneath.
>>
>>    B) It ties the clock to the powerdomain, if any of the current drivers
>>       wish to temporarily stop the clock to reduce the dynamic power
>>       consumption they cannot (see part A, if all drivers are resting
>>       in the power domain the whole domain may shutdown with a resulting
>>       cost to the work resumption).
>>
>>    C) It ties the drivers to the specific clock implementation and thus
>>       restricts future use of standard drivers on future devices.
>>
>>    D) It ties policy into the kernel, as it forces the power domains to
>>       shut down if the driver is not in use. The developer or end user
>>       may want to change this depending on either a device wide or usage
>>       case. Policy decisions are best left out of the kernel.
>>
>
> Um... yes, putting powerdomain/blockgating code at clk_* code is too
> invasive to the clk_* code. And it'd be more problematic if we move on
> to the common struct clk.

As a note, you could add virtual clocks, one per power domain which
have their enable function point into the power domain code. This
should be called each time the clock is enabled/disabled and thus
allows easier integration that the current method. It should also
avoid a pile of #ifdefs.

> I'll implement powerdomain/blockgating control code
>   at arch/arm/mach-s5pv210/clock.c:s5pv210_clk_*_ctrl.
>
> For B) and D), we may need to leave an option not to control
> powerdomain. How about leaving an option at sysfs if not using
> #ifdef's?

I'd like to see something more generic, however this approach has
its own merits. The plus side is it'll save power, the down sides
are as follows:

1) Drivers are now losing their clock _and_ power, really the driver
    should be quiesced by runtime-pm otherwise we end up relying on
    the lower level behaviour of the clock system (undocumented) and
    having drivers have to restore settings when they do clk_enable()

    This is fine for Samsung specific drivers, but is going to be really
    bad for everyone else.

2) Some devices, such as the SDHCI need clocks after the operation has
    finished to allow cards to complete

3) How much time is spent taking the power domains up/down? Is this time
    we could be usefully using to actually do work for the user?

The big one here is #1.

I would much prefer to see some framework which controls when devices
are going to be scheduled so that they can be put to sleep when it is
unlikely they're going to be used, and the system's performance can be
controlled (ie, if the device is in hard-use, such as decoding video
it is probably unlikely we'll want to shutdown the data source at-all)
another example would be if the device is idling, it would be very
permissible to shut things down when they are not in use as the system
does not need a lot of performance at that point.

I've suggested hooking power-domain support into the regulator framework
but Mark's pointed out some problems there. it may be worth using the
regulator framework as a low-level system so that regulators can be
chained off (ie, control external ldos/switches/etc).

I'd be happier to see something where the device drivers use runtime pm
(possibly with the regulator framework) to allow the user to stop the
system. We could also look at device in-use doing auto runtime-pm to
say open => resume, and close => suspend.

>> Part (1) is a definite barrier to merging, the code whilst functional is
>> both ugly and the use of #ifdefs like that are contrary to a number of
>> developers beliefs.
>>
>> The second part is also a stumbling block, as it is likely to be commented
>> upon by a number of interested parties if it did come up for review. I am
>> certainly not happy to see this sort of invasive change to the clock system
>> merged. I expect others would also raise objections.
>>
>> ...
>>
>> ===
>>
>> So need to another approach for it.

It certainly needs a pile of work before we can think about it.

>> Thanks.
>>
>> Best regards,
>> Kgene.
>> --
>> Kukjin Kim<kgene.kim@samsung.com>, Senior Engineer,
>> SW Solution Development Team, Samsung Electronics Co., Ltd.


-- 
Ben Dooks, Design & Software Engineer, Simtec Electronics

http://www.simtec.co.uk/

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

* [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags
  2010-07-21  0:33     ` Ben Dooks
@ 2010-07-21  7:23       ` MyungJoo Ham
  0 siblings, 0 replies; 12+ messages in thread
From: MyungJoo Ham @ 2010-07-21  7:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 21, 2010 at 9:33 AM, Ben Dooks <ben@simtec.co.uk> wrote:
> On 07/20/10 04:05, MyungJoo Ham wrote:
>>
>> On Tue, Jul 20, 2010 at 10:04 AM, Kukjin Kim<kgene.kim@samsung.com>
>> ?wrote:
>>>
>>> MyungJoo Ham wrote:
>>>>
>>>> This patches add support for powerdomain, block-gating, and flags in
>>>
>>> struct clk.
>>>>
>>>> Blockgating re-uses powerdomain support scheme and depends on
>>>> powerdomain
>>>> support.
>>>>
>>>> Flags support is independent from powerdomain; however, powerdomain
>>>
>>> support
>>>>
>>>> is NOT stable without flags support. Without flags support, powerdomain
>>>
>>> may lock
>>>>
>>>> up the system with some conditions although they are rare. Thus, when
>>>> powerdomain or block-gating is used, flags support should be turned on
>>>> for
>>>
>>> the
>>>>
>>>> system stability. (and that's why I'm sending flags support with
>>>> powerdomain/block-gating support).
>>>>
>>>> Although powerdomain support is requred for blockgating, blockgating is
>>>
>>> NOT
>>>>
>>>> required for powerdomain. Besides, powerdomain support is observed to
>>>
>>> reduce
>>>>
>>>> power consumption significantly (with 2.6.29 kernel); however,
>>>> blockgating
>>>
>>> support
>>>>
>>>> didn't show any significant improvement.
>>>>
>>>>
>>>> MyungJoo Ham (4):
>>>> ? ARM: SAMSUNG SoC: Powerdomain/Block-gating Support
>>>> ? ARM: S5PV210: Powerdomain/Clock-gating Support
>>>> ? ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk.
>>>> ? ARM: S5PV210: Clock Framework: Flag Support for struct clk.
>>>>
>>>> ?arch/arm/mach-s5pv210/Kconfig ? ? ? ? ? ? ?| ? 17 +
>>>> ?arch/arm/mach-s5pv210/clock.c ? ? ? ? ? ? ?| ?906
>>>> ++++++++++++++++++++++------
>>>> ?arch/arm/plat-samsung/Kconfig ? ? ? ? ? ? ?| ? 19 +
>>>> ?arch/arm/plat-samsung/clock.c ? ? ? ? ? ? ?| ?146 +++++-
>>>> ?arch/arm/plat-samsung/include/plat/clock.h | ? 44 ++
>>>> ?5 files changed, 935 insertions(+), 197 deletions(-)
>>>
>>> Already we discussed about power domain...
>>> And actually your code is similar with my member's 2.6.29 powerdomain
>>> scheme.
>>> So Ben's code review about that is available to your this patch.
>>>
>>> Following is from Ben Dooks note.
>>>
>>> ===
>
> My powers of psychic prediction are legendary now :0)

:D

>
>>> Powerdomain control notes
>>> =========================
>>>
>>> Copyright 2010 Simtec Electronics
>>> Ben Dooks<ben@simtec.co.uk>
>>>
>>> Code Review
>>> -----------
>>>
>>> The current implementation makes a number of #ifdef based additions to
>>> the clock.c which currently lies in plat-s3c/clock.c (but to be moved
>>> to plat-samsung/clock.c). The following are the observations from
>>> reviewing
>>> the code as presented:
>>>
>>> 1) The use of #ifdef is not recommended, as noted before in reviews it
>>> ? makes the code hard to read, allows bugs to creep in due to code
>>> ? either being skipped, and problems when we get to the stage several
>>> ? conflicting configurations could live in the kernel.
>>
>> I've been using #ifdef's for enabling/disabling powerdomain and
>> blockgating control (especially for machines that do not have support
>> for powerdomain/blockgating). However, it seems to be reasonable that
>> the #ifdef's are not needed and to be removed.
>>
>>>
>>> 2) The code is changing the functionality of the clk_enable() and the
>>> ? clk_disable() calls, which is bad for the following reasons:
>>>
>>> ? A) Anyone reading or modifying a driver using this API may not see
>>> ? ? ?what is going on underneath.
>>>
>>> ? B) It ties the clock to the powerdomain, if any of the current drivers
>>> ? ? ?wish to temporarily stop the clock to reduce the dynamic power
>>> ? ? ?consumption they cannot (see part A, if all drivers are resting
>>> ? ? ?in the power domain the whole domain may shutdown with a resulting
>>> ? ? ?cost to the work resumption).
>>>
>>> ? C) It ties the drivers to the specific clock implementation and thus
>>> ? ? ?restricts future use of standard drivers on future devices.
>>>
>>> ? D) It ties policy into the kernel, as it forces the power domains to
>>> ? ? ?shut down if the driver is not in use. The developer or end user
>>> ? ? ?may want to change this depending on either a device wide or usage
>>> ? ? ?case. Policy decisions are best left out of the kernel.
>>>
>>
>> Um... yes, putting powerdomain/blockgating code at clk_* code is too
>> invasive to the clk_* code. And it'd be more problematic if we move on
>> to the common struct clk.
>
> As a note, you could add virtual clocks, one per power domain which
> have their enable function point into the power domain code. This
> should be called each time the clock is enabled/disabled and thus
> allows easier integration that the current method. It should also
> avoid a pile of #ifdefs.

We've been using so-called virtual clocks for power domains that does
not have corresponding clocks (i.e., irom in S5PV210).

Because there are multiple clocks ties to a powerdomain and a
powerdomain should be turned on when one of them is turned on, using
powerdomain virtual clock as a parent can enable powerdomain feature.
However, unless we allow multiple parents per clock, this forces
clocks to lose their original parents; so, it's NO. The powerdomain
implementation in this revision of patch tried to add another "parent"
property at struct clk. In the next revision (which is under testing),
we separate powerdomain/blockgating feature from struct clk and do it
at mach-s5pv210/clock.c independently from platform's clk, which do
not have any #ifdefs or modifications in plat-*/*

>
>> I'll implement powerdomain/blockgating control code
>> ?at arch/arm/mach-s5pv210/clock.c:s5pv210_clk_*_ctrl.
>>
>> For B) and D), we may need to leave an option not to control
>> powerdomain. How about leaving an option at sysfs if not using
>> #ifdef's?
>
> I'd like to see something more generic, however this approach has
> its own merits. The plus side is it'll save power, the down sides
> are as follows:
>
> 1) Drivers are now losing their clock _and_ power, really the driver
> ? should be quiesced by runtime-pm otherwise we end up relying on
> ? the lower level behaviour of the clock system (undocumented) and
> ? having drivers have to restore settings when they do clk_enable()
>
> ? This is fine for Samsung specific drivers, but is going to be really
> ? bad for everyone else.

I think this issue is somewhat mitigated by implementing this feature
only at mach-s5pv210/*.

Besides, in order to avoid saving/restoring settings when drivers do
clk_enable/clk_disable, I've defined struct register_save *normal_ff,
which saves non-retention registers, which lose values when a
powerdomain is off. (well.. the list of those registers is not filled,
yet.) Thus, drivers do not need to do so as long as we fill these
lists out. Doing so allows us to do powerdomain control transparently
from drivers.

However, most drivers related with powerdomain seemed to be ok to lose
register values after clk_disable is called except for the audio
driver so far. So I'm thinking about saving those registers
selectively in S5PV210 although this breaks the transparency.

>
> 2) Some devices, such as the SDHCI need clocks after the operation has
> ? finished to allow cards to complete

If SDHCI needs clocks after the operation, isn't it holding its clk as
enabled and delaying clk_disable()? Does SDHCI call clk_disable()
while its clock is required to be left turned on? For devices required
to be "always on", there is the "ALWAYS_ON" flag. (and the powerdomain
control recognizes it.)

>
> 3) How much time is spent taking the power domains up/down? Is this time
> ? we could be usefully using to actually do work for the user?

When we counted the wait-for-stabilization loop iteration (e.g., do {
count++; } while(not stable);) the count value was somewhere around 12
~ 20.
When it does not need to access powerdomain (not connected with a
powerdomain or the powerdomain is already at the wanted state), it
skips accessing it.

>
> The big one here is #1.
>
> I would much prefer to see some framework which controls when devices
> are going to be scheduled so that they can be put to sleep when it is
> unlikely they're going to be used, and the system's performance can be
> controlled (ie, if the device is in hard-use, such as decoding video
> it is probably unlikely we'll want to shutdown the data source at-all)
> another example would be if the device is idling, it would be very
> permissible to shut things down when they are not in use as the system
> does not need a lot of performance at that point.
>
> I've suggested hooking power-domain support into the regulator framework
> but Mark's pointed out some problems there. it may be worth using the
> regulator framework as a low-level system so that regulators can be
> chained off (ie, control external ldos/switches/etc).

Um. yes.. I also thought about supporting powerdomain at regulator
framework, but the tight coupling between clocks and
powerdomains/blockgating combined with the problem of ALWAYS_ON and
BOOT_ON clocks makes it inadequate; we need to monitor the states of
related clocks even if those clocks were never "clk_enable"d. Because
we need to look at the related clocks before turning on and off
powerdomain, I think powerdomain would be better reside in clock
framework or machine implementation. Otherwise, we'll end up coupling
another framework with clock framework deeply.

Or... maybe _if_ it's ok to access clock-related registers at
regulator framework directly without accessing via clock framework (I
don't like this idea.. but), we may be able to implement powerdomain
at regulator framework by allowing regulator framework to look at the
states of related clocks. In that way, we can avoid turning off
powerdomains that should not be.

>
> I'd be happier to see something where the device drivers use runtime pm
> (possibly with the regulator framework) to allow the user to stop the
> system. We could also look at device in-use doing auto runtime-pm to
> say open => resume, and close => suspend.
>

This way we are putting more burdens to drivers (at least they need to
add regulators and enable/disable them), but I agree that this would
help implement realtime_pm.




>>> Part (1) is a definite barrier to merging, the code whilst functional is
>>> both ugly and the use of #ifdefs like that are contrary to a number of
>>> developers beliefs.
>>>
>>> The second part is also a stumbling block, as it is likely to be
>>> commented
>>> upon by a number of interested parties if it did come up for review. I am
>>> certainly not happy to see this sort of invasive change to the clock
>>> system
>>> merged. I expect others would also raise objections.
>>>
>>> ...
>>>
>>> ===
>>>
>>> So need to another approach for it.
>
> It certainly needs a pile of work before we can think about it.
>
>>> Thanks.
>>>
>>> Best regards,
>>> Kgene.
>>> --
>>> Kukjin Kim<kgene.kim@samsung.com>, Senior Engineer,
>>> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
>
> --
> Ben Dooks, Design & Software Engineer, Simtec Electronics
>
> http://www.simtec.co.uk/
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>



-- 
MyungJoo Ham (???), Ph.D.
Mobile Software Platform Lab,
Digital Media and Communications (DMC) Business
Samsung Electronics
cell: 82-10-6714-2858

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

end of thread, other threads:[~2010-07-21  7:23 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-19  8:30 [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags MyungJoo Ham
2010-07-19  8:30 ` [PATCH 1/4] ARM: SAMSUNG SoC: Powerdomain/Block-gating Support MyungJoo Ham
2010-07-19  8:30   ` [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support MyungJoo Ham
2010-07-19  8:30     ` [PATCH 3/4] ARM: SAMSUNG SoC: Clock Framework: Flag Support for struct clk MyungJoo Ham
2010-07-19  8:30       ` [PATCH 4/4] ARM: S5PV210: " MyungJoo Ham
2010-07-19  8:57       ` [PATCH 3/4] ARM: SAMSUNG SoC: " Russell King - ARM Linux
2010-07-19 10:07       ` Maurus Cuelenaere
2010-07-19  9:02     ` [PATCH 2/4] ARM: S5PV210: Powerdomain/Clock-gating Support Russell King - ARM Linux
2010-07-20  1:04 ` [PATCH 0/4] ARM: S5PV210: Clock Framework: powerdomain, block-gating, flags Kukjin Kim
2010-07-20  3:05   ` MyungJoo Ham
2010-07-21  0:33     ` Ben Dooks
2010-07-21  7:23       ` MyungJoo Ham

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).