X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?p=kvmfornfv.git;a=blobdiff_plain;f=kernel%2Fdrivers%2Fclk%2Fclk.c;h=f13c3f4228d4d51d5649c3705fd565b4aac82913;hp=9f9cadd00bc8396aa6a339d7e8c4ced54ffe0aed;hb=e09b41010ba33a20a87472ee821fa407a5b8da36;hpb=f93b97fd65072de626c074dbe099a1fff05ce060 diff --git a/kernel/drivers/clk/clk.c b/kernel/drivers/clk/clk.c index 9f9cadd00..f13c3f422 100644 --- a/kernel/drivers/clk/clk.c +++ b/kernel/drivers/clk/clk.c @@ -9,6 +9,7 @@ * Standard functionality for the common clock API. See Documentation/clk.txt */ +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include "clk.h" @@ -37,13 +39,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 *clk); -static unsigned long clk_core_get_rate(struct clk_core *clk); -static int clk_core_get_phase(struct clk_core *clk); -static bool clk_core_is_prepared(struct clk_core *clk); -static bool clk_core_is_enabled(struct clk_core *clk); -static struct clk_core *clk_core_lookup(const char *name); - /*** private data structures ***/ struct clk_core { @@ -62,17 +57,20 @@ struct clk_core { struct clk_core *new_parent; struct clk_core *new_child; unsigned long flags; + bool orphan; unsigned int enable_count; unsigned int prepare_count; + unsigned long min_rate; + unsigned long max_rate; unsigned long accuracy; int phase; struct hlist_head children; struct hlist_node child_node; - struct hlist_node debug_node; struct hlist_head clks; unsigned int notifier_count; #ifdef CONFIG_DEBUG_FS struct dentry *dentry; + struct hlist_node debug_node; #endif struct kref ref; }; @@ -117,12 +115,14 @@ static void clk_prepare_unlock(void) } static unsigned long clk_enable_lock(void) + __acquires(enable_lock) { unsigned long flags; if (!spin_trylock_irqsave(&enable_lock, flags)) { if (enable_owner == current) { enable_refcnt++; + __acquire(enable_lock); return flags; } spin_lock_irqsave(&enable_lock, flags); @@ -135,1435 +135,1110 @@ static unsigned long clk_enable_lock(void) } static void clk_enable_unlock(unsigned long flags) + __releases(enable_lock) { WARN_ON_ONCE(enable_owner != current); WARN_ON_ONCE(enable_refcnt == 0); - if (--enable_refcnt) + if (--enable_refcnt) { + __release(enable_lock); return; + } enable_owner = NULL; spin_unlock_irqrestore(&enable_lock, flags); } -/*** debugfs support ***/ - -#ifdef CONFIG_DEBUG_FS -#include +static bool clk_core_is_prepared(struct clk_core *core) +{ + /* + * .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; -static struct dentry *rootdir; -static int inited = 0; -static DEFINE_MUTEX(clk_debug_lock); -static HLIST_HEAD(clk_debug_list); + return core->ops->is_prepared(core->hw); +} -static struct hlist_head *all_lists[] = { - &clk_root_list, - &clk_orphan_list, - NULL, -}; +static bool clk_core_is_enabled(struct clk_core *core) +{ + /* + * .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; -static struct hlist_head *orphan_list[] = { - &clk_orphan_list, - NULL, -}; + return core->ops->is_enabled(core->hw); +} -static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, - int level) +static void clk_unprepare_unused_subtree(struct clk_core *core) { - if (!c) + struct clk_core *child; + + lockdep_assert_held(&prepare_lock); + + hlist_for_each_entry(child, &core->children, child_node) + clk_unprepare_unused_subtree(child); + + if (core->prepare_count) 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)); + if (core->flags & CLK_IGNORE_UNUSED) + return; + + if (clk_core_is_prepared(core)) { + trace_clk_unprepare(core); + if (core->ops->unprepare_unused) + core->ops->unprepare_unused(core->hw); + else if (core->ops->unprepare) + core->ops->unprepare(core->hw); + trace_clk_unprepare_complete(core); + } } -static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, - int level) +static void clk_disable_unused_subtree(struct clk_core *core) { struct clk_core *child; + unsigned long flags; - if (!c) - return; + lockdep_assert_held(&prepare_lock); - clk_summary_show_one(s, c, level); + hlist_for_each_entry(child, &core->children, child_node) + clk_disable_unused_subtree(child); - hlist_for_each_entry(child, &c->children, child_node) - clk_summary_show_subtree(s, child, level + 1); + flags = clk_enable_lock(); + + if (core->enable_count) + goto unlock_out; + + if (core->flags & CLK_IGNORE_UNUSED) + goto unlock_out; + + /* + * some gate clocks have special needs during the disable-unused + * sequence. call .disable_unused if available, otherwise fall + * back to .disable + */ + if (clk_core_is_enabled(core)) { + trace_clk_disable(core); + if (core->ops->disable_unused) + core->ops->disable_unused(core->hw); + else if (core->ops->disable) + core->ops->disable(core->hw); + trace_clk_disable_complete(core); + } + +unlock_out: + clk_enable_unlock(flags); } -static int clk_summary_show(struct seq_file *s, void *data) +static bool clk_ignore_unused; +static int __init clk_ignore_unused_setup(char *__unused) { - struct clk_core *c; - struct hlist_head **lists = (struct hlist_head **)s->private; + clk_ignore_unused = true; + return 1; +} +__setup("clk_ignore_unused", clk_ignore_unused_setup); - seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n"); - seq_puts(s, "----------------------------------------------------------------------------------------\n"); +static int clk_disable_unused(void) +{ + struct clk_core *core; + + if (clk_ignore_unused) { + pr_warn("clk: Not disabling unused clocks\n"); + return 0; + } clk_prepare_lock(); - for (; *lists; lists++) - hlist_for_each_entry(c, *lists, child_node) - clk_summary_show_subtree(s, c, 0); + hlist_for_each_entry(core, &clk_root_list, child_node) + clk_disable_unused_subtree(core); + + hlist_for_each_entry(core, &clk_orphan_list, child_node) + clk_disable_unused_subtree(core); + + hlist_for_each_entry(core, &clk_root_list, child_node) + clk_unprepare_unused_subtree(core); + + hlist_for_each_entry(core, &clk_orphan_list, child_node) + clk_unprepare_unused_subtree(core); clk_prepare_unlock(); return 0; } +late_initcall_sync(clk_disable_unused); +/*** helper functions ***/ -static int clk_summary_open(struct inode *inode, struct file *file) +const char *__clk_get_name(const struct clk *clk) { - return single_open(file, clk_summary_show, inode->i_private); + return !clk ? NULL : clk->core->name; } +EXPORT_SYMBOL_GPL(__clk_get_name); -static const struct file_operations clk_summary_fops = { - .open = clk_summary_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +const char *clk_hw_get_name(const struct clk_hw *hw) +{ + return hw->core->name; +} +EXPORT_SYMBOL_GPL(clk_hw_get_name); -static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) +struct clk_hw *__clk_get_hw(struct clk *clk) { - if (!c) - return; + return !clk ? NULL : clk->core->hw; +} +EXPORT_SYMBOL_GPL(__clk_get_hw); - /* This should be JSON format, i.e. elements separated with a comma */ - 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)); +unsigned int clk_hw_get_num_parents(const struct clk_hw *hw) +{ + return hw->core->num_parents; } +EXPORT_SYMBOL_GPL(clk_hw_get_num_parents); -static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level) +struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw) { - struct clk_core *child; + return hw->core->parent ? hw->core->parent->hw : NULL; +} +EXPORT_SYMBOL_GPL(clk_hw_get_parent); - if (!c) - return; +static struct clk_core *__clk_lookup_subtree(const char *name, + struct clk_core *core) +{ + struct clk_core *child; + struct clk_core *ret; - clk_dump_one(s, c, level); + if (!strcmp(core->name, name)) + return core; - hlist_for_each_entry(child, &c->children, child_node) { - seq_printf(s, ","); - clk_dump_subtree(s, child, level + 1); + hlist_for_each_entry(child, &core->children, child_node) { + ret = __clk_lookup_subtree(name, child); + if (ret) + return ret; } - seq_printf(s, "}"); + return NULL; } -static int clk_dump(struct seq_file *s, void *data) +static struct clk_core *clk_core_lookup(const char *name) { - struct clk_core *c; - bool first_node = true; - struct hlist_head **lists = (struct hlist_head **)s->private; - - seq_printf(s, "{"); + struct clk_core *root_clk; + struct clk_core *ret; - clk_prepare_lock(); + if (!name) + return NULL; - 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); - } + /* 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; } - clk_prepare_unlock(); + /* 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; + } - seq_printf(s, "}"); - return 0; + return NULL; } +static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, + u8 index) +{ + if (!core || index >= core->num_parents) + return NULL; + else if (!core->parents) + return clk_core_lookup(core->parent_names[index]); + else if (!core->parents[index]) + return core->parents[index] = + clk_core_lookup(core->parent_names[index]); + else + return core->parents[index]; +} -static int clk_dump_open(struct inode *inode, struct file *file) +struct clk_hw * +clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index) { - return single_open(file, clk_dump, inode->i_private); + struct clk_core *parent; + + parent = clk_core_get_parent_by_index(hw->core, index); + + return !parent ? NULL : parent->hw; } +EXPORT_SYMBOL_GPL(clk_hw_get_parent_by_index); -static const struct file_operations clk_dump_fops = { - .open = clk_dump_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +unsigned int __clk_get_enable_count(struct clk *clk) +{ + return !clk ? 0 : clk->core->enable_count; +} -static int clk_debug_create_one(struct clk_core *clk, struct dentry *pdentry) +static unsigned long clk_core_get_rate_nolock(struct clk_core *core) { - struct dentry *d; - int ret = -ENOMEM; + unsigned long ret; - if (!clk || !pdentry) { - ret = -EINVAL; + if (!core) { + ret = 0; goto out; } - d = debugfs_create_dir(clk->name, pdentry); - if (!d) + ret = core->rate; + + if (core->flags & CLK_IS_ROOT) goto out; - clk->dentry = d; + if (!core->parent) + ret = 0; - d = debugfs_create_u32("clk_rate", S_IRUGO, clk->dentry, - (u32 *)&clk->rate); - if (!d) - goto err_out; +out: + return ret; +} - d = debugfs_create_u32("clk_accuracy", S_IRUGO, clk->dentry, - (u32 *)&clk->accuracy); - if (!d) - goto err_out; +unsigned long clk_hw_get_rate(const struct clk_hw *hw) +{ + return clk_core_get_rate_nolock(hw->core); +} +EXPORT_SYMBOL_GPL(clk_hw_get_rate); - d = debugfs_create_u32("clk_phase", S_IRUGO, clk->dentry, - (u32 *)&clk->phase); - if (!d) - goto err_out; +static unsigned long __clk_get_accuracy(struct clk_core *core) +{ + if (!core) + return 0; - d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry, - (u32 *)&clk->flags); - if (!d) - goto err_out; + return core->accuracy; +} - d = debugfs_create_u32("clk_prepare_count", S_IRUGO, clk->dentry, - (u32 *)&clk->prepare_count); - if (!d) - goto err_out; +unsigned long __clk_get_flags(struct clk *clk) +{ + return !clk ? 0 : clk->core->flags; +} +EXPORT_SYMBOL_GPL(__clk_get_flags); - d = debugfs_create_u32("clk_enable_count", S_IRUGO, clk->dentry, - (u32 *)&clk->enable_count); - if (!d) - goto err_out; +unsigned long clk_hw_get_flags(const struct clk_hw *hw) +{ + return hw->core->flags; +} +EXPORT_SYMBOL_GPL(clk_hw_get_flags); - d = debugfs_create_u32("clk_notifier_count", S_IRUGO, clk->dentry, - (u32 *)&clk->notifier_count); - if (!d) - goto err_out; +bool clk_hw_is_prepared(const struct clk_hw *hw) +{ + return clk_core_is_prepared(hw->core); +} - if (clk->ops->debug_init) { - ret = clk->ops->debug_init(clk->hw, clk->dentry); - if (ret) - goto err_out; - } +bool clk_hw_is_enabled(const struct clk_hw *hw) +{ + return clk_core_is_enabled(hw->core); +} - ret = 0; - goto out; +bool __clk_is_enabled(struct clk *clk) +{ + if (!clk) + return false; -err_out: - debugfs_remove_recursive(clk->dentry); - clk->dentry = NULL; -out: - return ret; + return clk_core_is_enabled(clk->core); } +EXPORT_SYMBOL_GPL(__clk_is_enabled); -/** - * clk_debug_register - add a clk node to the debugfs clk tree - * @clk: 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 *clk) +static bool mux_is_better_rate(unsigned long rate, unsigned long now, + unsigned long best, unsigned long flags) { - int ret = 0; - - mutex_lock(&clk_debug_lock); - hlist_add_head(&clk->debug_node, &clk_debug_list); - - if (!inited) - goto unlock; - - ret = clk_debug_create_one(clk, rootdir); -unlock: - mutex_unlock(&clk_debug_lock); + if (flags & CLK_MUX_ROUND_CLOSEST) + return abs(now - rate) < abs(best - rate); - return ret; + return now <= rate && now > best; } - /** - * clk_debug_unregister - remove a clk node from the debugfs clk tree - * @clk: 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 *clk) +static int +clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req, + unsigned long flags) { - mutex_lock(&clk_debug_lock); - hlist_del_init(&clk->debug_node); - debugfs_remove_recursive(clk->dentry); - clk->dentry = NULL; - mutex_unlock(&clk_debug_lock); -} + struct clk_core *core = hw->core, *parent, *best_parent = NULL; + int i, num_parents, ret; + unsigned long best = 0; + struct clk_rate_request parent_req = *req; -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 NO_REPARENT flag set, pass through to current parent */ + if (core->flags & CLK_SET_RATE_NO_REPARENT) { + parent = core->parent; + if (core->flags & CLK_SET_RATE_PARENT) { + ret = __clk_determine_rate(parent ? parent->hw : NULL, + &parent_req); + if (ret) + return ret; + + best = parent_req.rate; + } else if (parent) { + best = clk_core_get_rate_nolock(parent); + } else { + best = clk_core_get_rate_nolock(core); + } - if (hw->core->dentry) - d = debugfs_create_file(name, mode, hw->core->dentry, data, - fops); + goto out; + } - return d; -} -EXPORT_SYMBOL_GPL(clk_debugfs_add_file); + /* find the parent that can provide the fastest rate <= rate */ + num_parents = core->num_parents; + for (i = 0; i < num_parents; i++) { + parent = clk_core_get_parent_by_index(core, i); + if (!parent) + continue; -/** - * 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 *clk; - struct dentry *d; + if (core->flags & CLK_SET_RATE_PARENT) { + parent_req = *req; + ret = __clk_determine_rate(parent->hw, &parent_req); + if (ret) + continue; + } else { + parent_req.rate = clk_core_get_rate_nolock(parent); + } - rootdir = debugfs_create_dir("clk", NULL); + if (mux_is_better_rate(req->rate, parent_req.rate, + best, flags)) { + best_parent = parent; + best = parent_req.rate; + } + } - if (!rootdir) - return -ENOMEM; + if (!best_parent) + return -EINVAL; - d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists, - &clk_summary_fops); - if (!d) - return -ENOMEM; +out: + if (best_parent) + req->best_parent_hw = best_parent->hw; + req->best_parent_rate = best; + req->rate = best; - d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists, - &clk_dump_fops); - if (!d) - return -ENOMEM; + return 0; +} - d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir, - &orphan_list, &clk_summary_fops); - if (!d) - return -ENOMEM; +struct clk *__clk_lookup(const char *name) +{ + struct clk_core *core = clk_core_lookup(name); - d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir, - &orphan_list, &clk_dump_fops); - if (!d) - return -ENOMEM; + return !core ? NULL : core->hw->clk; +} - mutex_lock(&clk_debug_lock); - hlist_for_each_entry(clk, &clk_debug_list, debug_node) - clk_debug_create_one(clk, rootdir); +static void clk_core_get_boundaries(struct clk_core *core, + unsigned long *min_rate, + unsigned long *max_rate) +{ + struct clk *clk_user; - inited = 1; - mutex_unlock(&clk_debug_lock); + *min_rate = core->min_rate; + *max_rate = core->max_rate; - return 0; + hlist_for_each_entry(clk_user, &core->clks, clks_node) + *min_rate = max(*min_rate, clk_user->min_rate); + + hlist_for_each_entry(clk_user, &core->clks, clks_node) + *max_rate = min(*max_rate, clk_user->max_rate); } -late_initcall(clk_debug_init); -#else -static inline int clk_debug_register(struct clk_core *clk) { return 0; } -static inline void clk_debug_reparent(struct clk_core *clk, - struct clk_core *new_parent) + +void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate, + unsigned long max_rate) { + hw->core->min_rate = min_rate; + hw->core->max_rate = max_rate; } -static inline void clk_debug_unregister(struct clk_core *clk) +EXPORT_SYMBOL_GPL(clk_hw_set_rate_range); + +/* + * Helper for finding best parent to provide a given frequency. This can be used + * directly as a determine_rate callback (e.g. for a mux), or from a more + * complex clock that may combine a mux with other operations. + */ +int __clk_mux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { + return clk_mux_determine_rate_flags(hw, req, 0); } -#endif +EXPORT_SYMBOL_GPL(__clk_mux_determine_rate); -/* caller must hold prepare_lock */ -static void clk_unprepare_unused_subtree(struct clk_core *clk) +int __clk_mux_determine_rate_closest(struct clk_hw *hw, + struct clk_rate_request *req) { - struct clk_core *child; + return clk_mux_determine_rate_flags(hw, req, CLK_MUX_ROUND_CLOSEST); +} +EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest); +/*** clk api ***/ + +static void clk_core_unprepare(struct clk_core *core) +{ lockdep_assert_held(&prepare_lock); - hlist_for_each_entry(child, &clk->children, child_node) - clk_unprepare_unused_subtree(child); + if (!core) + return; - if (clk->prepare_count) + if (WARN_ON(core->prepare_count == 0)) return; - if (clk->flags & CLK_IGNORE_UNUSED) + if (--core->prepare_count > 0) return; - if (clk_core_is_prepared(clk)) { - trace_clk_unprepare(clk); - if (clk->ops->unprepare_unused) - clk->ops->unprepare_unused(clk->hw); - else if (clk->ops->unprepare) - clk->ops->unprepare(clk->hw); - trace_clk_unprepare_complete(clk); - } + WARN_ON(core->enable_count > 0); + + trace_clk_unprepare(core); + + if (core->ops->unprepare) + core->ops->unprepare(core->hw); + + trace_clk_unprepare_complete(core); + clk_core_unprepare(core->parent); +} + +/** + * clk_unprepare - undo preparation of a clock source + * @clk: the clk being unprepared + * + * clk_unprepare may sleep, which differentiates it from clk_disable. In a + * simple case, clk_unprepare can be used instead of clk_disable to gate a clk + * if the operation may sleep. One example is a clk which is accessed over + * I2c. In the complex case a clk gate operation may require a fast and a slow + * part. It is this reason that clk_unprepare and clk_disable are not mutually + * exclusive. In fact clk_disable must be called before clk_unprepare. + */ +void clk_unprepare(struct clk *clk) +{ + if (IS_ERR_OR_NULL(clk)) + return; + + clk_prepare_lock(); + clk_core_unprepare(clk->core); + clk_prepare_unlock(); } +EXPORT_SYMBOL_GPL(clk_unprepare); -/* caller must hold prepare_lock */ -static void clk_disable_unused_subtree(struct clk_core *clk) +static int clk_core_prepare(struct clk_core *core) { - struct clk_core *child; - unsigned long flags; + int ret = 0; lockdep_assert_held(&prepare_lock); - hlist_for_each_entry(child, &clk->children, child_node) - clk_disable_unused_subtree(child); + if (!core) + return 0; - flags = clk_enable_lock(); + if (core->prepare_count == 0) { + ret = clk_core_prepare(core->parent); + if (ret) + return ret; - if (clk->enable_count) - goto unlock_out; + trace_clk_prepare(core); - if (clk->flags & CLK_IGNORE_UNUSED) - goto unlock_out; + if (core->ops->prepare) + ret = core->ops->prepare(core->hw); - /* - * some gate clocks have special needs during the disable-unused - * sequence. call .disable_unused if available, otherwise fall - * back to .disable - */ - if (clk_core_is_enabled(clk)) { - trace_clk_disable(clk); - if (clk->ops->disable_unused) - clk->ops->disable_unused(clk->hw); - else if (clk->ops->disable) - clk->ops->disable(clk->hw); - trace_clk_disable_complete(clk); + trace_clk_prepare_complete(core); + + if (ret) { + clk_core_unprepare(core->parent); + return ret; + } } -unlock_out: - clk_enable_unlock(flags); -} + core->prepare_count++; -static bool clk_ignore_unused; -static int __init clk_ignore_unused_setup(char *__unused) -{ - clk_ignore_unused = true; - return 1; + return 0; } -__setup("clk_ignore_unused", clk_ignore_unused_setup); -static int clk_disable_unused(void) +/** + * clk_prepare - prepare a clock source + * @clk: the clk being prepared + * + * clk_prepare may sleep, which differentiates it from clk_enable. In a simple + * case, clk_prepare can be used instead of clk_enable to ungate a clk if the + * operation may sleep. One example is a clk which is accessed over I2c. In + * the complex case a clk ungate operation may require a fast and a slow part. + * It is this reason that clk_prepare and clk_enable are not mutually + * exclusive. In fact clk_prepare must be called before clk_enable. + * Returns 0 on success, -EERROR otherwise. + */ +int clk_prepare(struct clk *clk) { - struct clk_core *clk; + int ret; - if (clk_ignore_unused) { - pr_warn("clk: Not disabling unused clocks\n"); + if (!clk) return 0; - } clk_prepare_lock(); + ret = clk_core_prepare(clk->core); + clk_prepare_unlock(); - hlist_for_each_entry(clk, &clk_root_list, child_node) - clk_disable_unused_subtree(clk); + return ret; +} +EXPORT_SYMBOL_GPL(clk_prepare); - hlist_for_each_entry(clk, &clk_orphan_list, child_node) - clk_disable_unused_subtree(clk); +static void clk_core_disable(struct clk_core *core) +{ + lockdep_assert_held(&enable_lock); - hlist_for_each_entry(clk, &clk_root_list, child_node) - clk_unprepare_unused_subtree(clk); + if (!core) + return; - hlist_for_each_entry(clk, &clk_orphan_list, child_node) - clk_unprepare_unused_subtree(clk); + if (WARN_ON(core->enable_count == 0)) + return; - clk_prepare_unlock(); + if (--core->enable_count > 0) + return; - return 0; -} -late_initcall_sync(clk_disable_unused); + trace_clk_disable(core); -/*** helper functions ***/ + if (core->ops->disable) + core->ops->disable(core->hw); -const char *__clk_get_name(struct clk *clk) -{ - return !clk ? NULL : clk->core->name; -} -EXPORT_SYMBOL_GPL(__clk_get_name); + trace_clk_disable_complete(core); -struct clk_hw *__clk_get_hw(struct clk *clk) -{ - return !clk ? NULL : clk->core->hw; + clk_core_disable(core->parent); } -EXPORT_SYMBOL_GPL(__clk_get_hw); -u8 __clk_get_num_parents(struct clk *clk) +/** + * clk_disable - gate a clock + * @clk: the clk being gated + * + * clk_disable must not sleep, which differentiates it from clk_unprepare. In + * a simple case, clk_disable can be used instead of clk_unprepare to gate a + * clk if the operation is fast and will never sleep. One example is a + * SoC-internal clk which is controlled via simple register writes. In the + * complex case a clk gate operation may require a fast and a slow part. It is + * this reason that clk_unprepare and clk_disable are not mutually exclusive. + * In fact clk_disable must be called before clk_unprepare. + */ +void clk_disable(struct clk *clk) { - return !clk ? 0 : clk->core->num_parents; -} -EXPORT_SYMBOL_GPL(__clk_get_num_parents); + unsigned long flags; -struct clk *__clk_get_parent(struct clk *clk) -{ - if (!clk) - return NULL; + if (IS_ERR_OR_NULL(clk)) + return; - /* TODO: Create a per-user clk and change callers to call clk_put */ - return !clk->core->parent ? NULL : clk->core->parent->hw->clk; + flags = clk_enable_lock(); + clk_core_disable(clk->core); + clk_enable_unlock(flags); } -EXPORT_SYMBOL_GPL(__clk_get_parent); +EXPORT_SYMBOL_GPL(clk_disable); -static struct clk_core *clk_core_get_parent_by_index(struct clk_core *clk, - u8 index) +static int clk_core_enable(struct clk_core *core) { - if (!clk || index >= clk->num_parents) - return NULL; - else if (!clk->parents) - return clk_core_lookup(clk->parent_names[index]); - else if (!clk->parents[index]) - return clk->parents[index] = - clk_core_lookup(clk->parent_names[index]); - else - return clk->parents[index]; -} + int ret = 0; -struct clk *clk_get_parent_by_index(struct clk *clk, u8 index) -{ - struct clk_core *parent; + lockdep_assert_held(&enable_lock); - if (!clk) - return NULL; + if (!core) + return 0; - parent = clk_core_get_parent_by_index(clk->core, index); + if (WARN_ON(core->prepare_count == 0)) + return -ESHUTDOWN; - return !parent ? NULL : parent->hw->clk; -} -EXPORT_SYMBOL_GPL(clk_get_parent_by_index); + if (core->enable_count == 0) { + ret = clk_core_enable(core->parent); -unsigned int __clk_get_enable_count(struct clk *clk) -{ - return !clk ? 0 : clk->core->enable_count; -} - -static unsigned long clk_core_get_rate_nolock(struct clk_core *clk) -{ - unsigned long ret; + if (ret) + return ret; - if (!clk) { - ret = 0; - goto out; - } + trace_clk_enable(core); - ret = clk->rate; + if (core->ops->enable) + ret = core->ops->enable(core->hw); - if (clk->flags & CLK_IS_ROOT) - goto out; + trace_clk_enable_complete(core); - if (!clk->parent) - ret = 0; + if (ret) { + clk_core_disable(core->parent); + return ret; + } + } -out: - return ret; + core->enable_count++; + return 0; } -unsigned long __clk_get_rate(struct clk *clk) +/** + * clk_enable - ungate a clock + * @clk: the clk being ungated + * + * clk_enable must not sleep, which differentiates it from clk_prepare. In a + * simple case, clk_enable can be used instead of clk_prepare to ungate a clk + * if the operation will never sleep. One example is a SoC-internal clk which + * is controlled via simple register writes. In the complex case a clk ungate + * operation may require a fast and a slow part. It is this reason that + * clk_enable and clk_prepare are not mutually exclusive. In fact clk_prepare + * must be called before clk_enable. Returns 0 on success, -EERROR + * otherwise. + */ +int clk_enable(struct clk *clk) { + unsigned long flags; + int ret; + if (!clk) return 0; - return clk_core_get_rate_nolock(clk->core); + flags = clk_enable_lock(); + ret = clk_core_enable(clk->core); + clk_enable_unlock(flags); + + return ret; } -EXPORT_SYMBOL_GPL(__clk_get_rate); +EXPORT_SYMBOL_GPL(clk_enable); -static unsigned long __clk_get_accuracy(struct clk_core *clk) +static int clk_core_round_rate_nolock(struct clk_core *core, + struct clk_rate_request *req) { - if (!clk) - return 0; + struct clk_core *parent; + long rate; - return clk->accuracy; -} + lockdep_assert_held(&prepare_lock); -unsigned long __clk_get_flags(struct clk *clk) -{ - return !clk ? 0 : clk->core->flags; -} -EXPORT_SYMBOL_GPL(__clk_get_flags); + if (!core) + return 0; -static bool clk_core_is_prepared(struct clk_core *clk) -{ - int ret; + parent = core->parent; + if (parent) { + req->best_parent_hw = parent->hw; + req->best_parent_rate = parent->rate; + } else { + req->best_parent_hw = NULL; + req->best_parent_rate = 0; + } - if (!clk) - return false; + if (core->ops->determine_rate) { + return core->ops->determine_rate(core->hw, req); + } else if (core->ops->round_rate) { + rate = core->ops->round_rate(core->hw, req->rate, + &req->best_parent_rate); + if (rate < 0) + return rate; - /* - * .is_prepared is optional for clocks that can prepare - * fall back to software usage counter if it is missing - */ - if (!clk->ops->is_prepared) { - ret = clk->prepare_count ? 1 : 0; - goto out; + req->rate = rate; + } else if (core->flags & CLK_SET_RATE_PARENT) { + return clk_core_round_rate_nolock(parent, req); + } else { + req->rate = core->rate; } - ret = clk->ops->is_prepared(clk->hw); -out: - return !!ret; + return 0; } -bool __clk_is_prepared(struct clk *clk) +/** + * __clk_determine_rate - get the closest rate actually supported by a clock + * @hw: determine the rate of this clock + * @rate: target rate + * @min_rate: returned rate must be greater than this rate + * @max_rate: returned rate must be less than this rate + * + * Useful for clk_ops such as .set_rate and .determine_rate. + */ +int __clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { - if (!clk) - return false; + if (!hw) { + req->rate = 0; + return 0; + } - return clk_core_is_prepared(clk->core); + return clk_core_round_rate_nolock(hw->core, req); } +EXPORT_SYMBOL_GPL(__clk_determine_rate); -static bool clk_core_is_enabled(struct clk_core *clk) +unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate) { int ret; + struct clk_rate_request req; - if (!clk) - return false; + clk_core_get_boundaries(hw->core, &req.min_rate, &req.max_rate); + req.rate = rate; - /* - * .is_enabled is only mandatory for clocks that gate - * fall back to software usage counter if .is_enabled is missing - */ - if (!clk->ops->is_enabled) { - ret = clk->enable_count ? 1 : 0; - goto out; - } + ret = clk_core_round_rate_nolock(hw->core, &req); + if (ret) + return 0; - ret = clk->ops->is_enabled(clk->hw); -out: - return !!ret; + return req.rate; } +EXPORT_SYMBOL_GPL(clk_hw_round_rate); -bool __clk_is_enabled(struct clk *clk) +/** + * clk_round_rate - round the given rate for a clk + * @clk: the clk for which we are rounding a rate + * @rate: the rate which is to be rounded + * + * Takes in a rate as input and rounds it to a rate that the clk can actually + * use which is then returned. If clk doesn't support round_rate operation + * then the parent rate is returned. + */ +long clk_round_rate(struct clk *clk, unsigned long rate) { + struct clk_rate_request req; + int ret; + if (!clk) - return false; + return 0; - return clk_core_is_enabled(clk->core); -} -EXPORT_SYMBOL_GPL(__clk_is_enabled); + clk_prepare_lock(); -static struct clk_core *__clk_lookup_subtree(const char *name, - struct clk_core *clk) -{ - struct clk_core *child; - struct clk_core *ret; + clk_core_get_boundaries(clk->core, &req.min_rate, &req.max_rate); + req.rate = rate; - if (!strcmp(clk->name, name)) - return clk; + ret = clk_core_round_rate_nolock(clk->core, &req); + clk_prepare_unlock(); - hlist_for_each_entry(child, &clk->children, child_node) { - ret = __clk_lookup_subtree(name, child); - if (ret) - return ret; - } + if (ret) + return ret; - return NULL; + return req.rate; } +EXPORT_SYMBOL_GPL(clk_round_rate); -static struct clk_core *clk_core_lookup(const char *name) +/** + * __clk_notify - call clk notifier chain + * @core: clk that is changing rate + * @msg: clk notifier type (see include/linux/clk.h) + * @old_rate: old clk rate + * @new_rate: new clk rate + * + * Triggers a notifier call chain on the clk rate-change notification + * for 'clk'. Passes a pointer to the struct clk and the previous + * and current rates to the notifier callback. Intended to be called by + * internal clock code only. Returns NOTIFY_DONE from the last driver + * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if + * a driver returns that. + */ +static int __clk_notify(struct clk_core *core, unsigned long msg, + unsigned long old_rate, unsigned long new_rate) { - struct clk_core *root_clk; - struct clk_core *ret; - - if (!name) - return NULL; + struct clk_notifier *cn; + struct clk_notifier_data cnd; + int ret = NOTIFY_DONE; - /* 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; - } + cnd.old_rate = old_rate; + cnd.new_rate = new_rate; - /* 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; + list_for_each_entry(cn, &clk_notifier_list, node) { + if (cn->clk->core == core) { + cnd.clk = cn->clk; + ret = srcu_notifier_call_chain(&cn->notifier_head, msg, + &cnd); + } } - return NULL; -} - -static bool mux_is_better_rate(unsigned long rate, unsigned long now, - unsigned long best, unsigned long flags) -{ - if (flags & CLK_MUX_ROUND_CLOSEST) - return abs(now - rate) < abs(best - rate); - - return now <= rate && now > best; + return ret; } -static long -clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate, - unsigned long min_rate, - unsigned long max_rate, - unsigned long *best_parent_rate, - struct clk_hw **best_parent_p, - unsigned long flags) +/** + * __clk_recalc_accuracies + * @core: first clk in the subtree + * + * Walks the subtree of clks starting with clk and recalculates accuracies as + * it goes. Note that if a clk does not implement the .recalc_accuracy + * callback then it is assumed that the clock will take on the accuracy of its + * parent. + */ +static void __clk_recalc_accuracies(struct clk_core *core) { - struct clk_core *core = hw->core, *parent, *best_parent = NULL; - int i, num_parents; - unsigned long parent_rate, best = 0; - - /* if NO_REPARENT flag set, pass through to current parent */ - if (core->flags & CLK_SET_RATE_NO_REPARENT) { - parent = core->parent; - if (core->flags & CLK_SET_RATE_PARENT) - best = __clk_determine_rate(parent ? parent->hw : NULL, - rate, min_rate, max_rate); - else if (parent) - best = clk_core_get_rate_nolock(parent); - else - best = clk_core_get_rate_nolock(core); - goto out; - } - - /* find the parent that can provide the fastest rate <= rate */ - num_parents = core->num_parents; - for (i = 0; i < num_parents; i++) { - parent = clk_core_get_parent_by_index(core, i); - if (!parent) - continue; - if (core->flags & CLK_SET_RATE_PARENT) - parent_rate = __clk_determine_rate(parent->hw, rate, - min_rate, - max_rate); - else - parent_rate = clk_core_get_rate_nolock(parent); - if (mux_is_better_rate(rate, parent_rate, best, flags)) { - best_parent = parent; - best = parent_rate; - } - } + unsigned long parent_accuracy = 0; + struct clk_core *child; -out: - if (best_parent) - *best_parent_p = best_parent->hw; - *best_parent_rate = best; + lockdep_assert_held(&prepare_lock); - return best; -} + if (core->parent) + parent_accuracy = core->parent->accuracy; -struct clk *__clk_lookup(const char *name) -{ - struct clk_core *core = clk_core_lookup(name); + if (core->ops->recalc_accuracy) + core->accuracy = core->ops->recalc_accuracy(core->hw, + parent_accuracy); + else + core->accuracy = parent_accuracy; - return !core ? NULL : core->hw->clk; + hlist_for_each_entry(child, &core->children, child_node) + __clk_recalc_accuracies(child); } -static void clk_core_get_boundaries(struct clk_core *clk, - unsigned long *min_rate, - unsigned long *max_rate) +static long clk_core_get_accuracy(struct clk_core *core) { - struct clk *clk_user; + unsigned long accuracy; - *min_rate = 0; - *max_rate = ULONG_MAX; + clk_prepare_lock(); + if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE)) + __clk_recalc_accuracies(core); - hlist_for_each_entry(clk_user, &clk->clks, clks_node) - *min_rate = max(*min_rate, clk_user->min_rate); + accuracy = __clk_get_accuracy(core); + clk_prepare_unlock(); - hlist_for_each_entry(clk_user, &clk->clks, clks_node) - *max_rate = min(*max_rate, clk_user->max_rate); + return accuracy; } -/* - * Helper for finding best parent to provide a given frequency. This can be used - * directly as a determine_rate callback (e.g. for a mux), or from a more - * complex clock that may combine a mux with other operations. +/** + * clk_get_accuracy - return the accuracy of clk + * @clk: the clk whose accuracy is being returned + * + * Simply returns the cached accuracy of the clk, unless + * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be + * issued. + * If clk is NULL then returns 0. */ -long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long min_rate, - unsigned long max_rate, - unsigned long *best_parent_rate, - struct clk_hw **best_parent_p) +long clk_get_accuracy(struct clk *clk) { - return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate, - best_parent_rate, - best_parent_p, 0); -} -EXPORT_SYMBOL_GPL(__clk_mux_determine_rate); + if (!clk) + return 0; -long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate, - unsigned long min_rate, - unsigned long max_rate, - unsigned long *best_parent_rate, - struct clk_hw **best_parent_p) -{ - return clk_mux_determine_rate_flags(hw, rate, min_rate, max_rate, - best_parent_rate, - best_parent_p, - CLK_MUX_ROUND_CLOSEST); + return clk_core_get_accuracy(clk->core); } -EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest); - -/*** clk api ***/ +EXPORT_SYMBOL_GPL(clk_get_accuracy); -static void clk_core_unprepare(struct clk_core *clk) +static unsigned long clk_recalc(struct clk_core *core, + unsigned long parent_rate) { - if (!clk) - return; - - if (WARN_ON(clk->prepare_count == 0)) - return; - - if (--clk->prepare_count > 0) - return; - - WARN_ON(clk->enable_count > 0); - - trace_clk_unprepare(clk); - - if (clk->ops->unprepare) - clk->ops->unprepare(clk->hw); - - trace_clk_unprepare_complete(clk); - clk_core_unprepare(clk->parent); -} + if (core->ops->recalc_rate) + return core->ops->recalc_rate(core->hw, parent_rate); + return parent_rate; +} /** - * clk_unprepare - undo preparation of a clock source - * @clk: the clk being unprepared + * __clk_recalc_rates + * @core: first clk in the subtree + * @msg: notification type (see include/linux/clk.h) * - * clk_unprepare may sleep, which differentiates it from clk_disable. In a - * simple case, clk_unprepare can be used instead of clk_disable to gate a clk - * if the operation may sleep. One example is a clk which is accessed over - * I2c. In the complex case a clk gate operation may require a fast and a slow - * part. It is this reason that clk_unprepare and clk_disable are not mutually - * exclusive. In fact clk_disable must be called before clk_unprepare. + * Walks the subtree of clks starting with clk and recalculates rates as it + * goes. Note that if a clk does not implement the .recalc_rate callback then + * it is assumed that the clock will take on the rate of its parent. + * + * clk_recalc_rates also propagates the POST_RATE_CHANGE notification, + * if necessary. */ -void clk_unprepare(struct clk *clk) +static void __clk_recalc_rates(struct clk_core *core, unsigned long msg) { - if (IS_ERR_OR_NULL(clk)) - return; + unsigned long old_rate; + unsigned long parent_rate = 0; + struct clk_core *child; - clk_prepare_lock(); - clk_core_unprepare(clk->core); - clk_prepare_unlock(); -} -EXPORT_SYMBOL_GPL(clk_unprepare); + lockdep_assert_held(&prepare_lock); -static int clk_core_prepare(struct clk_core *clk) -{ - int ret = 0; + old_rate = core->rate; - if (!clk) - return 0; + if (core->parent) + parent_rate = core->parent->rate; - if (clk->prepare_count == 0) { - ret = clk_core_prepare(clk->parent); - if (ret) - return ret; + core->rate = clk_recalc(core, parent_rate); - trace_clk_prepare(clk); + /* + * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE + * & ABORT_RATE_CHANGE notifiers + */ + if (core->notifier_count && msg) + __clk_notify(core, msg, old_rate, core->rate); - if (clk->ops->prepare) - ret = clk->ops->prepare(clk->hw); + hlist_for_each_entry(child, &core->children, child_node) + __clk_recalc_rates(child, msg); +} - trace_clk_prepare_complete(clk); +static unsigned long clk_core_get_rate(struct clk_core *core) +{ + unsigned long rate; - if (ret) { - clk_core_unprepare(clk->parent); - return ret; - } - } + clk_prepare_lock(); - clk->prepare_count++; + if (core && (core->flags & CLK_GET_RATE_NOCACHE)) + __clk_recalc_rates(core, 0); - return 0; + rate = clk_core_get_rate_nolock(core); + clk_prepare_unlock(); + + return rate; } /** - * clk_prepare - prepare a clock source - * @clk: the clk being prepared + * clk_get_rate - return the rate of clk + * @clk: the clk whose rate is being returned * - * clk_prepare may sleep, which differentiates it from clk_enable. In a simple - * case, clk_prepare can be used instead of clk_enable to ungate a clk if the - * operation may sleep. One example is a clk which is accessed over I2c. In - * the complex case a clk ungate operation may require a fast and a slow part. - * It is this reason that clk_prepare and clk_enable are not mutually - * exclusive. In fact clk_prepare must be called before clk_enable. - * Returns 0 on success, -EERROR otherwise. + * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag + * is set, which means a recalc_rate will be issued. + * If clk is NULL then returns 0. */ -int clk_prepare(struct clk *clk) +unsigned long clk_get_rate(struct clk *clk) { - int ret; - if (!clk) return 0; - clk_prepare_lock(); - ret = clk_core_prepare(clk->core); - clk_prepare_unlock(); - - return ret; + return clk_core_get_rate(clk->core); } -EXPORT_SYMBOL_GPL(clk_prepare); +EXPORT_SYMBOL_GPL(clk_get_rate); -static void clk_core_disable(struct clk_core *clk) +static int clk_fetch_parent_index(struct clk_core *core, + struct clk_core *parent) { - if (!clk) - return; - - if (WARN_ON(clk->enable_count == 0)) - return; - - if (--clk->enable_count > 0) - return; - - trace_clk_disable(clk); + int i; - if (clk->ops->disable) - clk->ops->disable(clk->hw); + if (!core->parents) { + core->parents = kcalloc(core->num_parents, + sizeof(struct clk *), GFP_KERNEL); + if (!core->parents) + return -ENOMEM; + } - trace_clk_disable_complete(clk); + /* + * find index of new parent clock using cached parent ptrs, + * or if not yet cached, use string name comparison and cache + * them now to avoid future calls to clk_core_lookup. + */ + for (i = 0; i < core->num_parents; i++) { + if (core->parents[i] == parent) + return i; - clk_core_disable(clk->parent); -} + if (core->parents[i]) + continue; -static void __clk_disable(struct clk *clk) -{ - if (!clk) - return; + if (!strcmp(core->parent_names[i], parent->name)) { + core->parents[i] = clk_core_lookup(parent->name); + return i; + } + } - clk_core_disable(clk->core); + return -EINVAL; } -/** - * clk_disable - gate a clock - * @clk: the clk being gated - * - * clk_disable must not sleep, which differentiates it from clk_unprepare. In - * a simple case, clk_disable can be used instead of clk_unprepare to gate a - * clk if the operation is fast and will never sleep. One example is a - * SoC-internal clk which is controlled via simple register writes. In the - * complex case a clk gate operation may require a fast and a slow part. It is - * this reason that clk_unprepare and clk_disable are not mutually exclusive. - * In fact clk_disable must be called before clk_unprepare. +/* + * Update the orphan status of @core and all its children. */ -void clk_disable(struct clk *clk) +static void clk_core_update_orphan_status(struct clk_core *core, bool is_orphan) { - unsigned long flags; + struct clk_core *child; - if (IS_ERR_OR_NULL(clk)) - return; + core->orphan = is_orphan; - flags = clk_enable_lock(); - __clk_disable(clk); - clk_enable_unlock(flags); + hlist_for_each_entry(child, &core->children, child_node) + clk_core_update_orphan_status(child, is_orphan); } -EXPORT_SYMBOL_GPL(clk_disable); -static int clk_core_enable(struct clk_core *clk) +static void clk_reparent(struct clk_core *core, struct clk_core *new_parent) { - int ret = 0; + bool was_orphan = core->orphan; - if (!clk) - return 0; + hlist_del(&core->child_node); - if (WARN_ON(clk->prepare_count == 0)) - return -ESHUTDOWN; + if (new_parent) { + bool becomes_orphan = new_parent->orphan; - if (clk->enable_count == 0) { - ret = clk_core_enable(clk->parent); + /* avoid duplicate POST_RATE_CHANGE notifications */ + if (new_parent->new_child == core) + new_parent->new_child = NULL; - if (ret) - return ret; + hlist_add_head(&core->child_node, &new_parent->children); - trace_clk_enable(clk); + if (was_orphan != becomes_orphan) + clk_core_update_orphan_status(core, becomes_orphan); + } else { + hlist_add_head(&core->child_node, &clk_orphan_list); + if (!was_orphan) + clk_core_update_orphan_status(core, true); + } - if (clk->ops->enable) - ret = clk->ops->enable(clk->hw); + core->parent = new_parent; +} - trace_clk_enable_complete(clk); +static struct clk_core *__clk_set_parent_before(struct clk_core *core, + struct clk_core *parent) +{ + unsigned long flags; + struct clk_core *old_parent = core->parent; - if (ret) { - clk_core_disable(clk->parent); - return ret; - } + /* + * Migrate prepare state between parents and prevent race with + * clk_enable(). + * + * If the clock is not prepared, then a race with + * clk_enable/disable() is impossible since we already have the + * prepare lock (future calls to clk_enable() need to be preceded by + * a clk_prepare()). + * + * If the clock is prepared, migrate the prepared state to the new + * parent and also protect against a race with clk_enable() by + * forcing the clock and the new parent on. This ensures that all + * future calls to clk_enable() are practically NOPs with respect to + * hardware and software states. + * + * See also: Comment for clk_set_parent() below. + */ + if (core->prepare_count) { + clk_core_prepare(parent); + flags = clk_enable_lock(); + clk_core_enable(parent); + clk_core_enable(core); + clk_enable_unlock(flags); } - clk->enable_count++; - return 0; + /* update the clk tree topology */ + flags = clk_enable_lock(); + clk_reparent(core, parent); + clk_enable_unlock(flags); + + return old_parent; } -static int __clk_enable(struct clk *clk) +static void __clk_set_parent_after(struct clk_core *core, + struct clk_core *parent, + struct clk_core *old_parent) { - if (!clk) - return 0; + unsigned long flags; - return clk_core_enable(clk->core); + /* + * Finish the migration of prepare state and undo the changes done + * for preventing a race with clk_enable(). + */ + if (core->prepare_count) { + flags = clk_enable_lock(); + clk_core_disable(core); + clk_core_disable(old_parent); + clk_enable_unlock(flags); + clk_core_unprepare(old_parent); + } } -/** - * clk_enable - ungate a clock - * @clk: the clk being ungated - * - * clk_enable must not sleep, which differentiates it from clk_prepare. In a - * simple case, clk_enable can be used instead of clk_prepare to ungate a clk - * if the operation will never sleep. One example is a SoC-internal clk which - * is controlled via simple register writes. In the complex case a clk ungate - * operation may require a fast and a slow part. It is this reason that - * clk_enable and clk_prepare are not mutually exclusive. In fact clk_prepare - * must be called before clk_enable. Returns 0 on success, -EERROR - * otherwise. - */ -int clk_enable(struct clk *clk) +static int __clk_set_parent(struct clk_core *core, struct clk_core *parent, + u8 p_index) { unsigned long flags; - int ret; + int ret = 0; + struct clk_core *old_parent; - flags = clk_enable_lock(); - ret = __clk_enable(clk); - clk_enable_unlock(flags); + old_parent = __clk_set_parent_before(core, parent); - return ret; -} -EXPORT_SYMBOL_GPL(clk_enable); + trace_clk_set_parent(core, parent); -static unsigned long clk_core_round_rate_nolock(struct clk_core *clk, - unsigned long rate, - unsigned long min_rate, - unsigned long max_rate) -{ - unsigned long parent_rate = 0; - struct clk_core *parent; - struct clk_hw *parent_hw; + /* change clock input source */ + if (parent && core->ops->set_parent) + ret = core->ops->set_parent(core->hw, p_index); - lockdep_assert_held(&prepare_lock); + trace_clk_set_parent_complete(core, parent); - if (!clk) - return 0; + if (ret) { + flags = clk_enable_lock(); + clk_reparent(core, old_parent); + clk_enable_unlock(flags); + __clk_set_parent_after(core, old_parent, parent); - parent = clk->parent; - if (parent) - parent_rate = parent->rate; - - if (clk->ops->determine_rate) { - parent_hw = parent ? parent->hw : NULL; - return clk->ops->determine_rate(clk->hw, rate, - min_rate, max_rate, - &parent_rate, &parent_hw); - } else if (clk->ops->round_rate) - return clk->ops->round_rate(clk->hw, rate, &parent_rate); - else if (clk->flags & CLK_SET_RATE_PARENT) - return clk_core_round_rate_nolock(clk->parent, rate, min_rate, - max_rate); - else - return clk->rate; -} + return ret; + } -/** - * __clk_determine_rate - get the closest rate actually supported by a clock - * @hw: determine the rate of this clock - * @rate: target rate - * @min_rate: returned rate must be greater than this rate - * @max_rate: returned rate must be less than this rate - * - * Caller must hold prepare_lock. Useful for clk_ops such as .set_rate and - * .determine_rate. - */ -unsigned long __clk_determine_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long min_rate, - unsigned long max_rate) -{ - if (!hw) - return 0; + __clk_set_parent_after(core, parent, old_parent); - return clk_core_round_rate_nolock(hw->core, rate, min_rate, max_rate); + return 0; } -EXPORT_SYMBOL_GPL(__clk_determine_rate); /** - * __clk_round_rate - round the given rate for a clk - * @clk: round the rate of this clock - * @rate: the rate which is to be rounded + * __clk_speculate_rates + * @core: first clk in the subtree + * @parent_rate: the "future" rate of clk's parent + * + * Walks the subtree of clks starting with clk, speculating rates as it + * goes and firing off PRE_RATE_CHANGE notifications as necessary. * - * Caller must hold prepare_lock. Useful for clk_ops such as .set_rate + * Unlike clk_recalc_rates, clk_speculate_rates exists only for sending + * pre-rate change notifications and returns early if no clks in the + * subtree have subscribed to the notifications. Note that if a clk does not + * implement the .recalc_rate callback then it is assumed that the clock will + * take on the rate of its parent. */ -unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long min_rate; - unsigned long max_rate; - - if (!clk) - return 0; - - clk_core_get_boundaries(clk->core, &min_rate, &max_rate); - - return clk_core_round_rate_nolock(clk->core, rate, min_rate, max_rate); -} -EXPORT_SYMBOL_GPL(__clk_round_rate); - -/** - * clk_round_rate - round the given rate for a clk - * @clk: the clk for which we are rounding a rate - * @rate: the rate which is to be rounded - * - * Takes in a rate as input and rounds it to a rate that the clk can actually - * use which is then returned. If clk doesn't support round_rate operation - * then the parent rate is returned. - */ -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long ret; - - if (!clk) - return 0; - - clk_prepare_lock(); - ret = __clk_round_rate(clk, rate); - clk_prepare_unlock(); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_round_rate); - -/** - * __clk_notify - call clk notifier chain - * @clk: struct clk * that is changing rate - * @msg: clk notifier type (see include/linux/clk.h) - * @old_rate: old clk rate - * @new_rate: new clk rate - * - * Triggers a notifier call chain on the clk rate-change notification - * for 'clk'. Passes a pointer to the struct clk and the previous - * and current rates to the notifier callback. Intended to be called by - * internal clock code only. Returns NOTIFY_DONE from the last driver - * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if - * a driver returns that. - */ -static int __clk_notify(struct clk_core *clk, unsigned long msg, - unsigned long old_rate, unsigned long new_rate) -{ - struct clk_notifier *cn; - struct clk_notifier_data cnd; - int ret = NOTIFY_DONE; - - cnd.old_rate = old_rate; - cnd.new_rate = new_rate; - - list_for_each_entry(cn, &clk_notifier_list, node) { - if (cn->clk->core == clk) { - cnd.clk = cn->clk; - ret = srcu_notifier_call_chain(&cn->notifier_head, msg, - &cnd); - } - } - - return ret; -} - -/** - * __clk_recalc_accuracies - * @clk: first clk in the subtree - * - * Walks the subtree of clks starting with clk and recalculates accuracies as - * it goes. Note that if a clk does not implement the .recalc_accuracy - * callback then it is assumed that the clock will take on the accuracy of it's - * parent. - * - * Caller must hold prepare_lock. - */ -static void __clk_recalc_accuracies(struct clk_core *clk) -{ - unsigned long parent_accuracy = 0; - struct clk_core *child; - - lockdep_assert_held(&prepare_lock); - - if (clk->parent) - parent_accuracy = clk->parent->accuracy; - - if (clk->ops->recalc_accuracy) - clk->accuracy = clk->ops->recalc_accuracy(clk->hw, - parent_accuracy); - else - clk->accuracy = parent_accuracy; - - hlist_for_each_entry(child, &clk->children, child_node) - __clk_recalc_accuracies(child); -} - -static long clk_core_get_accuracy(struct clk_core *clk) -{ - unsigned long accuracy; - - clk_prepare_lock(); - if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE)) - __clk_recalc_accuracies(clk); - - accuracy = __clk_get_accuracy(clk); - clk_prepare_unlock(); - - return accuracy; -} - -/** - * clk_get_accuracy - return the accuracy of clk - * @clk: the clk whose accuracy is being returned - * - * Simply returns the cached accuracy of the clk, unless - * CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be - * issued. - * If clk is NULL then returns 0. - */ -long clk_get_accuracy(struct clk *clk) -{ - if (!clk) - return 0; - - return clk_core_get_accuracy(clk->core); -} -EXPORT_SYMBOL_GPL(clk_get_accuracy); - -static unsigned long clk_recalc(struct clk_core *clk, - unsigned long parent_rate) -{ - if (clk->ops->recalc_rate) - return clk->ops->recalc_rate(clk->hw, parent_rate); - return parent_rate; -} - -/** - * __clk_recalc_rates - * @clk: first clk in the subtree - * @msg: notification type (see include/linux/clk.h) - * - * Walks the subtree of clks starting with clk and recalculates rates as it - * goes. Note that if a clk does not implement the .recalc_rate callback then - * it is assumed that the clock will take on the rate of its parent. - * - * clk_recalc_rates also propagates the POST_RATE_CHANGE notification, - * if necessary. - * - * Caller must hold prepare_lock. - */ -static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg) -{ - unsigned long old_rate; - unsigned long parent_rate = 0; - struct clk_core *child; - - lockdep_assert_held(&prepare_lock); - - old_rate = clk->rate; - - if (clk->parent) - parent_rate = clk->parent->rate; - - clk->rate = clk_recalc(clk, parent_rate); - - /* - * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE - * & ABORT_RATE_CHANGE notifiers - */ - if (clk->notifier_count && msg) - __clk_notify(clk, msg, old_rate, clk->rate); - - hlist_for_each_entry(child, &clk->children, child_node) - __clk_recalc_rates(child, msg); -} - -static unsigned long clk_core_get_rate(struct clk_core *clk) -{ - unsigned long rate; - - clk_prepare_lock(); - - if (clk && (clk->flags & CLK_GET_RATE_NOCACHE)) - __clk_recalc_rates(clk, 0); - - rate = clk_core_get_rate_nolock(clk); - clk_prepare_unlock(); - - return rate; -} - -/** - * clk_get_rate - return the rate of clk - * @clk: the clk whose rate is being returned - * - * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag - * is set, which means a recalc_rate will be issued. - * If clk is NULL then returns 0. - */ -unsigned long clk_get_rate(struct clk *clk) -{ - if (!clk) - return 0; - - return clk_core_get_rate(clk->core); -} -EXPORT_SYMBOL_GPL(clk_get_rate); - -static int clk_fetch_parent_index(struct clk_core *clk, - struct clk_core *parent) -{ - int i; - - if (!clk->parents) { - clk->parents = kcalloc(clk->num_parents, - sizeof(struct clk *), GFP_KERNEL); - if (!clk->parents) - return -ENOMEM; - } - - /* - * find index of new parent clock using cached parent ptrs, - * or if not yet cached, use string name comparison and cache - * them now to avoid future calls to clk_core_lookup. - */ - for (i = 0; i < clk->num_parents; i++) { - if (clk->parents[i] == parent) - return i; - - if (clk->parents[i]) - continue; - - if (!strcmp(clk->parent_names[i], parent->name)) { - clk->parents[i] = clk_core_lookup(parent->name); - return i; - } - } - - return -EINVAL; -} - -static void clk_reparent(struct clk_core *clk, struct clk_core *new_parent) -{ - hlist_del(&clk->child_node); - - if (new_parent) { - /* avoid duplicate POST_RATE_CHANGE notifications */ - if (new_parent->new_child == clk) - new_parent->new_child = NULL; - - hlist_add_head(&clk->child_node, &new_parent->children); - } else { - hlist_add_head(&clk->child_node, &clk_orphan_list); - } - - clk->parent = new_parent; -} - -static struct clk_core *__clk_set_parent_before(struct clk_core *clk, - struct clk_core *parent) -{ - unsigned long flags; - struct clk_core *old_parent = clk->parent; - - /* - * Migrate prepare state between parents and prevent race with - * clk_enable(). - * - * If the clock is not prepared, then a race with - * clk_enable/disable() is impossible since we already have the - * prepare lock (future calls to clk_enable() need to be preceded by - * a clk_prepare()). - * - * If the clock is prepared, migrate the prepared state to the new - * parent and also protect against a race with clk_enable() by - * forcing the clock and the new parent on. This ensures that all - * future calls to clk_enable() are practically NOPs with respect to - * hardware and software states. - * - * See also: Comment for clk_set_parent() below. - */ - if (clk->prepare_count) { - clk_core_prepare(parent); - flags = clk_enable_lock(); - clk_core_enable(parent); - clk_core_enable(clk); - clk_enable_unlock(flags); - } - - /* update the clk tree topology */ - flags = clk_enable_lock(); - clk_reparent(clk, parent); - clk_enable_unlock(flags); - - return old_parent; -} - -static void __clk_set_parent_after(struct clk_core *core, - struct clk_core *parent, - struct clk_core *old_parent) -{ - unsigned long flags; - - /* - * Finish the migration of prepare state and undo the changes done - * for preventing a race with clk_enable(). - */ - if (core->prepare_count) { - flags = clk_enable_lock(); - clk_core_disable(core); - clk_core_disable(old_parent); - clk_enable_unlock(flags); - clk_core_unprepare(old_parent); - } -} - -static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent, - u8 p_index) -{ - unsigned long flags; - int ret = 0; - struct clk_core *old_parent; - - old_parent = __clk_set_parent_before(clk, parent); - - trace_clk_set_parent(clk, parent); - - /* change clock input source */ - if (parent && clk->ops->set_parent) - ret = clk->ops->set_parent(clk->hw, p_index); - - trace_clk_set_parent_complete(clk, parent); - - if (ret) { - flags = clk_enable_lock(); - clk_reparent(clk, old_parent); - clk_enable_unlock(flags); - - if (clk->prepare_count) { - flags = clk_enable_lock(); - clk_core_disable(clk); - clk_core_disable(parent); - clk_enable_unlock(flags); - clk_core_unprepare(parent); - } - return ret; - } - - __clk_set_parent_after(clk, parent, old_parent); - - return 0; -} - -/** - * __clk_speculate_rates - * @clk: first clk in the subtree - * @parent_rate: the "future" rate of clk's parent - * - * Walks the subtree of clks starting with clk, speculating rates as it - * goes and firing off PRE_RATE_CHANGE notifications as necessary. - * - * Unlike clk_recalc_rates, clk_speculate_rates exists only for sending - * pre-rate change notifications and returns early if no clks in the - * subtree have subscribed to the notifications. Note that if a clk does not - * implement the .recalc_rate callback then it is assumed that the clock will - * take on the rate of its parent. - * - * Caller must hold prepare_lock. - */ -static int __clk_speculate_rates(struct clk_core *clk, - unsigned long parent_rate) +static int __clk_speculate_rates(struct clk_core *core, + unsigned long parent_rate) { struct clk_core *child; unsigned long new_rate; @@ -1571,19 +1246,19 @@ static int __clk_speculate_rates(struct clk_core *clk, lockdep_assert_held(&prepare_lock); - new_rate = clk_recalc(clk, parent_rate); + new_rate = clk_recalc(core, parent_rate); /* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */ - if (clk->notifier_count) - ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate); + if (core->notifier_count) + ret = __clk_notify(core, PRE_RATE_CHANGE, core->rate, new_rate); if (ret & NOTIFY_STOP_MASK) { pr_debug("%s: clk notifier callback for clock %s aborted with error %d\n", - __func__, clk->name, ret); + __func__, core->name, ret); goto out; } - hlist_for_each_entry(child, &clk->children, child_node) { + hlist_for_each_entry(child, &core->children, child_node) { ret = __clk_speculate_rates(child, new_rate); if (ret & NOTIFY_STOP_MASK) break; @@ -1593,20 +1268,20 @@ out: return ret; } -static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate, +static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate, struct clk_core *new_parent, u8 p_index) { struct clk_core *child; - clk->new_rate = new_rate; - clk->new_parent = new_parent; - clk->new_parent_index = p_index; + core->new_rate = new_rate; + core->new_parent = new_parent; + core->new_parent_index = p_index; /* include clk in new parent's PRE_RATE_CHANGE notifications */ - clk->new_child = NULL; - if (new_parent && new_parent != clk->parent) - new_parent->new_child = clk; + core->new_child = NULL; + if (new_parent && new_parent != core->parent) + new_parent->new_child = core; - hlist_for_each_entry(child, &clk->children, child_node) { + hlist_for_each_entry(child, &core->children, child_node) { child->new_rate = clk_recalc(child, new_rate); clk_calc_subtree(child, child->new_rate, NULL, 0); } @@ -1616,12 +1291,11 @@ static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate, * calculate the new rates returning the topmost clock that has to be * changed. */ -static struct clk_core *clk_calc_new_rates(struct clk_core *clk, +static struct clk_core *clk_calc_new_rates(struct clk_core *core, unsigned long rate) { - struct clk_core *top = clk; + struct clk_core *top = core; struct clk_core *old_parent, *parent; - struct clk_hw *parent_hw; unsigned long best_parent_rate = 0; unsigned long new_rate; unsigned long min_rate; @@ -1630,41 +1304,50 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk, long ret; /* sanity */ - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR_OR_NULL(core)) return NULL; /* save parent rate, if it exists */ - parent = old_parent = clk->parent; + parent = old_parent = core->parent; if (parent) best_parent_rate = parent->rate; - clk_core_get_boundaries(clk, &min_rate, &max_rate); + clk_core_get_boundaries(core, &min_rate, &max_rate); /* find the closest rate and parent clk/rate */ - if (clk->ops->determine_rate) { - parent_hw = parent ? parent->hw : NULL; - ret = clk->ops->determine_rate(clk->hw, rate, - min_rate, - max_rate, - &best_parent_rate, - &parent_hw); + if (core->ops->determine_rate) { + struct clk_rate_request req; + + req.rate = rate; + req.min_rate = min_rate; + req.max_rate = max_rate; + if (parent) { + req.best_parent_hw = parent->hw; + req.best_parent_rate = parent->rate; + } else { + req.best_parent_hw = NULL; + req.best_parent_rate = 0; + } + + ret = core->ops->determine_rate(core->hw, &req); if (ret < 0) return NULL; - new_rate = ret; - parent = parent_hw ? parent_hw->core : NULL; - } else if (clk->ops->round_rate) { - ret = clk->ops->round_rate(clk->hw, rate, - &best_parent_rate); + best_parent_rate = req.best_parent_rate; + new_rate = req.rate; + parent = req.best_parent_hw ? req.best_parent_hw->core : NULL; + } else if (core->ops->round_rate) { + ret = core->ops->round_rate(core->hw, rate, + &best_parent_rate); if (ret < 0) return NULL; new_rate = ret; if (new_rate < min_rate || new_rate > max_rate) return NULL; - } else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) { + } else if (!parent || !(core->flags & CLK_SET_RATE_PARENT)) { /* pass-through clock without adjustable parent */ - clk->new_rate = clk->rate; + core->new_rate = core->rate; return NULL; } else { /* pass-through clock with adjustable parent */ @@ -1675,28 +1358,28 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk, /* some clocks must be gated to change parent */ if (parent != old_parent && - (clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) { + (core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) { pr_debug("%s: %s not gated but wants to reparent\n", - __func__, clk->name); + __func__, core->name); return NULL; } /* try finding the new parent index */ - if (parent && clk->num_parents > 1) { - p_index = clk_fetch_parent_index(clk, parent); + if (parent && core->num_parents > 1) { + p_index = clk_fetch_parent_index(core, parent); if (p_index < 0) { pr_debug("%s: clk %s can not be parent of clk %s\n", - __func__, parent->name, clk->name); + __func__, parent->name, core->name); return NULL; } } - if ((clk->flags & CLK_SET_RATE_PARENT) && parent && + if ((core->flags & CLK_SET_RATE_PARENT) && parent && best_parent_rate != parent->rate) top = clk_calc_new_rates(parent, best_parent_rate); out: - clk_calc_subtree(clk, new_rate, parent, p_index); + clk_calc_subtree(core, new_rate, parent, p_index); return top; } @@ -1706,33 +1389,33 @@ out: * so that in case of an error we can walk down the whole tree again and * abort the change. */ -static struct clk_core *clk_propagate_rate_change(struct clk_core *clk, +static struct clk_core *clk_propagate_rate_change(struct clk_core *core, unsigned long event) { struct clk_core *child, *tmp_clk, *fail_clk = NULL; int ret = NOTIFY_DONE; - if (clk->rate == clk->new_rate) + if (core->rate == core->new_rate) return NULL; - if (clk->notifier_count) { - ret = __clk_notify(clk, event, clk->rate, clk->new_rate); + if (core->notifier_count) { + ret = __clk_notify(core, event, core->rate, core->new_rate); if (ret & NOTIFY_STOP_MASK) - fail_clk = clk; + fail_clk = core; } - hlist_for_each_entry(child, &clk->children, child_node) { + hlist_for_each_entry(child, &core->children, child_node) { /* Skip children who will be reparented to another clock */ - if (child->new_parent && child->new_parent != clk) + if (child->new_parent && child->new_parent != core) continue; tmp_clk = clk_propagate_rate_change(child, event); if (tmp_clk) fail_clk = tmp_clk; } - /* handle the new child who might not be in clk->children yet */ - if (clk->new_child) { - tmp_clk = clk_propagate_rate_change(clk->new_child, event); + /* handle the new child who might not be in core->children yet */ + if (core->new_child) { + tmp_clk = clk_propagate_rate_change(core->new_child, event); if (tmp_clk) fail_clk = tmp_clk; } @@ -1744,7 +1427,7 @@ static struct clk_core *clk_propagate_rate_change(struct clk_core *clk, * walk down a subtree and set the new rates notifying the rate * change on the way */ -static void clk_change_rate(struct clk_core *clk) +static void clk_change_rate(struct clk_core *core) { struct clk_core *child; struct hlist_node *tmp; @@ -1753,77 +1436,80 @@ static void clk_change_rate(struct clk_core *clk) bool skip_set_rate = false; struct clk_core *old_parent; - old_rate = clk->rate; + old_rate = core->rate; - if (clk->new_parent) - best_parent_rate = clk->new_parent->rate; - else if (clk->parent) - best_parent_rate = clk->parent->rate; + if (core->new_parent) + best_parent_rate = core->new_parent->rate; + else if (core->parent) + best_parent_rate = core->parent->rate; - if (clk->new_parent && clk->new_parent != clk->parent) { - old_parent = __clk_set_parent_before(clk, clk->new_parent); - trace_clk_set_parent(clk, clk->new_parent); + if (core->new_parent && core->new_parent != core->parent) { + old_parent = __clk_set_parent_before(core, core->new_parent); + trace_clk_set_parent(core, core->new_parent); - if (clk->ops->set_rate_and_parent) { + if (core->ops->set_rate_and_parent) { skip_set_rate = true; - clk->ops->set_rate_and_parent(clk->hw, clk->new_rate, + core->ops->set_rate_and_parent(core->hw, core->new_rate, best_parent_rate, - clk->new_parent_index); - } else if (clk->ops->set_parent) { - clk->ops->set_parent(clk->hw, clk->new_parent_index); + core->new_parent_index); + } else if (core->ops->set_parent) { + core->ops->set_parent(core->hw, core->new_parent_index); } - trace_clk_set_parent_complete(clk, clk->new_parent); - __clk_set_parent_after(clk, clk->new_parent, old_parent); + trace_clk_set_parent_complete(core, core->new_parent); + __clk_set_parent_after(core, core->new_parent, old_parent); } - trace_clk_set_rate(clk, clk->new_rate); + trace_clk_set_rate(core, core->new_rate); + + if (!skip_set_rate && core->ops->set_rate) + core->ops->set_rate(core->hw, core->new_rate, best_parent_rate); - if (!skip_set_rate && clk->ops->set_rate) - clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); + trace_clk_set_rate_complete(core, core->new_rate); - trace_clk_set_rate_complete(clk, clk->new_rate); + core->rate = clk_recalc(core, best_parent_rate); - clk->rate = clk_recalc(clk, best_parent_rate); + if (core->notifier_count && old_rate != core->rate) + __clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate); - if (clk->notifier_count && old_rate != clk->rate) - __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); + if (core->flags & CLK_RECALC_NEW_RATES) + (void)clk_calc_new_rates(core, core->new_rate); /* * Use safe iteration, as change_rate can actually swap parents * for certain clock types. */ - hlist_for_each_entry_safe(child, tmp, &clk->children, child_node) { + hlist_for_each_entry_safe(child, tmp, &core->children, child_node) { /* Skip children who will be reparented to another clock */ - if (child->new_parent && child->new_parent != clk) + if (child->new_parent && child->new_parent != core) continue; clk_change_rate(child); } - /* handle the new child who might not be in clk->children yet */ - if (clk->new_child) - clk_change_rate(clk->new_child); + /* handle the new child who might not be in core->children yet */ + if (core->new_child) + clk_change_rate(core->new_child); } -static int clk_core_set_rate_nolock(struct clk_core *clk, +static int clk_core_set_rate_nolock(struct clk_core *core, unsigned long req_rate) { struct clk_core *top, *fail_clk; unsigned long rate = req_rate; int ret = 0; - if (!clk) + if (!core) return 0; /* bail early if nothing to do */ - if (rate == clk_core_get_rate_nolock(clk)) + if (rate == clk_core_get_rate_nolock(core)) return 0; - if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) + if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count) return -EBUSY; /* calculate new rates and get the topmost changed clock */ - top = clk_calc_new_rates(clk, rate); + top = clk_calc_new_rates(core, rate); if (!top) return -EINVAL; @@ -1839,7 +1525,7 @@ static int clk_core_set_rate_nolock(struct clk_core *clk, /* change the rates */ clk_change_rate(top); - clk->req_rate = req_rate; + core->req_rate = req_rate; return ret; } @@ -1889,375 +1575,714 @@ EXPORT_SYMBOL_GPL(clk_set_rate); * @min: desired minimum clock rate in Hz, inclusive * @max: desired maximum clock rate in Hz, inclusive * - * Returns success (0) or negative errno. + * Returns success (0) or negative errno. + */ +int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max) +{ + int ret = 0; + + if (!clk) + return 0; + + if (min > max) { + pr_err("%s: clk %s dev %s con %s: invalid range [%lu, %lu]\n", + __func__, clk->core->name, clk->dev_id, clk->con_id, + min, max); + return -EINVAL; + } + + clk_prepare_lock(); + + if (min != clk->min_rate || max != clk->max_rate) { + clk->min_rate = min; + clk->max_rate = max; + ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate); + } + + clk_prepare_unlock(); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate_range); + +/** + * clk_set_min_rate - set a minimum clock rate for a clock source + * @clk: clock source + * @rate: desired minimum clock rate in Hz, inclusive + * + * Returns success (0) or negative errno. + */ +int clk_set_min_rate(struct clk *clk, unsigned long rate) +{ + if (!clk) + return 0; + + return clk_set_rate_range(clk, rate, clk->max_rate); +} +EXPORT_SYMBOL_GPL(clk_set_min_rate); + +/** + * clk_set_max_rate - set a maximum clock rate for a clock source + * @clk: clock source + * @rate: desired maximum clock rate in Hz, inclusive + * + * Returns success (0) or negative errno. + */ +int clk_set_max_rate(struct clk *clk, unsigned long rate) +{ + if (!clk) + return 0; + + return clk_set_rate_range(clk, clk->min_rate, rate); +} +EXPORT_SYMBOL_GPL(clk_set_max_rate); + +/** + * clk_get_parent - return the parent of a clk + * @clk: the clk whose parent gets returned + * + * Simply returns clk->parent. Returns NULL if clk is NULL. + */ +struct clk *clk_get_parent(struct clk *clk) +{ + struct clk *parent; + + if (!clk) + return NULL; + + clk_prepare_lock(); + /* TODO: Create a per-user clk and change callers to call clk_put */ + parent = !clk->core->parent ? NULL : clk->core->parent->hw->clk; + clk_prepare_unlock(); + + return parent; +} +EXPORT_SYMBOL_GPL(clk_get_parent); + +/* + * .get_parent is mandatory for clocks with multiple possible parents. It is + * optional for single-parent clocks. Always call .get_parent if it is + * available and WARN if it is missing for multi-parent clocks. + * + * For single-parent clocks without .get_parent, first check to see if the + * .parents array exists, and if so use it to avoid an expensive tree + * traversal. If .parents does not exist then walk the tree. + */ +static struct clk_core *__clk_init_parent(struct clk_core *core) +{ + struct clk_core *ret = NULL; + u8 index; + + /* handle the trivial cases */ + + if (!core->num_parents) + goto out; + + if (core->num_parents == 1) { + if (IS_ERR_OR_NULL(core->parent)) + core->parent = clk_core_lookup(core->parent_names[0]); + ret = core->parent; + goto out; + } + + if (!core->ops->get_parent) { + WARN(!core->ops->get_parent, + "%s: multi-parent clocks must implement .get_parent\n", + __func__); + goto out; + } + + /* + * Do our best to cache parent clocks in core->parents. This prevents + * unnecessary and expensive lookups. We don't set core->parent here; + * that is done by the calling function. + */ + + index = core->ops->get_parent(core->hw); + + if (!core->parents) + core->parents = + kcalloc(core->num_parents, sizeof(struct clk *), + GFP_KERNEL); + + ret = clk_core_get_parent_by_index(core, index); + +out: + return ret; +} + +static void clk_core_reparent(struct clk_core *core, + struct clk_core *new_parent) +{ + clk_reparent(core, new_parent); + __clk_recalc_accuracies(core); + __clk_recalc_rates(core, POST_RATE_CHANGE); +} + +void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent) +{ + if (!hw) + return; + + clk_core_reparent(hw->core, !new_parent ? NULL : new_parent->core); +} + +/** + * clk_has_parent - check if a clock is a possible parent for another + * @clk: clock source + * @parent: parent clock source + * + * This function can be used in drivers that need to check that a clock can be + * the parent of another without actually changing the parent. + * + * Returns true if @parent is a possible parent for @clk, false otherwise. + */ +bool clk_has_parent(struct clk *clk, struct clk *parent) +{ + struct clk_core *core, *parent_core; + unsigned int i; + + /* NULL clocks should be nops, so return success if either is NULL. */ + if (!clk || !parent) + return true; + + core = clk->core; + parent_core = parent->core; + + /* Optimize for the case where the parent is already the parent. */ + if (core->parent == parent_core) + return true; + + for (i = 0; i < core->num_parents; i++) + if (strcmp(core->parent_names[i], parent_core->name) == 0) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(clk_has_parent); + +static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) +{ + int ret = 0; + int p_index = 0; + unsigned long p_rate = 0; + + if (!core) + return 0; + + /* prevent racing with updates to the clock topology */ + clk_prepare_lock(); + + if (core->parent == parent) + goto out; + + /* verify ops for for multi-parent clks */ + if ((core->num_parents > 1) && (!core->ops->set_parent)) { + ret = -ENOSYS; + goto out; + } + + /* check that we are allowed to re-parent if the clock is in use */ + if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) { + ret = -EBUSY; + goto out; + } + + /* try finding the new parent index */ + if (parent) { + p_index = clk_fetch_parent_index(core, parent); + p_rate = parent->rate; + if (p_index < 0) { + pr_debug("%s: clk %s can not be parent of clk %s\n", + __func__, parent->name, core->name); + ret = p_index; + goto out; + } + } + + /* propagate PRE_RATE_CHANGE notifications */ + ret = __clk_speculate_rates(core, p_rate); + + /* abort if a driver objects */ + if (ret & NOTIFY_STOP_MASK) + goto out; + + /* do the re-parent */ + ret = __clk_set_parent(core, parent, p_index); + + /* propagate rate an accuracy recalculation accordingly */ + if (ret) { + __clk_recalc_rates(core, ABORT_RATE_CHANGE); + } else { + __clk_recalc_rates(core, POST_RATE_CHANGE); + __clk_recalc_accuracies(core); + } + +out: + clk_prepare_unlock(); + + return ret; +} + +/** + * clk_set_parent - switch the parent of a mux clk + * @clk: the mux clk whose input we are switching + * @parent: the new input to clk + * + * Re-parent clk to use parent as its new input source. If clk is in + * prepared state, the clk will get enabled for the duration of this call. If + * that's not acceptable for a specific clk (Eg: the consumer can't handle + * that, the reparenting is glitchy in hardware, etc), use the + * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared. + * + * After successfully changing clk's parent clk_set_parent will update the + * clk topology, sysfs topology and propagate rate recalculation via + * __clk_recalc_rates. + * + * Returns 0 on success, -EERROR otherwise. + */ +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + if (!clk) + return 0; + + return clk_core_set_parent(clk->core, parent ? parent->core : NULL); +} +EXPORT_SYMBOL_GPL(clk_set_parent); + +/** + * clk_set_phase - adjust the phase shift of a clock signal + * @clk: clock signal source + * @degrees: number of degrees the signal is shifted + * + * Shifts the phase of a clock signal by the specified + * degrees. Returns 0 on success, -EERROR otherwise. + * + * This function makes no distinction about the input or reference + * signal that we adjust the clock signal phase against. For example + * phase locked-loop clock signal generators we may shift phase with + * respect to feedback clock signal input, but for other cases the + * clock phase may be shifted with respect to some other, unspecified + * signal. + * + * Additionally the concept of phase shift does not propagate through + * the clock tree hierarchy, which sets it apart from clock rates and + * clock accuracy. A parent clock phase attribute does not have an + * impact on the phase attribute of a child clock. */ -int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max) +int clk_set_phase(struct clk *clk, int degrees) { - int ret = 0; + int ret = -EINVAL; if (!clk) return 0; - if (min > max) { - pr_err("%s: clk %s dev %s con %s: invalid range [%lu, %lu]\n", - __func__, clk->core->name, clk->dev_id, clk->con_id, - min, max); - return -EINVAL; - } + /* sanity check degrees */ + degrees %= 360; + if (degrees < 0) + degrees += 360; clk_prepare_lock(); - if (min != clk->min_rate || max != clk->max_rate) { - clk->min_rate = min; - clk->max_rate = max; - ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate); - } + trace_clk_set_phase(clk->core, degrees); + + if (clk->core->ops->set_phase) + ret = clk->core->ops->set_phase(clk->core->hw, degrees); + + trace_clk_set_phase_complete(clk->core, degrees); + + if (!ret) + clk->core->phase = degrees; clk_prepare_unlock(); return ret; } -EXPORT_SYMBOL_GPL(clk_set_rate_range); +EXPORT_SYMBOL_GPL(clk_set_phase); -/** - * clk_set_min_rate - set a minimum clock rate for a clock source - * @clk: clock source - * @rate: desired minimum clock rate in Hz, inclusive - * - * Returns success (0) or negative errno. - */ -int clk_set_min_rate(struct clk *clk, unsigned long rate) +static int clk_core_get_phase(struct clk_core *core) { - if (!clk) - return 0; + int ret; - return clk_set_rate_range(clk, rate, clk->max_rate); + clk_prepare_lock(); + ret = core->phase; + clk_prepare_unlock(); + + return ret; } -EXPORT_SYMBOL_GPL(clk_set_min_rate); /** - * clk_set_max_rate - set a maximum clock rate for a clock source - * @clk: clock source - * @rate: desired maximum clock rate in Hz, inclusive + * clk_get_phase - return the phase shift of a clock signal + * @clk: clock signal source * - * Returns success (0) or negative errno. + * Returns the phase shift of a clock node in degrees, otherwise returns + * -EERROR. */ -int clk_set_max_rate(struct clk *clk, unsigned long rate) +int clk_get_phase(struct clk *clk) { if (!clk) return 0; - return clk_set_rate_range(clk, clk->min_rate, rate); + return clk_core_get_phase(clk->core); } -EXPORT_SYMBOL_GPL(clk_set_max_rate); +EXPORT_SYMBOL_GPL(clk_get_phase); /** - * clk_get_parent - return the parent of a clk - * @clk: the clk whose parent gets returned + * clk_is_match - check if two clk's point to the same hardware clock + * @p: clk compared against q + * @q: clk compared against p * - * Simply returns clk->parent. Returns NULL if clk is NULL. + * Returns true if the two struct clk pointers both point to the same hardware + * clock node. Put differently, returns true if struct clk *p and struct clk *q + * share the same struct clk_core object. + * + * Returns false otherwise. Note that two NULL clks are treated as matching. */ -struct clk *clk_get_parent(struct clk *clk) +bool clk_is_match(const struct clk *p, const struct clk *q) { - struct clk *parent; + /* trivial case: identical struct clk's or both NULL */ + if (p == q) + return true; - clk_prepare_lock(); - parent = __clk_get_parent(clk); - clk_prepare_unlock(); + /* true if clk->core pointers match. Avoid derefing garbage */ + if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q)) + if (p->core == q->core) + return true; - return parent; + return false; } -EXPORT_SYMBOL_GPL(clk_get_parent); +EXPORT_SYMBOL_GPL(clk_is_match); -/* - * .get_parent is mandatory for clocks with multiple possible parents. It is - * optional for single-parent clocks. Always call .get_parent if it is - * available and WARN if it is missing for multi-parent clocks. - * - * For single-parent clocks without .get_parent, first check to see if the - * .parents array exists, and if so use it to avoid an expensive tree - * traversal. If .parents does not exist then walk the tree. - */ -static struct clk_core *__clk_init_parent(struct clk_core *clk) -{ - struct clk_core *ret = NULL; - u8 index; +/*** debugfs support ***/ - /* handle the trivial cases */ +#ifdef CONFIG_DEBUG_FS +#include - if (!clk->num_parents) - goto out; +static struct dentry *rootdir; +static int inited = 0; +static DEFINE_MUTEX(clk_debug_lock); +static HLIST_HEAD(clk_debug_list); - if (clk->num_parents == 1) { - if (IS_ERR_OR_NULL(clk->parent)) - clk->parent = clk_core_lookup(clk->parent_names[0]); - ret = clk->parent; - goto out; - } +static struct hlist_head *all_lists[] = { + &clk_root_list, + &clk_orphan_list, + NULL, +}; - if (!clk->ops->get_parent) { - WARN(!clk->ops->get_parent, - "%s: multi-parent clocks must implement .get_parent\n", - __func__); - goto out; - }; +static struct hlist_head *orphan_list[] = { + &clk_orphan_list, + NULL, +}; - /* - * Do our best to cache parent clocks in clk->parents. This prevents - * unnecessary and expensive lookups. We don't set clk->parent here; - * that is done by the calling function. - */ +static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, + int level) +{ + if (!c) + return; - index = clk->ops->get_parent(clk->hw); + 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)); +} - if (!clk->parents) - clk->parents = - kcalloc(clk->num_parents, sizeof(struct clk *), - GFP_KERNEL); +static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, + int level) +{ + struct clk_core *child; - ret = clk_core_get_parent_by_index(clk, index); + if (!c) + return; -out: - return ret; -} + clk_summary_show_one(s, c, level); -static void clk_core_reparent(struct clk_core *clk, - struct clk_core *new_parent) -{ - clk_reparent(clk, new_parent); - __clk_recalc_accuracies(clk); - __clk_recalc_rates(clk, POST_RATE_CHANGE); + hlist_for_each_entry(child, &c->children, child_node) + clk_summary_show_subtree(s, child, level + 1); } -/** - * clk_has_parent - check if a clock is a possible parent for another - * @clk: clock source - * @parent: parent clock source - * - * This function can be used in drivers that need to check that a clock can be - * the parent of another without actually changing the parent. - * - * Returns true if @parent is a possible parent for @clk, false otherwise. - */ -bool clk_has_parent(struct clk *clk, struct clk *parent) +static int clk_summary_show(struct seq_file *s, void *data) { - struct clk_core *core, *parent_core; - unsigned int i; + struct clk_core *c; + struct hlist_head **lists = (struct hlist_head **)s->private; - /* NULL clocks should be nops, so return success if either is NULL. */ - if (!clk || !parent) - return true; + seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n"); + seq_puts(s, "----------------------------------------------------------------------------------------\n"); - core = clk->core; - parent_core = parent->core; + clk_prepare_lock(); - /* Optimize for the case where the parent is already the parent. */ - if (core->parent == parent_core) - return true; + for (; *lists; lists++) + hlist_for_each_entry(c, *lists, child_node) + clk_summary_show_subtree(s, c, 0); - for (i = 0; i < core->num_parents; i++) - if (strcmp(core->parent_names[i], parent_core->name) == 0) - return true; + clk_prepare_unlock(); - return false; + return 0; } -EXPORT_SYMBOL_GPL(clk_has_parent); -static int clk_core_set_parent(struct clk_core *clk, struct clk_core *parent) + +static int clk_summary_open(struct inode *inode, struct file *file) { - int ret = 0; - int p_index = 0; - unsigned long p_rate = 0; + return single_open(file, clk_summary_show, inode->i_private); +} - if (!clk) - return 0; +static const struct file_operations clk_summary_fops = { + .open = clk_summary_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; - /* prevent racing with updates to the clock topology */ - clk_prepare_lock(); +static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) +{ + if (!c) + return; - if (clk->parent == parent) - goto out; + /* This should be JSON format, i.e. elements separated with a comma */ + 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)); +} - /* verify ops for for multi-parent clks */ - if ((clk->num_parents > 1) && (!clk->ops->set_parent)) { - ret = -ENOSYS; - goto out; - } +static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level) +{ + struct clk_core *child; - /* check that we are allowed to re-parent if the clock is in use */ - if ((clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) { - ret = -EBUSY; - goto out; - } + if (!c) + return; - /* try finding the new parent index */ - if (parent) { - p_index = clk_fetch_parent_index(clk, parent); - p_rate = parent->rate; - if (p_index < 0) { - pr_debug("%s: clk %s can not be parent of clk %s\n", - __func__, parent->name, clk->name); - ret = p_index; - goto out; - } + 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); } - /* propagate PRE_RATE_CHANGE notifications */ - ret = __clk_speculate_rates(clk, p_rate); + 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; - /* abort if a driver objects */ - if (ret & NOTIFY_STOP_MASK) - goto out; + seq_printf(s, "{"); - /* do the re-parent */ - ret = __clk_set_parent(clk, parent, p_index); + clk_prepare_lock(); - /* propagate rate an accuracy recalculation accordingly */ - if (ret) { - __clk_recalc_rates(clk, ABORT_RATE_CHANGE); - } else { - __clk_recalc_rates(clk, POST_RATE_CHANGE); - __clk_recalc_accuracies(clk); + 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); + } } -out: clk_prepare_unlock(); - return ret; + seq_puts(s, "}\n"); + return 0; } -/** - * clk_set_parent - switch the parent of a mux clk - * @clk: the mux clk whose input we are switching - * @parent: the new input to clk - * - * Re-parent clk to use parent as its new input source. If clk is in - * prepared state, the clk will get enabled for the duration of this call. If - * that's not acceptable for a specific clk (Eg: the consumer can't handle - * that, the reparenting is glitchy in hardware, etc), use the - * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared. - * - * After successfully changing clk's parent clk_set_parent will update the - * clk topology, sysfs topology and propagate rate recalculation via - * __clk_recalc_rates. - * - * Returns 0 on success, -EERROR otherwise. - */ -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - if (!clk) - return 0; - return clk_core_set_parent(clk->core, parent ? parent->core : NULL); +static int clk_dump_open(struct inode *inode, struct file *file) +{ + return single_open(file, clk_dump, inode->i_private); } -EXPORT_SYMBOL_GPL(clk_set_parent); -/** - * clk_set_phase - adjust the phase shift of a clock signal - * @clk: clock signal source - * @degrees: number of degrees the signal is shifted - * - * Shifts the phase of a clock signal by the specified - * degrees. Returns 0 on success, -EERROR otherwise. - * - * This function makes no distinction about the input or reference - * signal that we adjust the clock signal phase against. For example - * phase locked-loop clock signal generators we may shift phase with - * respect to feedback clock signal input, but for other cases the - * clock phase may be shifted with respect to some other, unspecified - * signal. - * - * Additionally the concept of phase shift does not propagate through - * the clock tree hierarchy, which sets it apart from clock rates and - * clock accuracy. A parent clock phase attribute does not have an - * impact on the phase attribute of a child clock. - */ -int clk_set_phase(struct clk *clk, int degrees) +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) { - int ret = -EINVAL; + struct dentry *d; + int ret = -ENOMEM; - if (!clk) - return 0; + if (!core || !pdentry) { + ret = -EINVAL; + goto out; + } - /* sanity check degrees */ - degrees %= 360; - if (degrees < 0) - degrees += 360; + d = debugfs_create_dir(core->name, pdentry); + if (!d) + goto out; - clk_prepare_lock(); + core->dentry = d; - trace_clk_set_phase(clk->core, degrees); + d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry, + (u32 *)&core->rate); + if (!d) + goto err_out; - if (clk->core->ops->set_phase) - ret = clk->core->ops->set_phase(clk->core->hw, degrees); + d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry, + (u32 *)&core->accuracy); + if (!d) + goto err_out; - trace_clk_set_phase_complete(clk->core, degrees); + d = debugfs_create_u32("clk_phase", S_IRUGO, core->dentry, + (u32 *)&core->phase); + if (!d) + goto err_out; - if (!ret) - clk->core->phase = degrees; + d = debugfs_create_x32("clk_flags", S_IRUGO, core->dentry, + (u32 *)&core->flags); + if (!d) + goto err_out; - clk_prepare_unlock(); + 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; } -EXPORT_SYMBOL_GPL(clk_set_phase); -static int clk_core_get_phase(struct clk_core *clk) +/** + * clk_debug_register - add a clk node to the debugfs clk directory + * @core: the clk being added to the debugfs clk directory + * + * Dynamically adds a clk to the debugfs clk directory if debugfs has been + * initialized. Otherwise it bails out early since the debugfs clk directory + * 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; - if (!clk) - goto out; + mutex_lock(&clk_debug_lock); + hlist_add_head(&core->debug_node, &clk_debug_list); - clk_prepare_lock(); - ret = clk->phase; - clk_prepare_unlock(); + if (!inited) + goto unlock; + + ret = clk_debug_create_one(core, rootdir); +unlock: + mutex_unlock(&clk_debug_lock); -out: return ret; } -EXPORT_SYMBOL_GPL(clk_get_phase); -/** - * clk_get_phase - return the phase shift of a clock signal - * @clk: clock signal source + /** + * clk_debug_unregister - remove a clk node from the debugfs clk directory + * @core: the clk being removed from the debugfs clk directory * - * Returns the phase shift of a clock node in degrees, otherwise returns - * -EERROR. + * Dynamically removes a clk and all its child nodes from the + * debugfs clk directory if clk->dentry points to debugfs created by + * clk_debug_register in __clk_init. */ -int clk_get_phase(struct clk *clk) +static void clk_debug_unregister(struct clk_core *core) { - if (!clk) - return 0; + mutex_lock(&clk_debug_lock); + hlist_del_init(&core->debug_node); + debugfs_remove_recursive(core->dentry); + core->dentry = NULL; + mutex_unlock(&clk_debug_lock); +} - return clk_core_get_phase(clk->core); +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_is_match - check if two clk's point to the same hardware clock - * @p: clk compared against q - * @q: clk compared against p - * - * Returns true if the two struct clk pointers both point to the same hardware - * clock node. Put differently, returns true if struct clk *p and struct clk *q - * share the same struct clk_core object. + * clk_debug_init - lazily populate the debugfs clk directory * - * Returns false otherwise. Note that two NULL clks are treated as matching. + * clks are often initialized very early during boot before memory can be + * dynamically allocated and well before debugfs is setup. This function + * populates the debugfs clk directory once at boot-time when we know that + * debugfs is setup. It should only be called once at boot-time, all other clks + * added dynamically will be done so with clk_debug_register. */ -bool clk_is_match(const struct clk *p, const struct clk *q) +static int __init clk_debug_init(void) { - /* trivial case: identical struct clk's or both NULL */ - if (p == q) - return true; + struct clk_core *core; + struct dentry *d; - /* true if clk->core pointers match. Avoid derefing garbage */ - if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q)) - if (p->core == q->core) - return true; + rootdir = debugfs_create_dir("clk", NULL); - return false; + 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; } -EXPORT_SYMBOL_GPL(clk_is_match); +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 @@ -2272,67 +2297,67 @@ static int __clk_init(struct device *dev, struct clk *clk_user) int i, ret = 0; struct clk_core *orphan; struct hlist_node *tmp2; - struct clk_core *clk; + struct clk_core *core; unsigned long rate; if (!clk_user) return -EINVAL; - clk = clk_user->core; + core = clk_user->core; clk_prepare_lock(); /* check to see if a clock with this name is already registered */ - if (clk_core_lookup(clk->name)) { + if (clk_core_lookup(core->name)) { pr_debug("%s: clk %s already initialized\n", - __func__, clk->name); + __func__, core->name); ret = -EEXIST; goto out; } /* check that clk_ops are sane. See Documentation/clk.txt */ - if (clk->ops->set_rate && - !((clk->ops->round_rate || clk->ops->determine_rate) && - clk->ops->recalc_rate)) { + if (core->ops->set_rate && + !((core->ops->round_rate || core->ops->determine_rate) && + core->ops->recalc_rate)) { pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", - __func__, clk->name); + __func__, core->name); ret = -EINVAL; goto out; } - if (clk->ops->set_parent && !clk->ops->get_parent) { + if (core->ops->set_parent && !core->ops->get_parent) { pr_warning("%s: %s must implement .get_parent & .set_parent\n", - __func__, clk->name); + __func__, core->name); ret = -EINVAL; goto out; } - if (clk->ops->set_rate_and_parent && - !(clk->ops->set_parent && clk->ops->set_rate)) { + if (core->ops->set_rate_and_parent && + !(core->ops->set_parent && core->ops->set_rate)) { pr_warn("%s: %s must implement .set_parent & .set_rate\n", - __func__, clk->name); + __func__, core->name); ret = -EINVAL; goto out; } /* throw a WARN if any entries in parent_names are NULL */ - for (i = 0; i < clk->num_parents; i++) - WARN(!clk->parent_names[i], + for (i = 0; i < core->num_parents; i++) + WARN(!core->parent_names[i], "%s: invalid NULL in %s's .parent_names\n", - __func__, clk->name); + __func__, core->name); /* * Allocate an array of struct clk *'s to avoid unnecessary string * look-ups of clk's possible parents. This can fail for clocks passed - * in to clk_init during early boot; thus any access to clk->parents[] + * in to clk_init during early boot; thus any access to core->parents[] * must always check for a NULL pointer and try to populate it if * necessary. * - * If clk->parents is not NULL we skip this entire block. This allows - * for clock drivers to statically initialize clk->parents. + * If core->parents is not NULL we skip this entire block. This allows + * for clock drivers to statically initialize core->parents. */ - if (clk->num_parents > 1 && !clk->parents) { - clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *), + if (core->num_parents > 1 && !core->parents) { + core->parents = kcalloc(core->num_parents, sizeof(struct clk *), GFP_KERNEL); /* * clk_core_lookup returns NULL for parents that have not been @@ -2340,16 +2365,16 @@ static int __clk_init(struct device *dev, struct clk *clk_user) * for a NULL pointer. We can always perform lazy lookups for * missing parents later on. */ - if (clk->parents) - for (i = 0; i < clk->num_parents; i++) - clk->parents[i] = - clk_core_lookup(clk->parent_names[i]); + if (core->parents) + for (i = 0; i < core->num_parents; i++) + core->parents[i] = + clk_core_lookup(core->parent_names[i]); } - clk->parent = __clk_init_parent(clk); + core->parent = __clk_init_parent(core); /* - * Populate clk->parent if parent has already been __clk_init'd. If + * Populate core->parent if parent has already been __clk_init'd. If * parent has not yet been __clk_init'd then place clk in the orphan * list. If clk has set the CLK_IS_ROOT flag then place it in the root * clk list. @@ -2358,13 +2383,17 @@ static int __clk_init(struct device *dev, struct clk *clk_user) * clocks and re-parent any that are children of the clock currently * being clk_init'd. */ - if (clk->parent) - hlist_add_head(&clk->child_node, - &clk->parent->children); - else if (clk->flags & CLK_IS_ROOT) - hlist_add_head(&clk->child_node, &clk_root_list); - else - hlist_add_head(&clk->child_node, &clk_orphan_list); + if (core->parent) { + hlist_add_head(&core->child_node, + &core->parent->children); + core->orphan = core->parent->orphan; + } else if (core->flags & CLK_IS_ROOT) { + hlist_add_head(&core->child_node, &clk_root_list); + core->orphan = false; + } else { + hlist_add_head(&core->child_node, &clk_orphan_list); + core->orphan = true; + } /* * Set clk's accuracy. The preferred method is to use @@ -2373,23 +2402,23 @@ static int __clk_init(struct device *dev, struct clk *clk_user) * parent (or is orphaned) then accuracy is set to zero (perfect * clock). */ - if (clk->ops->recalc_accuracy) - clk->accuracy = clk->ops->recalc_accuracy(clk->hw, - __clk_get_accuracy(clk->parent)); - else if (clk->parent) - clk->accuracy = clk->parent->accuracy; + if (core->ops->recalc_accuracy) + core->accuracy = core->ops->recalc_accuracy(core->hw, + __clk_get_accuracy(core->parent)); + else if (core->parent) + core->accuracy = core->parent->accuracy; else - clk->accuracy = 0; + core->accuracy = 0; /* * Set clk's phase. * Since a phase is by definition relative to its parent, just * query the current clock phase, or just assume it's in phase. */ - if (clk->ops->get_phase) - clk->phase = clk->ops->get_phase(clk->hw); + if (core->ops->get_phase) + core->phase = core->ops->get_phase(core->hw); else - clk->phase = 0; + core->phase = 0; /* * Set clk's rate. The preferred method is to use .recalc_rate. For @@ -2397,14 +2426,14 @@ static int __clk_init(struct device *dev, struct clk *clk_user) * parent's rate. If a clock doesn't have a parent (or is orphaned) * then rate is set to zero. */ - if (clk->ops->recalc_rate) - rate = clk->ops->recalc_rate(clk->hw, - clk_core_get_rate_nolock(clk->parent)); - else if (clk->parent) - rate = clk->parent->rate; + if (core->ops->recalc_rate) + rate = core->ops->recalc_rate(core->hw, + clk_core_get_rate_nolock(core->parent)); + else if (core->parent) + rate = core->parent->rate; else rate = 0; - clk->rate = clk->req_rate = rate; + core->rate = core->req_rate = rate; /* * walk the list of orphan clocks and reparent any that are children of @@ -2413,14 +2442,15 @@ static int __clk_init(struct device *dev, struct clk *clk_user) hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { if (orphan->num_parents && orphan->ops->get_parent) { i = orphan->ops->get_parent(orphan->hw); - if (!strcmp(clk->name, orphan->parent_names[i])) - clk_core_reparent(orphan, clk); + if (i >= 0 && i < orphan->num_parents && + !strcmp(core->name, orphan->parent_names[i])) + clk_core_reparent(orphan, core); continue; } for (i = 0; i < orphan->num_parents; i++) - if (!strcmp(clk->name, orphan->parent_names[i])) { - clk_core_reparent(orphan, clk); + if (!strcmp(core->name, orphan->parent_names[i])) { + clk_core_reparent(orphan, core); break; } } @@ -2433,15 +2463,15 @@ static int __clk_init(struct device *dev, struct clk *clk_user) * Please consider other ways of solving initialization problems before * using this callback, as its use is discouraged. */ - if (clk->ops->init) - clk->ops->init(clk->hw); + if (core->ops->init) + core->ops->init(core->hw); - kref_init(&clk->ref); + kref_init(&core->ref); out: clk_prepare_unlock(); if (!ret) - clk_debug_register(clk); + clk_debug_register(core); return ret; } @@ -2487,63 +2517,60 @@ void __clk_free_clk(struct clk *clk) * * clk_register is the primary interface for populating the clock tree with new * clock nodes. It returns a pointer to the newly allocated struct clk which - * cannot be dereferenced by driver code but may be used in conjuction with the + * cannot be dereferenced by driver code but may be used in conjunction with the * rest of the clock API. In the event of an error clk_register will return an * error code; drivers must test for an error code after calling clk_register. */ struct clk *clk_register(struct device *dev, struct clk_hw *hw) { int i, ret; - struct clk_core *clk; + struct clk_core *core; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); - if (!clk) { - pr_err("%s: could not allocate clk\n", __func__); + core = kzalloc(sizeof(*core), GFP_KERNEL); + if (!core) { ret = -ENOMEM; goto fail_out; } - clk->name = kstrdup_const(hw->init->name, GFP_KERNEL); - if (!clk->name) { - pr_err("%s: could not allocate clk->name\n", __func__); + core->name = kstrdup_const(hw->init->name, GFP_KERNEL); + if (!core->name) { ret = -ENOMEM; goto fail_name; } - clk->ops = hw->init->ops; + core->ops = hw->init->ops; if (dev && dev->driver) - clk->owner = dev->driver->owner; - clk->hw = hw; - clk->flags = hw->init->flags; - clk->num_parents = hw->init->num_parents; - hw->core = clk; + core->owner = dev->driver->owner; + core->hw = hw; + core->flags = hw->init->flags; + core->num_parents = hw->init->num_parents; + core->min_rate = 0; + core->max_rate = ULONG_MAX; + hw->core = core; /* allocate local copy in case parent_names is __initdata */ - clk->parent_names = kcalloc(clk->num_parents, sizeof(char *), + core->parent_names = kcalloc(core->num_parents, sizeof(char *), GFP_KERNEL); - if (!clk->parent_names) { - pr_err("%s: could not allocate clk->parent_names\n", __func__); + if (!core->parent_names) { ret = -ENOMEM; goto fail_parent_names; } /* copy each string name in case parent_names is __initdata */ - for (i = 0; i < clk->num_parents; i++) { - clk->parent_names[i] = kstrdup_const(hw->init->parent_names[i], + for (i = 0; i < core->num_parents; i++) { + core->parent_names[i] = kstrdup_const(hw->init->parent_names[i], GFP_KERNEL); - if (!clk->parent_names[i]) { - pr_err("%s: could not copy parent_names\n", __func__); + if (!core->parent_names[i]) { ret = -ENOMEM; goto fail_parent_names_copy; } } - INIT_HLIST_HEAD(&clk->clks); + INIT_HLIST_HEAD(&core->clks); hw->clk = __clk_create_clk(hw, NULL, NULL); if (IS_ERR(hw->clk)) { - pr_err("%s: could not allocate per-user clk\n", __func__); ret = PTR_ERR(hw->clk); goto fail_parent_names_copy; } @@ -2557,35 +2584,32 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) fail_parent_names_copy: while (--i >= 0) - kfree_const(clk->parent_names[i]); - kfree(clk->parent_names); + kfree_const(core->parent_names[i]); + kfree(core->parent_names); fail_parent_names: - kfree_const(clk->name); + kfree_const(core->name); fail_name: - kfree(clk); + kfree(core); fail_out: return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(clk_register); -/* - * Free memory allocated for a clock. - * Caller must hold prepare_lock. - */ +/* Free memory allocated for a clock. */ static void __clk_release(struct kref *ref) { - struct clk_core *clk = container_of(ref, struct clk_core, ref); - int i = clk->num_parents; + struct clk_core *core = container_of(ref, struct clk_core, ref); + int i = core->num_parents; lockdep_assert_held(&prepare_lock); - kfree(clk->parents); + kfree(core->parents); while (--i >= 0) - kfree_const(clk->parent_names[i]); + kfree_const(core->parent_names[i]); - kfree(clk->parent_names); - kfree_const(clk->name); - kfree(clk); + kfree(core->parent_names); + kfree_const(core->name); + kfree(core); } /* @@ -2913,7 +2937,7 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) unsigned int idx = clkspec->args[0]; if (idx >= clk_data->clk_num) { - pr_err("%s: invalid clock index %d\n", __func__, idx); + pr_err("%s: invalid clock index %u\n", __func__, idx); return ERR_PTR(-EINVAL); } @@ -3036,6 +3060,7 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) u32 pv; int rc; int count; + struct clk *clk; if (index < 0) return NULL; @@ -3061,22 +3086,58 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) if (of_property_read_string_index(clkspec.np, "clock-output-names", index, - &clk_name) < 0) - clk_name = clkspec.np->name; + &clk_name) < 0) { + /* + * Best effort to get the name if the clock has been + * registered with the framework. If the clock isn't + * registered, we return the node name as the name of + * the clock as long as #clock-cells = 0. + */ + clk = of_clk_get_from_provider(&clkspec); + if (IS_ERR(clk)) { + if (clkspec.args_count == 0) + clk_name = clkspec.np->name; + else + clk_name = NULL; + } else { + clk_name = __clk_get_name(clk); + clk_put(clk); + } + } + of_node_put(clkspec.np); return clk_name; } EXPORT_SYMBOL_GPL(of_clk_get_parent_name); +/** + * of_clk_parent_fill() - Fill @parents with names of @np's parents and return + * number of parents + * @np: Device node pointer associated with clock provider + * @parents: pointer to char array that hold the parents' names + * @size: size of the @parents array + * + * Return: number of parents for the clock node. + */ +int of_clk_parent_fill(struct device_node *np, const char **parents, + unsigned int size) +{ + unsigned int i = 0; + + while (i < size && (parents[i] = of_clk_get_parent_name(np, i)) != NULL) + i++; + + return i; +} +EXPORT_SYMBOL_GPL(of_clk_parent_fill); + struct clock_provider { of_clk_init_cb_t clk_init_cb; struct device_node *np; struct list_head node; }; -static LIST_HEAD(clk_provider_list); - /* * This function looks for a parent clock. If there is one, then it * checks that the provider for this parent clock was initialized, in @@ -3127,17 +3188,29 @@ void __init of_clk_init(const struct of_device_id *matches) struct clock_provider *clk_provider, *next; bool is_init_done; bool force = false; + LIST_HEAD(clk_provider_list); if (!matches) matches = &__clk_of_table; /* First prepare the list of the clocks providers */ for_each_matching_node_and_match(np, matches, &match) { - struct clock_provider *parent = - kzalloc(sizeof(struct clock_provider), GFP_KERNEL); + struct clock_provider *parent; + + parent = kzalloc(sizeof(*parent), GFP_KERNEL); + if (!parent) { + list_for_each_entry_safe(clk_provider, next, + &clk_provider_list, node) { + list_del(&clk_provider->node); + of_node_put(clk_provider->np); + kfree(clk_provider); + } + of_node_put(np); + return; + } parent->clk_init_cb = match->data; - parent->np = np; + parent->np = of_node_get(np); list_add_tail(&parent->node, &clk_provider_list); } @@ -3151,6 +3224,7 @@ void __init of_clk_init(const struct of_device_id *matches) of_clk_set_defaults(clk_provider->np, true); list_del(&clk_provider->node); + of_node_put(clk_provider->np); kfree(clk_provider); is_init_done = true; }