diff options
author | Prashant Gaikwad <pgaikwad@nvidia.com> | 2012-12-26 08:46:22 -0500 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2013-01-11 22:46:32 -0500 |
commit | 1af599df6bdad9ee34ae9e50efcda273e12b9d4f (patch) | |
tree | 56a0395104878ce7a074da8144a44dd4fde66170 /drivers/clk/clk.c | |
parent | 9f58b9b9fe3646421d9de251a4c5eec6d299a395 (diff) |
clk: human-readable debugfs clock tree summary
Adds debug file "clk_summary" in /sys/kernel/debug/clk dir.
It helps to view all the clock registered in human-readable format.
For example:
clock enable_cnt prepare_cnt rate
---------------------------------------------------------------------
i2s0_sync 0 0 24000000
spdif_in_sync 0 0 24000000
spdif_mux 0 0 24000000
spdif 0 0 24000000
spdif_doubler 0 0 48000000
spdif_div 0 0 48000000
spdif_2x 0 0 48000000
clk_32k 2 2 32768
blink_override 1 1 32768
blink 1 1 32768
clk_m 2 2 12000000
clk_out_3_mux 0 0 12000000
clk_out_3 0 0 12000000
pll_ref 3 3 12000000
pll_e_mux 0 0 12000000
pll_e 0 0 100000000
cml0 0 0 100000000
cml1 0 0 100000000
pciex 0 0 100000000
pll_d2 0 0 1000000
pll_d2_out0 0 0 500000
pll_d 0 0 1000000
pll_d_out0 0 0 500000
dsib_mux 0 0 500000
dsib 0 0 500000
dsia 0 0 500000
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r-- | drivers/clk/clk.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index eea70da02500..8622b9de7302 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -35,6 +35,67 @@ static struct dentry *rootdir; | |||
35 | static struct dentry *orphandir; | 35 | static struct dentry *orphandir; |
36 | static int inited = 0; | 36 | static int inited = 0; |
37 | 37 | ||
38 | static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level) | ||
39 | { | ||
40 | if (!c) | ||
41 | return; | ||
42 | |||
43 | seq_printf(s, "%*s%-*s %-11d %-12d %-10lu", | ||
44 | level * 3 + 1, "", | ||
45 | 30 - level * 3, c->name, | ||
46 | c->enable_count, c->prepare_count, c->rate); | ||
47 | seq_printf(s, "\n"); | ||
48 | } | ||
49 | |||
50 | static void clk_summary_show_subtree(struct seq_file *s, struct clk *c, | ||
51 | int level) | ||
52 | { | ||
53 | struct clk *child; | ||
54 | struct hlist_node *tmp; | ||
55 | |||
56 | if (!c) | ||
57 | return; | ||
58 | |||
59 | clk_summary_show_one(s, c, level); | ||
60 | |||
61 | hlist_for_each_entry(child, tmp, &c->children, child_node) | ||
62 | clk_summary_show_subtree(s, child, level + 1); | ||
63 | } | ||
64 | |||
65 | static int clk_summary_show(struct seq_file *s, void *data) | ||
66 | { | ||
67 | struct clk *c; | ||
68 | struct hlist_node *tmp; | ||
69 | |||
70 | seq_printf(s, " clock enable_cnt prepare_cnt rate\n"); | ||
71 | seq_printf(s, "---------------------------------------------------------------------\n"); | ||
72 | |||
73 | mutex_lock(&prepare_lock); | ||
74 | |||
75 | hlist_for_each_entry(c, tmp, &clk_root_list, child_node) | ||
76 | clk_summary_show_subtree(s, c, 0); | ||
77 | |||
78 | hlist_for_each_entry(c, tmp, &clk_orphan_list, child_node) | ||
79 | clk_summary_show_subtree(s, c, 0); | ||
80 | |||
81 | mutex_unlock(&prepare_lock); | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | |||
87 | static int clk_summary_open(struct inode *inode, struct file *file) | ||
88 | { | ||
89 | return single_open(file, clk_summary_show, inode->i_private); | ||
90 | } | ||
91 | |||
92 | static const struct file_operations clk_summary_fops = { | ||
93 | .open = clk_summary_open, | ||
94 | .read = seq_read, | ||
95 | .llseek = seq_lseek, | ||
96 | .release = single_release, | ||
97 | }; | ||
98 | |||
38 | /* caller must hold prepare_lock */ | 99 | /* caller must hold prepare_lock */ |
39 | static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry) | 100 | static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry) |
40 | { | 101 | { |
@@ -168,12 +229,18 @@ static int __init clk_debug_init(void) | |||
168 | { | 229 | { |
169 | struct clk *clk; | 230 | struct clk *clk; |
170 | struct hlist_node *tmp; | 231 | struct hlist_node *tmp; |
232 | struct dentry *d; | ||
171 | 233 | ||
172 | rootdir = debugfs_create_dir("clk", NULL); | 234 | rootdir = debugfs_create_dir("clk", NULL); |
173 | 235 | ||
174 | if (!rootdir) | 236 | if (!rootdir) |
175 | return -ENOMEM; | 237 | return -ENOMEM; |
176 | 238 | ||
239 | d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, NULL, | ||
240 | &clk_summary_fops); | ||
241 | if (!d) | ||
242 | return -ENOMEM; | ||
243 | |||
177 | orphandir = debugfs_create_dir("orphans", rootdir); | 244 | orphandir = debugfs_create_dir("orphans", rootdir); |
178 | 245 | ||
179 | if (!orphandir) | 246 | if (!orphandir) |