aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2014-05-30 11:03:57 -0400
committerMike Turquette <mturquette@linaro.org>2014-06-26 15:55:04 -0400
commit27b8d5f723e64b5f7beac45a4d5785906d0a2f9d (patch)
treecd0db0bbc908a71ac84016ba6beeb8363097039f /drivers/clk/clk.c
parentd8e53c3deb46ec5b45bd7f5e1cc8ff8d35ec92ba (diff)
clk: flatten clk tree in debugfs
This patch flattens the clk tree in CCF debugfs. Instead of representing the clocks and their hierarchy as a directory structure under /sys/kernel/debug/clk, each clock gets a single directory directly under /sys/kernel/debug/clk. The orphans directory is replaced by a file called clk_orphan_summary. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c114
1 files changed, 35 insertions, 79 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8b73edef151d..7dfb2f308b35 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -36,6 +36,17 @@ static HLIST_HEAD(clk_root_list);
36static HLIST_HEAD(clk_orphan_list); 36static HLIST_HEAD(clk_orphan_list);
37static LIST_HEAD(clk_notifier_list); 37static LIST_HEAD(clk_notifier_list);
38 38
39static struct hlist_head *all_lists[] = {
40 &clk_root_list,
41 &clk_orphan_list,
42 NULL,
43};
44
45static struct hlist_head *orphan_list[] = {
46 &clk_orphan_list,
47 NULL,
48};
49
39/*** locking ***/ 50/*** locking ***/
40static void clk_prepare_lock(void) 51static void clk_prepare_lock(void)
41{ 52{
@@ -98,7 +109,6 @@ static void clk_enable_unlock(unsigned long flags)
98#include <linux/debugfs.h> 109#include <linux/debugfs.h>
99 110
100static struct dentry *rootdir; 111static struct dentry *rootdir;
101static struct dentry *orphandir;
102static int inited = 0; 112static int inited = 0;
103 113
104static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level) 114static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
@@ -130,17 +140,16 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
130static int clk_summary_show(struct seq_file *s, void *data) 140static int clk_summary_show(struct seq_file *s, void *data)
131{ 141{
132 struct clk *c; 142 struct clk *c;
143 struct hlist_head **lists = (struct hlist_head **)s->private;
133 144
134 seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy\n"); 145 seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy\n");
135 seq_puts(s, "--------------------------------------------------------------------------------\n"); 146 seq_puts(s, "--------------------------------------------------------------------------------\n");
136 147
137 clk_prepare_lock(); 148 clk_prepare_lock();
138 149
139 hlist_for_each_entry(c, &clk_root_list, child_node) 150 for (; *lists; lists++)
140 clk_summary_show_subtree(s, c, 0); 151 hlist_for_each_entry(c, *lists, child_node)
141 152 clk_summary_show_subtree(s, c, 0);
142 hlist_for_each_entry(c, &clk_orphan_list, child_node)
143 clk_summary_show_subtree(s, c, 0);
144 153
145 clk_prepare_unlock(); 154 clk_prepare_unlock();
146 155
@@ -193,21 +202,19 @@ static int clk_dump(struct seq_file *s, void *data)
193{ 202{
194 struct clk *c; 203 struct clk *c;
195 bool first_node = true; 204 bool first_node = true;
205 struct hlist_head **lists = (struct hlist_head **)s->private;
196 206
197 seq_printf(s, "{"); 207 seq_printf(s, "{");
198 208
199 clk_prepare_lock(); 209 clk_prepare_lock();
200 210
201 hlist_for_each_entry(c, &clk_root_list, child_node) { 211 for (; *lists; lists++) {
202 if (!first_node) 212 hlist_for_each_entry(c, *lists, child_node) {
203 seq_printf(s, ","); 213 if (!first_node)
204 first_node = false; 214 seq_puts(s, ",");
205 clk_dump_subtree(s, c, 0); 215 first_node = false;
206 } 216 clk_dump_subtree(s, c, 0);
207 217 }
208 hlist_for_each_entry(c, &clk_orphan_list, child_node) {
209 seq_printf(s, ",");
210 clk_dump_subtree(s, c, 0);
211 } 218 }
212 219
213 clk_prepare_unlock(); 220 clk_prepare_unlock();
@@ -305,7 +312,7 @@ static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry)
305 goto out; 312 goto out;
306 313
307 hlist_for_each_entry(child, &clk->children, child_node) 314 hlist_for_each_entry(child, &clk->children, child_node)
308 clk_debug_create_subtree(child, clk->dentry); 315 clk_debug_create_subtree(child, pdentry);
309 316
310 ret = 0; 317 ret = 0;
311out: 318out:
@@ -325,31 +332,12 @@ out:
325 */ 332 */
326static int clk_debug_register(struct clk *clk) 333static int clk_debug_register(struct clk *clk)
327{ 334{
328 struct clk *parent;
329 struct dentry *pdentry;
330 int ret = 0; 335 int ret = 0;
331 336
332 if (!inited) 337 if (!inited)
333 goto out; 338 goto out;
334 339
335 parent = clk->parent; 340 ret = clk_debug_create_subtree(clk, rootdir);
336
337 /*
338 * Check to see if a clk is a root clk. Also check that it is
339 * safe to add this clk to debugfs
340 */
341 if (!parent)
342 if (clk->flags & CLK_IS_ROOT)
343 pdentry = rootdir;
344 else
345 pdentry = orphandir;
346 else
347 if (parent->dentry)
348 pdentry = parent->dentry;
349 else
350 goto out;
351
352 ret = clk_debug_create_subtree(clk, pdentry);
353 341
354out: 342out:
355 return ret; 343 return ret;
@@ -371,39 +359,6 @@ static void clk_debug_unregister(struct clk *clk)
371} 359}
372 360
373/** 361/**
374 * clk_debug_reparent - reparent clk node in the debugfs clk tree
375 * @clk: the clk being reparented
376 * @new_parent: the new clk parent, may be NULL
377 *
378 * Rename clk entry in the debugfs clk tree if debugfs has been
379 * initialized. Otherwise it bails out early since the debugfs clk tree
380 * will be created lazily by clk_debug_init as part of a late_initcall.
381 *
382 * Caller must hold prepare_lock.
383 */
384static void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
385{
386 struct dentry *d;
387 struct dentry *new_parent_d;
388
389 if (!inited)
390 return;
391
392 if (new_parent)
393 new_parent_d = new_parent->dentry;
394 else
395 new_parent_d = orphandir;
396
397 d = debugfs_rename(clk->dentry->d_parent, clk->dentry,
398 new_parent_d, clk->name);
399 if (d)
400 clk->dentry = d;
401 else
402 pr_debug("%s: failed to rename debugfs entry for %s\n",
403 __func__, clk->name);
404}
405
406/**
407 * clk_debug_init - lazily create the debugfs clk tree visualization 362 * clk_debug_init - lazily create the debugfs clk tree visualization
408 * 363 *
409 * clks are often initialized very early during boot before memory can 364 * clks are often initialized very early during boot before memory can
@@ -425,19 +380,24 @@ static int __init clk_debug_init(void)
425 if (!rootdir) 380 if (!rootdir)
426 return -ENOMEM; 381 return -ENOMEM;
427 382
428 d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, NULL, 383 d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists,
429 &clk_summary_fops); 384 &clk_summary_fops);
430 if (!d) 385 if (!d)
431 return -ENOMEM; 386 return -ENOMEM;
432 387
433 d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, NULL, 388 d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists,
434 &clk_dump_fops); 389 &clk_dump_fops);
435 if (!d) 390 if (!d)
436 return -ENOMEM; 391 return -ENOMEM;
437 392
438 orphandir = debugfs_create_dir("orphans", rootdir); 393 d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir,
394 &orphan_list, &clk_summary_fops);
395 if (!d)
396 return -ENOMEM;
439 397
440 if (!orphandir) 398 d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir,
399 &orphan_list, &clk_dump_fops);
400 if (!d)
441 return -ENOMEM; 401 return -ENOMEM;
442 402
443 clk_prepare_lock(); 403 clk_prepare_lock();
@@ -446,7 +406,7 @@ static int __init clk_debug_init(void)
446 clk_debug_create_subtree(clk, rootdir); 406 clk_debug_create_subtree(clk, rootdir);
447 407
448 hlist_for_each_entry(clk, &clk_orphan_list, child_node) 408 hlist_for_each_entry(clk, &clk_orphan_list, child_node)
449 clk_debug_create_subtree(clk, orphandir); 409 clk_debug_create_subtree(clk, rootdir);
450 410
451 inited = 1; 411 inited = 1;
452 412
@@ -1284,9 +1244,6 @@ static void __clk_set_parent_after(struct clk *clk, struct clk *parent,
1284 clk_disable(old_parent); 1244 clk_disable(old_parent);
1285 __clk_unprepare(old_parent); 1245 __clk_unprepare(old_parent);
1286 } 1246 }
1287
1288 /* update debugfs with new clk tree topology */
1289 clk_debug_reparent(clk, parent);
1290} 1247}
1291 1248
1292static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) 1249static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
@@ -1683,7 +1640,6 @@ out:
1683void __clk_reparent(struct clk *clk, struct clk *new_parent) 1640void __clk_reparent(struct clk *clk, struct clk *new_parent)
1684{ 1641{
1685 clk_reparent(clk, new_parent); 1642 clk_reparent(clk, new_parent);
1686 clk_debug_reparent(clk, new_parent);
1687 __clk_recalc_accuracies(clk); 1643 __clk_recalc_accuracies(clk);
1688 __clk_recalc_rates(clk, POST_RATE_CHANGE); 1644 __clk_recalc_rates(clk, POST_RATE_CHANGE);
1689} 1645}