aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/clock.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-01-31 05:05:51 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-08 12:50:42 -0500
commit3f0a820c4c0b4670fb5f164baa5582e23c2ef118 (patch)
tree6af02e1456c0316791ab95e7da9c09496f29c232 /arch/arm/plat-omap/clock.c
parentb5088c0d90b898802318c62caf2320a53df6ce57 (diff)
[ARM] omap: create a proper tree of clocks
Traditionally, we've tracked the parent/child relationships between clk structures by setting the child's parent member to point at the upstream clock. As a result, when decending the tree, we have had to scan all clocks to find the children. Avoid this wasteful scanning by keeping a list of the clock's children. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/plat-omap/clock.c')
-rw-r--r--arch/arm/plat-omap/clock.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 54da27af0bd5..6a1737a74477 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -143,8 +143,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
143 if (ret == 0) { 143 if (ret == 0) {
144 if (clk->recalc) 144 if (clk->recalc)
145 clk->recalc(clk); 145 clk->recalc(clk);
146 if (clk->flags & RATE_PROPAGATES) 146 propagate_rate(clk);
147 propagate_rate(clk);
148 } 147 }
149 spin_unlock_irqrestore(&clockfw_lock, flags); 148 spin_unlock_irqrestore(&clockfw_lock, flags);
150 149
@@ -166,8 +165,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
166 if (ret == 0) { 165 if (ret == 0) {
167 if (clk->recalc) 166 if (clk->recalc)
168 clk->recalc(clk); 167 clk->recalc(clk);
169 if (clk->flags & RATE_PROPAGATES) 168 propagate_rate(clk);
170 propagate_rate(clk);
171 } 169 }
172 spin_unlock_irqrestore(&clockfw_lock, flags); 170 spin_unlock_irqrestore(&clockfw_lock, flags);
173 171
@@ -214,24 +212,31 @@ void followparent_recalc(struct clk *clk)
214 clk->rate = clk->parent->rate; 212 clk->rate = clk->parent->rate;
215} 213}
216 214
215void clk_reparent(struct clk *child, struct clk *parent)
216{
217 list_del_init(&child->sibling);
218 if (parent)
219 list_add(&child->sibling, &parent->children);
220 child->parent = parent;
221
222 /* now do the debugfs renaming to reattach the child
223 to the proper parent */
224}
225
217/* Propagate rate to children */ 226/* Propagate rate to children */
218void propagate_rate(struct clk * tclk) 227void propagate_rate(struct clk * tclk)
219{ 228{
220 struct clk *clkp; 229 struct clk *clkp;
221 230
222 if (tclk == NULL || IS_ERR(tclk)) 231 list_for_each_entry(clkp, &tclk->children, sibling) {
223 return;
224
225 list_for_each_entry(clkp, &clocks, node) {
226 if (likely(clkp->parent != tclk))
227 continue;
228 if (clkp->recalc) 232 if (clkp->recalc)
229 clkp->recalc(clkp); 233 clkp->recalc(clkp);
230 if (clkp->flags & RATE_PROPAGATES) 234 propagate_rate(clkp);
231 propagate_rate(clkp);
232 } 235 }
233} 236}
234 237
238static LIST_HEAD(root_clks);
239
235/** 240/**
236 * recalculate_root_clocks - recalculate and propagate all root clocks 241 * recalculate_root_clocks - recalculate and propagate all root clocks
237 * 242 *
@@ -243,16 +248,18 @@ void recalculate_root_clocks(void)
243{ 248{
244 struct clk *clkp; 249 struct clk *clkp;
245 250
246 list_for_each_entry(clkp, &clocks, node) { 251 list_for_each_entry(clkp, &root_clks, sibling) {
247 if (!clkp->parent) { 252 if (clkp->recalc)
248 if (clkp->recalc) 253 clkp->recalc(clkp);
249 clkp->recalc(clkp); 254 propagate_rate(clkp);
250 if (clkp->flags & RATE_PROPAGATES)
251 propagate_rate(clkp);
252 }
253 } 255 }
254} 256}
255 257
258void clk_init_one(struct clk *clk)
259{
260 INIT_LIST_HEAD(&clk->children);
261}
262
256int clk_register(struct clk *clk) 263int clk_register(struct clk *clk)
257{ 264{
258 if (clk == NULL || IS_ERR(clk)) 265 if (clk == NULL || IS_ERR(clk))
@@ -265,6 +272,11 @@ int clk_register(struct clk *clk)
265 return 0; 272 return 0;
266 273
267 mutex_lock(&clocks_mutex); 274 mutex_lock(&clocks_mutex);
275 if (clk->parent)
276 list_add(&clk->sibling, &clk->parent->children);
277 else
278 list_add(&clk->sibling, &root_clks);
279
268 list_add(&clk->node, &clocks); 280 list_add(&clk->node, &clocks);
269 if (clk->init) 281 if (clk->init)
270 clk->init(clk); 282 clk->init(clk);
@@ -280,6 +292,7 @@ void clk_unregister(struct clk *clk)
280 return; 292 return;
281 293
282 mutex_lock(&clocks_mutex); 294 mutex_lock(&clocks_mutex);
295 list_del(&clk->sibling);
283 list_del(&clk->node); 296 list_del(&clk->node);
284 mutex_unlock(&clocks_mutex); 297 mutex_unlock(&clocks_mutex);
285} 298}