add chaos_calmer branch
[15.05/openwrt.git] / target / linux / ipq806x / patches-3.18 / 131-clk-Add-__clk_mux_determine_rate_closest.patch
1 From 15a02c1f6dd7c2bb150c61d00ffb33f584ff2288 Mon Sep 17 00:00:00 2001
2 From: Stephen Boyd <sboyd@codeaurora.org>
3 Date: Mon, 19 Jan 2015 18:05:28 -0800
4 Subject: [PATCH] clk: Add __clk_mux_determine_rate_closest
5
6 Some clock drivers want to find the closest rate on the input of
7 a mux instead of a rate that's less than or equal to the desired
8 rate. Add a generic mux function to support this.
9
10 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
11 Tested-by: Kenneth Westfield <kwestfie@codeaurora.org>
12 Signed-off-by: Michael Turquette <mturquette@linaro.org>
13 ---
14  drivers/clk/clk.c            | 47 +++++++++++++++++++++++++++++++++++---------
15  include/linux/clk-provider.h |  8 +++++++-
16  2 files changed, 45 insertions(+), 10 deletions(-)
17
18 --- a/drivers/clk/clk.c
19 +++ b/drivers/clk/clk.c
20 @@ -695,14 +695,20 @@ struct clk *__clk_lookup(const char *nam
21         return NULL;
22  }
23  
24 -/*
25 - * Helper for finding best parent to provide a given frequency. This can be used
26 - * directly as a determine_rate callback (e.g. for a mux), or from a more
27 - * complex clock that may combine a mux with other operations.
28 - */
29 -long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
30 -                             unsigned long *best_parent_rate,
31 -                             struct clk **best_parent_p)
32 +static bool mux_is_better_rate(unsigned long rate, unsigned long now,
33 +                          unsigned long best, unsigned long flags)
34 +{
35 +       if (flags & CLK_MUX_ROUND_CLOSEST)
36 +               return abs(now - rate) < abs(best - rate);
37 +
38 +       return now <= rate && now > best;
39 +}
40 +
41 +static long
42 +clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate,
43 +                            unsigned long *best_parent_rate,
44 +                            struct clk **best_parent_p,
45 +                            unsigned long flags)
46  {
47         struct clk *clk = hw->clk, *parent, *best_parent = NULL;
48         int i, num_parents;
49 @@ -730,7 +736,7 @@ long __clk_mux_determine_rate(struct clk
50                         parent_rate = __clk_round_rate(parent, rate);
51                 else
52                         parent_rate = __clk_get_rate(parent);
53 -               if (parent_rate <= rate && parent_rate > best) {
54 +               if (mux_is_better_rate(rate, parent_rate, best, flags)) {
55                         best_parent = parent;
56                         best = parent_rate;
57                 }
58 @@ -743,8 +749,31 @@ out:
59  
60         return best;
61  }
62 +
63 +/*
64 + * Helper for finding best parent to provide a given frequency. This can be used
65 + * directly as a determine_rate callback (e.g. for a mux), or from a more
66 + * complex clock that may combine a mux with other operations.
67 + */
68 +long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
69 +                             unsigned long *best_parent_rate,
70 +                             struct clk **best_parent_p)
71 +{
72 +       return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
73 +                                           best_parent_p, 0);
74 +}
75  EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
76  
77 +long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
78 +                             unsigned long *best_parent_rate,
79 +                             struct clk **best_parent_p)
80 +{
81 +       return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
82 +                                           best_parent_p,
83 +                                           CLK_MUX_ROUND_CLOSEST);
84 +}
85 +EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
86 +
87  /***        clk api        ***/
88  
89  void __clk_unprepare(struct clk *clk)
90 --- a/include/linux/clk-provider.h
91 +++ b/include/linux/clk-provider.h
92 @@ -382,6 +382,8 @@ struct clk *clk_register_divider_table(s
93   *     register, and mask of mux bits are in higher 16-bit of this register.
94   *     While setting the mux bits, higher 16-bit should also be updated to
95   *     indicate changing mux bits.
96 + * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired
97 + *     frequency.
98   */
99  struct clk_mux {
100         struct clk_hw   hw;
101 @@ -396,7 +398,8 @@ struct clk_mux {
102  #define CLK_MUX_INDEX_ONE              BIT(0)
103  #define CLK_MUX_INDEX_BIT              BIT(1)
104  #define CLK_MUX_HIWORD_MASK            BIT(2)
105 -#define CLK_MUX_READ_ONLY      BIT(3) /* mux setting cannot be changed */
106 +#define CLK_MUX_READ_ONLY              BIT(3) /* mux can't be changed */
107 +#define CLK_MUX_ROUND_CLOSEST          BIT(4)
108  
109  extern const struct clk_ops clk_mux_ops;
110  extern const struct clk_ops clk_mux_ro_ops;
111 @@ -554,6 +557,9 @@ struct clk *__clk_lookup(const char *nam
112  long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
113                               unsigned long *best_parent_rate,
114                               struct clk **best_parent_p);
115 +long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
116 +                             unsigned long *best_parent_rate,
117 +                             struct clk **best_parent_p);
118  
119  /*
120   * FIXME clock api without lock protection