aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2015-01-19 21:05:28 -0500
committerMichael Turquette <mturquette@linaro.org>2015-01-27 14:48:39 -0500
commit15a02c1f6dd7c2bb150c61d00ffb33f584ff2288 (patch)
tree803aecc489bac86074b95d25cbdb2bbc426ffb38 /drivers/clk/clk.c
parent52bba9809a954d72bc77773bd560b9724b495eb7 (diff)
clk: Add __clk_mux_determine_rate_closest
Some clock drivers want to find the closest rate on the input of a mux instead of a rate that's less than or equal to the desired rate. Add a generic mux function to support this. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Tested-by: Kenneth Westfield <kwestfie@codeaurora.org> Signed-off-by: Michael Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 30fff56e1f15..9fc209abcb48 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -690,14 +690,20 @@ struct clk *__clk_lookup(const char *name)
690 return NULL; 690 return NULL;
691} 691}
692 692
693/* 693static bool mux_is_better_rate(unsigned long rate, unsigned long now,
694 * Helper for finding best parent to provide a given frequency. This can be used 694 unsigned long best, unsigned long flags)
695 * directly as a determine_rate callback (e.g. for a mux), or from a more 695{
696 * complex clock that may combine a mux with other operations. 696 if (flags & CLK_MUX_ROUND_CLOSEST)
697 */ 697 return abs(now - rate) < abs(best - rate);
698long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, 698
699 unsigned long *best_parent_rate, 699 return now <= rate && now > best;
700 struct clk_hw **best_parent_p) 700}
701
702static long
703clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate,
704 unsigned long *best_parent_rate,
705 struct clk_hw **best_parent_p,
706 unsigned long flags)
701{ 707{
702 struct clk *clk = hw->clk, *parent, *best_parent = NULL; 708 struct clk *clk = hw->clk, *parent, *best_parent = NULL;
703 int i, num_parents; 709 int i, num_parents;
@@ -725,7 +731,7 @@ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
725 parent_rate = __clk_round_rate(parent, rate); 731 parent_rate = __clk_round_rate(parent, rate);
726 else 732 else
727 parent_rate = __clk_get_rate(parent); 733 parent_rate = __clk_get_rate(parent);
728 if (parent_rate <= rate && parent_rate > best) { 734 if (mux_is_better_rate(rate, parent_rate, best, flags)) {
729 best_parent = parent; 735 best_parent = parent;
730 best = parent_rate; 736 best = parent_rate;
731 } 737 }
@@ -738,8 +744,31 @@ out:
738 744
739 return best; 745 return best;
740} 746}
747
748/*
749 * Helper for finding best parent to provide a given frequency. This can be used
750 * directly as a determine_rate callback (e.g. for a mux), or from a more
751 * complex clock that may combine a mux with other operations.
752 */
753long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
754 unsigned long *best_parent_rate,
755 struct clk_hw **best_parent_p)
756{
757 return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
758 best_parent_p, 0);
759}
741EXPORT_SYMBOL_GPL(__clk_mux_determine_rate); 760EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
742 761
762long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
763 unsigned long *best_parent_rate,
764 struct clk_hw **best_parent_p)
765{
766 return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
767 best_parent_p,
768 CLK_MUX_ROUND_CLOSEST);
769}
770EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
771
743/*** clk api ***/ 772/*** clk api ***/
744 773
745void __clk_unprepare(struct clk *clk) 774void __clk_unprepare(struct clk *clk)