Skip to content

Commit

Permalink
clk: JSON debugfs clock tree summary
Browse files Browse the repository at this point in the history
Clock information is dumped in JSON format which is easy
for machines to parse.

Each clock is represented as an object which has same name as
clock and following properties
	- enable_count
	- prepare_count
	- rate

Output is verified using online JSON editor.

Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
  • Loading branch information
Prashant Gaikwad authored and Mike Turquette committed Jan 12, 2013
1 parent 1af599d commit bddca89
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions drivers/clk/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,76 @@ static const struct file_operations clk_summary_fops = {
.release = single_release,
};

static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
{
if (!c)
return;

seq_printf(s, "\"%s\": { ", c->name);
seq_printf(s, "\"enable_count\": %d,", c->enable_count);
seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
seq_printf(s, "\"rate\": %lu", c->rate);
}

static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
{
struct clk *child;
struct hlist_node *tmp;

if (!c)
return;

clk_dump_one(s, c, level);

hlist_for_each_entry(child, tmp, &c->children, child_node) {
seq_printf(s, ",");
clk_dump_subtree(s, child, level + 1);
}

seq_printf(s, "}");
}

static int clk_dump(struct seq_file *s, void *data)
{
struct clk *c;
struct hlist_node *tmp;
bool first_node = true;

seq_printf(s, "{");

mutex_lock(&prepare_lock);

hlist_for_each_entry(c, tmp, &clk_root_list, child_node) {
if (!first_node)
seq_printf(s, ",");
first_node = false;
clk_dump_subtree(s, c, 0);
}

hlist_for_each_entry(c, tmp, &clk_orphan_list, child_node) {
seq_printf(s, ",");
clk_dump_subtree(s, c, 0);
}

mutex_unlock(&prepare_lock);

seq_printf(s, "}");
return 0;
}


static int clk_dump_open(struct inode *inode, struct file *file)
{
return single_open(file, clk_dump, inode->i_private);
}

static const struct file_operations clk_dump_fops = {
.open = clk_dump_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

/* caller must hold prepare_lock */
static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
{
Expand Down Expand Up @@ -241,6 +311,11 @@ static int __init clk_debug_init(void)
if (!d)
return -ENOMEM;

d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, NULL,
&clk_dump_fops);
if (!d)
return -ENOMEM;

orphandir = debugfs_create_dir("orphans", rootdir);

if (!orphandir)
Expand Down

0 comments on commit bddca89

Please sign in to comment.