public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Russell King - ARM Linux <linux@arm.linux.org.uk>
To: Paul Walmsley <paul@pwsan.com>
Cc: linux-arm-kernel@lists.arm.linux.org.uk,
	linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
	Tony Lindgren <tony@atomide.com>
Subject: Re: [PATCH E 11/14] OMAP clock: track child clocks
Date: Thu, 29 Jan 2009 22:06:08 +0000	[thread overview]
Message-ID: <20090129220608.GJ18233@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20090129151401.GC18233@n2100.arm.linux.org.uk>

On Thu, Jan 29, 2009 at 03:14:01PM +0000, Russell King - ARM Linux wrote:
> On Wed, Jan 28, 2009 at 12:27:59PM -0700, Paul Walmsley wrote:
> > The price paid is additional runtime memory consumption - 8 bytes per
> > clock and 16 bytes per child clock - roughly 4.5KiB on OMAP3.
> 
> For OMAP3, that's 222 struct clks of which 182 are children, and indeed
> 222 * 8 + 182 * 16 gives about 4.5K.  On OMAP2, it's 140 and 136,
> giving 140 * 8 + 136 * 16 = 3.3K.
> 
> Moving struct clk_child into struct clk means that its clk and flags
> members can be deleted, making it 8 bytes in size - effectively just
> the list_head.  We need a list_head for the 'children' as you have it.
> So, that works out as 16 bytes per clock.  That gives 3.5K on OMAP3
> and 2.2K on OMAP2.
> 
> So, by taking that alternative approach, not only do you end up using
> less memory, but you also don't have to have the overhead of your
> custom memory bookkeeping.
> 
> The other change I'd suggest is that you have one function which deals
> with setting the parent of a clock:
> 
> void clk_reparent(struct clk *child, struct clk *parent)
> {
> 	list_del_init(&child->sibling);
> 	if (parent)
> 		list_add(&child->sibling, &parent->children);
> 	child->parent = parent;
> 
> 	/* now do the debugfs renaming to reattach the child
> 	   to the proper parent */
> }
> 
> which is a lot simpler than your omap_clk_add_child() and omap_clk_del_child().
> 
> These should be in the _core_ OMAP clock code, not just in the OMAP2
> clock code.  OMAP1 has child clocks as well as OMAP2.

And here is my version of this patch:

 arch/arm/mach-omap2/clock.c             |    4 +-
 arch/arm/plat-omap/clock.c              |   49 +++++++++++++++++++------------
 arch/arm/plat-omap/include/mach/clock.h |    3 ++
 3 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 56d9ea4..14bf566 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -175,7 +175,7 @@ void omap2_init_clksel_parent(struct clk *clk)
 						 clk->name, clks->parent->name,
 						 ((clk->parent) ?
 						  clk->parent->name : "NULL"));
-					clk->parent = clks->parent;
+					clk_reparent(clk, clks->parent);
 				};
 				found = 1;
 			}
@@ -780,7 +780,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 	if (clk->usecount > 0)
 		_omap2_clk_enable(clk);
 
-	clk->parent = new_parent;
+	clk_reparent(clk, new_parent);
 
 	/* CLKSEL clocks follow their parents' rates, divided by a divisor */
 	clk->rate = new_parent->rate;
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 3688400..58e42b1 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -127,8 +127,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (ret == 0) {
 		if (clk->recalc)
 			clk->recalc(clk);
-		if (clk->flags & RATE_PROPAGATES)
-			propagate_rate(clk);
+		propagate_rate(clk);
 	}
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
@@ -150,8 +149,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	if (ret == 0) {
 		if (clk->recalc)
 			clk->recalc(clk);
-		if (clk->flags & RATE_PROPAGATES)
-			propagate_rate(clk);
+		propagate_rate(clk);
 	}
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
@@ -192,27 +190,34 @@ void followparent_recalc(struct clk *clk)
 	clk->rate = clk->parent->rate;
 }
 
+void clk_reparent(struct clk *child, struct clk *parent)
+{
+	list_del_init(&child->sibling);
+	if (parent)
+		list_add(&child->sibling, &parent->children);
+	child->parent = parent;
+
+	/* now do the debugfs renaming to reattach the child
+	   to the proper parent */
+}
+
 /* Propagate rate to children */
 void propagate_rate(struct clk * tclk)
 {
 	struct clk *clkp;
 
-	if (tclk == NULL || IS_ERR(tclk))
-		return;
-
-	list_for_each_entry(clkp, &clocks, node) {
-		if (likely(clkp->parent != tclk))
-			continue;
+	list_for_each_entry(clkp, &tclk->children, sibling) {
 		if (clkp->recalc) {
 			unsigned long old_rate = clkp->rate;
 			clkp->recalc(clkp);
-			if (clkp->rate != old_rate &&
-			    (clkp->flags & RATE_PROPAGATES))
+			if (clkp->rate != old_rate)
 				propagate_rate(clkp);
 		}
 	}
 }
 
+static LIST_HEAD(root_clks);
+
 /**
  * recalculate_root_clocks - recalculate and propagate all root clocks
  *
@@ -224,13 +229,10 @@ void recalculate_root_clocks(void)
 {
 	struct clk *clkp;
 
-	list_for_each_entry(clkp, &clocks, node) {
-		if (!clkp->parent) {
-			if (clkp->recalc)
-				clkp->recalc(clkp);
-			if (clkp->flags & RATE_PROPAGATES)
-				propagate_rate(clkp);
-		}
+	list_for_each_entry(clkp, &root_clks, sibling) {
+		if (clkp->recalc)
+			clkp->recalc(clkp);
+		propagate_rate(clkp);
 	}
 }
 
@@ -246,6 +248,15 @@ int clk_register(struct clk *clk)
 		return 0;
 
 	mutex_lock(&clocks_mutex);
+	if (!clk->children.next)
+		INIT_LIST_HEAD(&clk->children);
+	if (clk->parent && !clk->parent->children.next)
+		INIT_LIST_HEAD(&clk->parent->children);
+	if (clk->parent)
+		list_add(&clk->sibling, &clk->parent->children);
+	else
+		list_add(&clk->sibling, &root_clks);
+
 	list_add(&clk->node, &clocks);
 	if (clk->init)
 		clk->init(clk);
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
index ad0345f..3504c2b 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -70,6 +70,8 @@ struct clk {
 	const char		*name;
 	int			id;
 	struct clk		*parent;
+	struct list_head	children;
+	struct list_head	sibling;	/* node for children */
 	unsigned long		rate;
 	__u32			flags;
 	void __iomem		*enable_reg;
@@ -116,6 +118,7 @@ extern unsigned int mpurate;
 
 extern int clk_init(struct clk_functions *custom_clocks);
 extern int clk_register(struct clk *clk);
+extern void clk_reparent(struct clk *child, struct clk *parent);
 extern void clk_unregister(struct clk *clk);
 extern void propagate_rate(struct clk *clk);
 extern void recalculate_root_clocks(void);

  reply	other threads:[~2009-01-29 22:06 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-28 19:27 [PATCH E 00/14] OMAP clock, E of F: SDRAM fixes, clock optimization Paul Walmsley
2009-01-28 19:27 ` [PATCH E 01/14] OMAP2 SDRC: move mach-omap2/memory.h into include/asm-arm/arch-omap/sdrc.h Paul Walmsley
2009-01-28 19:27 ` [PATCH E 02/14] OMAP2 SDRC: rename memory.c to sdrc2xxx.c Paul Walmsley
2009-01-28 19:27 ` [PATCH E 03/14] OMAP2 SDRC: separate common OMAP2/3 code from OMAP2xxx code Paul Walmsley
2009-01-28 19:27 ` [PATCH E 04/14] OMAP2 SDRC: add SDRAM timing parameter infrastructure Paul Walmsley
2009-01-28 19:27 ` [PATCH E 05/14] OMAP3 clock: add omap3_core_dpll_m2_set_rate() Paul Walmsley
2009-01-28 19:27 ` [PATCH E 06/14] PM: OMAP3: Make sure clk_disable_unused() order is correct Paul Walmsley
2009-01-28 19:27 ` [PATCH E 07/14] OMAP2/3 clock: use standard set_rate fn in omap2_clk_arch_init() Paul Walmsley
2009-01-28 19:27 ` [PATCH E 08/14] OMAP clock: move rate recalc, propagation code up to plat-omap/clock.c Paul Walmsley
2009-01-29 17:41   ` Russell King - ARM Linux
2009-01-30  8:42     ` Paul Walmsley
2009-01-30  8:52       ` Russell King - ARM Linux
2009-01-30 14:23         ` Woodruff, Richard
2009-01-31 11:40           ` Russell King - ARM Linux
2009-02-03  8:42             ` Paul Walmsley
2009-02-03  9:45             ` Paul Walmsley
2009-02-02  7:13       ` Paul Walmsley
2009-02-03 13:18         ` Russell King - ARM Linux
2009-01-28 19:27 ` [PATCH E 09/14] OMAP2/3 clock: drop recalc function pointers from fixed rate clocks Paul Walmsley
2009-01-28 19:27 ` [PATCH E 10/14] OMAP clock: support "dry run" rate and parent changes Paul Walmsley
2009-02-08 13:17   ` Russell King - ARM Linux
2009-02-08 19:48     ` David Brownell
2009-02-11  7:53     ` Paul Walmsley
2009-02-08 15:53   ` Russell King - ARM Linux
2009-02-11  8:18     ` Paul Walmsley
2009-01-28 19:27 ` [PATCH E 11/14] OMAP clock: track child clocks Paul Walmsley
2009-01-29 15:14   ` Russell King - ARM Linux
2009-01-29 22:06     ` Russell King - ARM Linux [this message]
2009-01-30  8:35       ` Paul Walmsley
2009-02-02  4:57       ` Paul Walmsley
2009-02-09 14:11       ` Russell King - ARM Linux
2009-02-13  7:01         ` Paul Walmsley
2009-02-14 11:23           ` Russell King - ARM Linux
2009-02-14 11:36             ` Russell King - ARM Linux
2009-02-25  9:45               ` Paul Walmsley
2009-02-19 12:19             ` Russell King - ARM Linux
2009-02-20  0:50               ` Woodruff, Richard
2009-02-23 16:03                 ` Russell King - ARM Linux
2009-02-24 12:35                   ` Woodruff, Richard
2009-03-02 23:02                   ` Paul Walmsley
2009-03-03 16:45                     ` Russell King - ARM Linux
2009-02-22 23:37             ` Paul Walmsley
2009-02-24  9:43               ` Russell King - ARM Linux
2009-01-29 19:52   ` Russell King - ARM Linux
2009-02-02  7:57     ` Paul Walmsley
2009-01-28 19:28 ` [PATCH E 12/14] OMAP clock: unnecessary clock flag removal fiesta Paul Walmsley
2009-02-23 15:50   ` Russell King - ARM Linux
2009-03-02 22:35     ` Paul Walmsley
2009-01-28 19:28 ` [PATCH E 13/14] OMAP2/3 clock: remove clk->owner Paul Walmsley
2009-01-28 19:28 ` [PATCH E 14/14] OMAP clock: rearrange clock.h structure order Paul Walmsley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090129220608.GJ18233@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.arm.linux.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.com \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox