diff options
author | Colin Cross <ccross@android.com> | 2012-10-23 19:11:04 +0900 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2012-10-23 19:11:09 +0900 |
commit | 52569e2f1747703c1cc6b3b058b0ac11e4288ef5 (patch) | |
tree | 34b121ed6c5ad1f46a97ec01f5ed38c671b5dacb /arch/arm/plat-samsung/clock.c | |
parent | 6f0c0580b70c89094b3422ba81118c7b959c7556 (diff) |
ARM: SAMSUNG: add clock_tree debugfs file in clock
Add a clock/clock_tree debugfs file that shows the entire clock
hierarchy including usage counts and rates.
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: Jonghwan Choi <jhbird.choi@samsung.com>
[kgene.kim@samsung.com: silence checkpatch complaining]
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm/plat-samsung/clock.c')
-rw-r--r-- | arch/arm/plat-samsung/clock.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 012bbd0b8d81..36c1e67423a2 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -389,6 +389,64 @@ int __init s3c24xx_register_baseclocks(unsigned long xtal) static struct dentry *clk_debugfs_root; +static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) +{ + struct clk *child; + const char *state; + char buf[255] = { 0 }; + int n = 0; + + if (c->name) + n = snprintf(buf, sizeof(buf) - 1, "%s", c->name); + + if (c->devname) + n += snprintf(buf + n, sizeof(buf) - 1 - n, ":%s", c->devname); + + state = (c->usage > 0) ? "on" : "off"; + + seq_printf(s, "%*s%-*s %-6s %-3d %-10lu\n", + level * 3 + 1, "", + 50 - level * 3, buf, + state, c->usage, clk_get_rate(c)); + + list_for_each_entry(child, &clocks, list) { + if (child->parent != c) + continue; + + clock_tree_show_one(s, child, level + 1); + } +} + +static int clock_tree_show(struct seq_file *s, void *data) +{ + struct clk *c; + unsigned long flags; + + seq_printf(s, " clock state ref rate\n"); + seq_printf(s, "----------------------------------------------------\n"); + + spin_lock_irqsave(&clocks_lock, flags); + + list_for_each_entry(c, &clocks, list) + if (c->parent == NULL) + clock_tree_show_one(s, c, 0); + + spin_unlock_irqrestore(&clocks_lock, flags); + return 0; +} + +static int clock_tree_open(struct inode *inode, struct file *file) +{ + return single_open(file, clock_tree_show, inode->i_private); +} + +static const struct file_operations clock_tree_fops = { + .open = clock_tree_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int clk_debugfs_register_one(struct clk *c) { int err; @@ -446,13 +504,18 @@ static int __init clk_debugfs_init(void) { struct clk *c; struct dentry *d; - int err; + int err = -ENOMEM; d = debugfs_create_dir("clock", NULL); if (!d) return -ENOMEM; clk_debugfs_root = d; + d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL, + &clock_tree_fops); + if (!d) + goto err_out; + list_for_each_entry(c, &clocks, list) { err = clk_debugfs_register(c); if (err) |