1
0
Fork 0

clk: Remove forward declared function prototypes

Move the code around so that we don't need to declare function
prototypes at the start of the file. Simplify
clk_core_is_prepared() and clk_core_is_enabled() too to make the
diff easier to read.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
hifive-unleashed-5.1
Stephen Boyd 2015-04-30 14:43:22 -07:00
parent 1f3e198342
commit 4dff95dc94
1 changed files with 393 additions and 418 deletions

View File

@ -37,13 +37,6 @@ static HLIST_HEAD(clk_root_list);
static HLIST_HEAD(clk_orphan_list);
static LIST_HEAD(clk_notifier_list);
static long clk_core_get_accuracy(struct clk_core *core);
static unsigned long clk_core_get_rate(struct clk_core *core);
static int clk_core_get_phase(struct clk_core *core);
static bool clk_core_is_prepared(struct clk_core *core);
static bool clk_core_is_enabled(struct clk_core *core);
static struct clk_core *clk_core_lookup(const char *name);
/*** private data structures ***/
struct clk_core {
@ -145,339 +138,30 @@ static void clk_enable_unlock(unsigned long flags)
spin_unlock_irqrestore(&enable_lock, flags);
}
/*** debugfs support ***/
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
static struct dentry *rootdir;
static int inited = 0;
static DEFINE_MUTEX(clk_debug_lock);
static HLIST_HEAD(clk_debug_list);
static struct hlist_head *all_lists[] = {
&clk_root_list,
&clk_orphan_list,
NULL,
};
static struct hlist_head *orphan_list[] = {
&clk_orphan_list,
NULL,
};
static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
int level)
static bool clk_core_is_prepared(struct clk_core *core)
{
if (!c)
return;
/*
* .is_prepared is optional for clocks that can prepare
* fall back to software usage counter if it is missing
*/
if (!core->ops->is_prepared)
return core->prepare_count;
seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
level * 3 + 1, "",
30 - level * 3, c->name,
c->enable_count, c->prepare_count, clk_core_get_rate(c),
clk_core_get_accuracy(c), clk_core_get_phase(c));
return core->ops->is_prepared(core->hw);
}
static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
int level)
static bool clk_core_is_enabled(struct clk_core *core)
{
struct clk_core *child;
/*
* .is_enabled is only mandatory for clocks that gate
* fall back to software usage counter if .is_enabled is missing
*/
if (!core->ops->is_enabled)
return core->enable_count;
if (!c)
return;
clk_summary_show_one(s, c, level);
hlist_for_each_entry(child, &c->children, child_node)
clk_summary_show_subtree(s, child, level + 1);
return core->ops->is_enabled(core->hw);
}
static int clk_summary_show(struct seq_file *s, void *data)
{
struct clk_core *c;
struct hlist_head **lists = (struct hlist_head **)s->private;
seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n");
seq_puts(s, "----------------------------------------------------------------------------------------\n");
clk_prepare_lock();
for (; *lists; lists++)
hlist_for_each_entry(c, *lists, child_node)
clk_summary_show_subtree(s, c, 0);
clk_prepare_unlock();
return 0;
}
static int clk_summary_open(struct inode *inode, struct file *file)
{
return single_open(file, clk_summary_show, inode->i_private);
}
static const struct file_operations clk_summary_fops = {
.open = clk_summary_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static void clk_dump_one(struct seq_file *s, struct clk_core *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", clk_core_get_rate(c));
seq_printf(s, "\"accuracy\": %lu", clk_core_get_accuracy(c));
seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
}
static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
{
struct clk_core *child;
if (!c)
return;
clk_dump_one(s, c, level);
hlist_for_each_entry(child, &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_core *c;
bool first_node = true;
struct hlist_head **lists = (struct hlist_head **)s->private;
seq_printf(s, "{");
clk_prepare_lock();
for (; *lists; lists++) {
hlist_for_each_entry(c, *lists, child_node) {
if (!first_node)
seq_puts(s, ",");
first_node = false;
clk_dump_subtree(s, c, 0);
}
}
clk_prepare_unlock();
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,
};
static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
{
struct dentry *d;
int ret = -ENOMEM;
if (!core || !pdentry) {
ret = -EINVAL;
goto out;
}
d = debugfs_create_dir(core->name, pdentry);
if (!d)
goto out;
core->dentry = d;
d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry,
(u32 *)&core->rate);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry,
(u32 *)&core->accuracy);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_phase", S_IRUGO, core->dentry,
(u32 *)&core->phase);
if (!d)
goto err_out;
d = debugfs_create_x32("clk_flags", S_IRUGO, core->dentry,
(u32 *)&core->flags);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_prepare_count", S_IRUGO, core->dentry,
(u32 *)&core->prepare_count);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_enable_count", S_IRUGO, core->dentry,
(u32 *)&core->enable_count);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_notifier_count", S_IRUGO, core->dentry,
(u32 *)&core->notifier_count);
if (!d)
goto err_out;
if (core->ops->debug_init) {
ret = core->ops->debug_init(core->hw, core->dentry);
if (ret)
goto err_out;
}
ret = 0;
goto out;
err_out:
debugfs_remove_recursive(core->dentry);
core->dentry = NULL;
out:
return ret;
}
/**
* clk_debug_register - add a clk node to the debugfs clk tree
* @core: the clk being added to the debugfs clk tree
*
* Dynamically adds a clk to the debugfs clk tree if debugfs has been
* initialized. Otherwise it bails out early since the debugfs clk tree
* will be created lazily by clk_debug_init as part of a late_initcall.
*/
static int clk_debug_register(struct clk_core *core)
{
int ret = 0;
mutex_lock(&clk_debug_lock);
hlist_add_head(&core->debug_node, &clk_debug_list);
if (!inited)
goto unlock;
ret = clk_debug_create_one(core, rootdir);
unlock:
mutex_unlock(&clk_debug_lock);
return ret;
}
/**
* clk_debug_unregister - remove a clk node from the debugfs clk tree
* @core: the clk being removed from the debugfs clk tree
*
* Dynamically removes a clk and all it's children clk nodes from the
* debugfs clk tree if clk->dentry points to debugfs created by
* clk_debug_register in __clk_init.
*/
static void clk_debug_unregister(struct clk_core *core)
{
mutex_lock(&clk_debug_lock);
hlist_del_init(&core->debug_node);
debugfs_remove_recursive(core->dentry);
core->dentry = NULL;
mutex_unlock(&clk_debug_lock);
}
struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
void *data, const struct file_operations *fops)
{
struct dentry *d = NULL;
if (hw->core->dentry)
d = debugfs_create_file(name, mode, hw->core->dentry, data,
fops);
return d;
}
EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
/**
* clk_debug_init - lazily create the debugfs clk tree visualization
*
* clks are often initialized very early during boot before memory can
* be dynamically allocated and well before debugfs is setup.
* clk_debug_init walks the clk tree hierarchy while holding
* prepare_lock and creates the topology as part of a late_initcall,
* thus insuring that clks initialized very early will still be
* represented in the debugfs clk tree. This function should only be
* called once at boot-time, and all other clks added dynamically will
* be done so with clk_debug_register.
*/
static int __init clk_debug_init(void)
{
struct clk_core *core;
struct dentry *d;
rootdir = debugfs_create_dir("clk", NULL);
if (!rootdir)
return -ENOMEM;
d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists,
&clk_summary_fops);
if (!d)
return -ENOMEM;
d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists,
&clk_dump_fops);
if (!d)
return -ENOMEM;
d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir,
&orphan_list, &clk_summary_fops);
if (!d)
return -ENOMEM;
d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir,
&orphan_list, &clk_dump_fops);
if (!d)
return -ENOMEM;
mutex_lock(&clk_debug_lock);
hlist_for_each_entry(core, &clk_debug_list, debug_node)
clk_debug_create_one(core, rootdir);
inited = 1;
mutex_unlock(&clk_debug_lock);
return 0;
}
late_initcall(clk_debug_init);
#else
static inline int clk_debug_register(struct clk_core *core) { return 0; }
static inline void clk_debug_reparent(struct clk_core *core,
struct clk_core *new_parent)
{
}
static inline void clk_debug_unregister(struct clk_core *core)
{
}
#endif
/* caller must hold prepare_lock */
static void clk_unprepare_unused_subtree(struct clk_core *core)
{
@ -608,6 +292,49 @@ struct clk *__clk_get_parent(struct clk *clk)
}
EXPORT_SYMBOL_GPL(__clk_get_parent);
static struct clk_core *__clk_lookup_subtree(const char *name,
struct clk_core *core)
{
struct clk_core *child;
struct clk_core *ret;
if (!strcmp(core->name, name))
return core;
hlist_for_each_entry(child, &core->children, child_node) {
ret = __clk_lookup_subtree(name, child);
if (ret)
return ret;
}
return NULL;
}
static struct clk_core *clk_core_lookup(const char *name)
{
struct clk_core *root_clk;
struct clk_core *ret;
if (!name)
return NULL;
/* search the 'proper' clk tree first */
hlist_for_each_entry(root_clk, &clk_root_list, child_node) {
ret = __clk_lookup_subtree(name, root_clk);
if (ret)
return ret;
}
/* if not found, then search the orphan tree */
hlist_for_each_entry(root_clk, &clk_orphan_list, child_node) {
ret = __clk_lookup_subtree(name, root_clk);
if (ret)
return ret;
}
return NULL;
}
static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
u8 index)
{
@ -684,27 +411,6 @@ unsigned long __clk_get_flags(struct clk *clk)
}
EXPORT_SYMBOL_GPL(__clk_get_flags);
static bool clk_core_is_prepared(struct clk_core *core)
{
int ret;
if (!core)
return false;
/*
* .is_prepared is optional for clocks that can prepare
* fall back to software usage counter if it is missing
*/
if (!core->ops->is_prepared) {
ret = core->prepare_count ? 1 : 0;
goto out;
}
ret = core->ops->is_prepared(core->hw);
out:
return !!ret;
}
bool __clk_is_prepared(struct clk *clk)
{
if (!clk)
@ -713,27 +419,6 @@ bool __clk_is_prepared(struct clk *clk)
return clk_core_is_prepared(clk->core);
}
static bool clk_core_is_enabled(struct clk_core *core)
{
int ret;
if (!core)
return false;
/*
* .is_enabled is only mandatory for clocks that gate
* fall back to software usage counter if .is_enabled is missing
*/
if (!core->ops->is_enabled) {
ret = core->enable_count ? 1 : 0;
goto out;
}
ret = core->ops->is_enabled(core->hw);
out:
return !!ret;
}
bool __clk_is_enabled(struct clk *clk)
{
if (!clk)
@ -743,49 +428,6 @@ bool __clk_is_enabled(struct clk *clk)
}
EXPORT_SYMBOL_GPL(__clk_is_enabled);
static struct clk_core *__clk_lookup_subtree(const char *name,
struct clk_core *core)
{
struct clk_core *child;
struct clk_core *ret;
if (!strcmp(core->name, name))
return core;
hlist_for_each_entry(child, &core->children, child_node) {
ret = __clk_lookup_subtree(name, child);
if (ret)
return ret;
}
return NULL;
}
static struct clk_core *clk_core_lookup(const char *name)
{
struct clk_core *root_clk;
struct clk_core *ret;
if (!name)
return NULL;
/* search the 'proper' clk tree first */
hlist_for_each_entry(root_clk, &clk_root_list, child_node) {
ret = __clk_lookup_subtree(name, root_clk);
if (ret)
return ret;
}
/* if not found, then search the orphan tree */
hlist_for_each_entry(root_clk, &clk_orphan_list, child_node) {
ret = __clk_lookup_subtree(name, root_clk);
if (ret)
return ret;
}
return NULL;
}
static bool mux_is_better_rate(unsigned long rate, unsigned long now,
unsigned long best, unsigned long flags)
{
@ -2190,7 +1832,6 @@ static int clk_core_get_phase(struct clk_core *core)
return ret;
}
EXPORT_SYMBOL_GPL(clk_get_phase);
/**
* clk_get_phase - return the phase shift of a clock signal
@ -2206,6 +1847,7 @@ int clk_get_phase(struct clk *clk)
return clk_core_get_phase(clk->core);
}
EXPORT_SYMBOL_GPL(clk_get_phase);
/**
* clk_is_match - check if two clk's point to the same hardware clock
@ -2233,6 +1875,339 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
}
EXPORT_SYMBOL_GPL(clk_is_match);
/*** debugfs support ***/
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
static struct dentry *rootdir;
static int inited = 0;
static DEFINE_MUTEX(clk_debug_lock);
static HLIST_HEAD(clk_debug_list);
static struct hlist_head *all_lists[] = {
&clk_root_list,
&clk_orphan_list,
NULL,
};
static struct hlist_head *orphan_list[] = {
&clk_orphan_list,
NULL,
};
static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
int level)
{
if (!c)
return;
seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
level * 3 + 1, "",
30 - level * 3, c->name,
c->enable_count, c->prepare_count, clk_core_get_rate(c),
clk_core_get_accuracy(c), clk_core_get_phase(c));
}
static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
int level)
{
struct clk_core *child;
if (!c)
return;
clk_summary_show_one(s, c, level);
hlist_for_each_entry(child, &c->children, child_node)
clk_summary_show_subtree(s, child, level + 1);
}
static int clk_summary_show(struct seq_file *s, void *data)
{
struct clk_core *c;
struct hlist_head **lists = (struct hlist_head **)s->private;
seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n");
seq_puts(s, "----------------------------------------------------------------------------------------\n");
clk_prepare_lock();
for (; *lists; lists++)
hlist_for_each_entry(c, *lists, child_node)
clk_summary_show_subtree(s, c, 0);
clk_prepare_unlock();
return 0;
}
static int clk_summary_open(struct inode *inode, struct file *file)
{
return single_open(file, clk_summary_show, inode->i_private);
}
static const struct file_operations clk_summary_fops = {
.open = clk_summary_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static void clk_dump_one(struct seq_file *s, struct clk_core *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", clk_core_get_rate(c));
seq_printf(s, "\"accuracy\": %lu", clk_core_get_accuracy(c));
seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
}
static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
{
struct clk_core *child;
if (!c)
return;
clk_dump_one(s, c, level);
hlist_for_each_entry(child, &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_core *c;
bool first_node = true;
struct hlist_head **lists = (struct hlist_head **)s->private;
seq_printf(s, "{");
clk_prepare_lock();
for (; *lists; lists++) {
hlist_for_each_entry(c, *lists, child_node) {
if (!first_node)
seq_puts(s, ",");
first_node = false;
clk_dump_subtree(s, c, 0);
}
}
clk_prepare_unlock();
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,
};
static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
{
struct dentry *d;
int ret = -ENOMEM;
if (!core || !pdentry) {
ret = -EINVAL;
goto out;
}
d = debugfs_create_dir(core->name, pdentry);
if (!d)
goto out;
core->dentry = d;
d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry,
(u32 *)&core->rate);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry,
(u32 *)&core->accuracy);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_phase", S_IRUGO, core->dentry,
(u32 *)&core->phase);
if (!d)
goto err_out;
d = debugfs_create_x32("clk_flags", S_IRUGO, core->dentry,
(u32 *)&core->flags);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_prepare_count", S_IRUGO, core->dentry,
(u32 *)&core->prepare_count);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_enable_count", S_IRUGO, core->dentry,
(u32 *)&core->enable_count);
if (!d)
goto err_out;
d = debugfs_create_u32("clk_notifier_count", S_IRUGO, core->dentry,
(u32 *)&core->notifier_count);
if (!d)
goto err_out;
if (core->ops->debug_init) {
ret = core->ops->debug_init(core->hw, core->dentry);
if (ret)
goto err_out;
}
ret = 0;
goto out;
err_out:
debugfs_remove_recursive(core->dentry);
core->dentry = NULL;
out:
return ret;
}
/**
* clk_debug_register - add a clk node to the debugfs clk tree
* @core: the clk being added to the debugfs clk tree
*
* Dynamically adds a clk to the debugfs clk tree if debugfs has been
* initialized. Otherwise it bails out early since the debugfs clk tree
* will be created lazily by clk_debug_init as part of a late_initcall.
*/
static int clk_debug_register(struct clk_core *core)
{
int ret = 0;
mutex_lock(&clk_debug_lock);
hlist_add_head(&core->debug_node, &clk_debug_list);
if (!inited)
goto unlock;
ret = clk_debug_create_one(core, rootdir);
unlock:
mutex_unlock(&clk_debug_lock);
return ret;
}
/**
* clk_debug_unregister - remove a clk node from the debugfs clk tree
* @core: the clk being removed from the debugfs clk tree
*
* Dynamically removes a clk and all it's children clk nodes from the
* debugfs clk tree if clk->dentry points to debugfs created by
* clk_debug_register in __clk_init.
*/
static void clk_debug_unregister(struct clk_core *core)
{
mutex_lock(&clk_debug_lock);
hlist_del_init(&core->debug_node);
debugfs_remove_recursive(core->dentry);
core->dentry = NULL;
mutex_unlock(&clk_debug_lock);
}
struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
void *data, const struct file_operations *fops)
{
struct dentry *d = NULL;
if (hw->core->dentry)
d = debugfs_create_file(name, mode, hw->core->dentry, data,
fops);
return d;
}
EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
/**
* clk_debug_init - lazily create the debugfs clk tree visualization
*
* clks are often initialized very early during boot before memory can
* be dynamically allocated and well before debugfs is setup.
* clk_debug_init walks the clk tree hierarchy while holding
* prepare_lock and creates the topology as part of a late_initcall,
* thus insuring that clks initialized very early will still be
* represented in the debugfs clk tree. This function should only be
* called once at boot-time, and all other clks added dynamically will
* be done so with clk_debug_register.
*/
static int __init clk_debug_init(void)
{
struct clk_core *core;
struct dentry *d;
rootdir = debugfs_create_dir("clk", NULL);
if (!rootdir)
return -ENOMEM;
d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists,
&clk_summary_fops);
if (!d)
return -ENOMEM;
d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists,
&clk_dump_fops);
if (!d)
return -ENOMEM;
d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir,
&orphan_list, &clk_summary_fops);
if (!d)
return -ENOMEM;
d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir,
&orphan_list, &clk_dump_fops);
if (!d)
return -ENOMEM;
mutex_lock(&clk_debug_lock);
hlist_for_each_entry(core, &clk_debug_list, debug_node)
clk_debug_create_one(core, rootdir);
inited = 1;
mutex_unlock(&clk_debug_lock);
return 0;
}
late_initcall(clk_debug_init);
#else
static inline int clk_debug_register(struct clk_core *core) { return 0; }
static inline void clk_debug_reparent(struct clk_core *core,
struct clk_core *new_parent)
{
}
static inline void clk_debug_unregister(struct clk_core *core)
{
}
#endif
/**
* __clk_init - initialize the data structures in a struct clk
* @dev: device initializing this clk, placeholder for now