mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-17 14:30:00 +00:00
ARM: 6681/1: SPEAr: add debugfs support to clk API
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>
This commit is contained in:
parent
af89fd812b
commit
4b9502e167
@ -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>
|
||||
@ -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)
|
||||
{
|
||||
@ -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)
|
||||
@ -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);
|
||||
}
|
||||
@ -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 */
|
||||
|
@ -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;
|
||||
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user