131-clk-Add-__clk_mux_determine_rate_closest.patch 4.3 KB

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