Skip to content

Commit

Permalink
ARM: 6681/1: SPEAr: add debugfs support to clk API
Browse files Browse the repository at this point in the history
Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Shiraz Hashim authored and Russell King committed Mar 9, 2011
1 parent af89fd8 commit 4b9502e
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
116 changes: 116 additions & 0 deletions arch/arm/plat-spear/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <linux/bug.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/list.h>
Expand All @@ -22,8 +23,14 @@

static DEFINE_SPINLOCK(clocks_lock);
static LIST_HEAD(root_clks);
#ifdef CONFIG_DEBUG_FS
static LIST_HEAD(clocks);
#endif

static void propagate_rate(struct clk *, int on_init);
#ifdef CONFIG_DEBUG_FS
static int clk_debugfs_reparent(struct clk *);
#endif

static int generic_clk_enable(struct clk *clk)
{
Expand Down Expand Up @@ -96,6 +103,10 @@ static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)

clk->pclk = pclk_info->pclk;
spin_unlock_irqrestore(&clocks_lock, flags);

#ifdef CONFIG_DEBUG_FS
clk_debugfs_reparent(clk);
#endif
}

static void do_clk_disable(struct clk *clk)
Expand Down Expand Up @@ -336,6 +347,12 @@ void clk_register(struct clk_lookup *cl)

spin_unlock_irqrestore(&clocks_lock, flags);

/* debugfs specific */
#ifdef CONFIG_DEBUG_FS
list_add(&clk->node, &clocks);
clk->cl = cl;
#endif

/* add clock to arm clockdev framework */
clkdev_add(cl);
}
Expand Down Expand Up @@ -885,3 +902,102 @@ void recalc_root_clocks(void)
}
spin_unlock_irqrestore(&clocks_lock, flags);
}

#ifdef CONFIG_DEBUG_FS
/*
* debugfs support to trace clock tree hierarchy and attributes
*/
static struct dentry *clk_debugfs_root;
static int clk_debugfs_register_one(struct clk *c)
{
int err;
struct dentry *d, *child;
struct clk *pa = c->pclk;
char s[255];
char *p = s;

if (c) {
if (c->cl->con_id)
p += sprintf(p, "%s", c->cl->con_id);
if (c->cl->dev_id)
p += sprintf(p, "%s", c->cl->dev_id);
}
d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
if (!d)
return -ENOMEM;
c->dent = d;

d = debugfs_create_u32("usage_count", S_IRUGO, c->dent,
(u32 *)&c->usage_count);
if (!d) {
err = -ENOMEM;
goto err_out;
}
d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
if (!d) {
err = -ENOMEM;
goto err_out;
}
d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
if (!d) {
err = -ENOMEM;
goto err_out;
}
return 0;

err_out:
d = c->dent;
list_for_each_entry(child, &d->d_subdirs, d_u.d_child)
debugfs_remove(child);
debugfs_remove(c->dent);
return err;
}

static int clk_debugfs_register(struct clk *c)
{
int err;
struct clk *pa = c->pclk;

if (pa && !pa->dent) {
err = clk_debugfs_register(pa);
if (err)
return err;
}

if (!c->dent) {
err = clk_debugfs_register_one(c);
if (err)
return err;
}
return 0;
}

static int __init clk_debugfs_init(void)
{
struct clk *c;
struct dentry *d;
int err;

d = debugfs_create_dir("clock", NULL);
if (!d)
return -ENOMEM;
clk_debugfs_root = d;

list_for_each_entry(c, &clocks, node) {
err = clk_debugfs_register(c);
if (err)
goto err_out;
}
return 0;
err_out:
debugfs_remove_recursive(clk_debugfs_root);
return err;
}
late_initcall(clk_debugfs_init);

static int clk_debugfs_reparent(struct clk *c)
{
debugfs_remove(c->dent);
return clk_debugfs_register_one(c);
}
#endif /* CONFIG_DEBUG_FS */
8 changes: 8 additions & 0 deletions arch/arm/plat-spear/include/plat/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ struct rate_config {
* @children: list for childrens or this clock
* @sibling: node for list of clocks having same parents
* @private_data: clock specific private data
* @node: list to maintain clocks linearly
* @cl: clocklook up assoicated with this clock
* @dent: object for debugfs
*/
struct clk {
unsigned int usage_count;
Expand All @@ -109,6 +112,11 @@ struct clk {
struct list_head children;
struct list_head sibling;
void *private_data;
#ifdef CONFIG_DEBUG_FS
struct list_head node;
struct clk_lookup *cl;
struct dentry *dent;
#endif
};

/* pll configuration structure */
Expand Down

0 comments on commit 4b9502e

Please sign in to comment.