aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch')
-rw-r--r--target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch120
1 files changed, 120 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch b/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch
new file mode 100644
index 0000000..18972f3
--- /dev/null
+++ b/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch
@@ -0,0 +1,120 @@
+From 15a02c1f6dd7c2bb150c61d00ffb33f584ff2288 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Mon, 19 Jan 2015 18:05:28 -0800
+Subject: [PATCH] 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>
+---
+ drivers/clk/clk.c | 47 +++++++++++++++++++++++++++++++++++---------
+ include/linux/clk-provider.h | 8 +++++++-
+ 2 files changed, 45 insertions(+), 10 deletions(-)
+
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -695,14 +695,20 @@ struct clk *__clk_lookup(const char *nam
+ return NULL;
+ }
+
+-/*
+- * 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.
+- */
+-long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
+- unsigned long *best_parent_rate,
+- struct clk **best_parent_p)
++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;
++}
++
++static long
++clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate,
++ unsigned long *best_parent_rate,
++ struct clk **best_parent_p,
++ unsigned long flags)
+ {
+ struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+ int i, num_parents;
+@@ -730,7 +736,7 @@ long __clk_mux_determine_rate(struct clk
+ parent_rate = __clk_round_rate(parent, rate);
+ else
+ parent_rate = __clk_get_rate(parent);
+- if (parent_rate <= rate && parent_rate > best) {
++ if (mux_is_better_rate(rate, parent_rate, best, flags)) {
+ best_parent = parent;
+ best = parent_rate;
+ }
+@@ -743,8 +749,31 @@ out:
+
+ return best;
+ }
++
++/*
++ * 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.
++ */
++long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long *best_parent_rate,
++ struct clk **best_parent_p)
++{
++ return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
++ best_parent_p, 0);
++}
+ EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
+
++long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
++ unsigned long *best_parent_rate,
++ struct clk **best_parent_p)
++{
++ return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
++ best_parent_p,
++ CLK_MUX_ROUND_CLOSEST);
++}
++EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
++
+ /*** clk api ***/
+
+ void __clk_unprepare(struct clk *clk)
+--- a/include/linux/clk-provider.h
++++ b/include/linux/clk-provider.h
+@@ -382,6 +382,8 @@ struct clk *clk_register_divider_table(s
+ * register, and mask of mux bits are in higher 16-bit of this register.
+ * While setting the mux bits, higher 16-bit should also be updated to
+ * indicate changing mux bits.
++ * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired
++ * frequency.
+ */
+ struct clk_mux {
+ struct clk_hw hw;
+@@ -396,7 +398,8 @@ struct clk_mux {
+ #define CLK_MUX_INDEX_ONE BIT(0)
+ #define CLK_MUX_INDEX_BIT BIT(1)
+ #define CLK_MUX_HIWORD_MASK BIT(2)
+-#define CLK_MUX_READ_ONLY BIT(3) /* mux setting cannot be changed */
++#define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */
++#define CLK_MUX_ROUND_CLOSEST BIT(4)
+
+ extern const struct clk_ops clk_mux_ops;
+ extern const struct clk_ops clk_mux_ro_ops;
+@@ -554,6 +557,9 @@ struct clk *__clk_lookup(const char *nam
+ long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *best_parent_rate,
+ struct clk **best_parent_p);
++long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
++ unsigned long *best_parent_rate,
++ struct clk **best_parent_p);
+
+ /*
+ * FIXME clock api without lock protection