From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- ...-clk-Add-__clk_mux_determine_rate_closest.patch | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch (limited to 'target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch') 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 +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 +Tested-by: Kenneth Westfield +Signed-off-by: Michael Turquette +--- + 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 -- cgit v1.2.3