diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2017-05-17 10:40:30 +0300 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2017-06-07 16:32:12 +0300 |
commit | 22833a9165a1c72a54ddc696a3765bd6f87fbb92 (patch) | |
tree | c7633d35fa9dc645da3f64f3602b7a8999a68742 /drivers/clk/clk-divider.c | |
parent | b042e42feec495dd199525d3f88ffb323e5ec199 (diff) | |
download | linux-22833a9165a1c72a54ddc696a3765bd6f87fbb92.tar.xz |
clk: divider: Make divider_round_rate take the parent clock
So far, divider_round_rate only considers the parent clock returned by
clk_hw_get_parent.
This works fine on clocks that have a single parents, this doesn't work on
muxes, since we will only consider the first parent, while other parents
may totally be able to provide a better combination.
Clocks in that case cannot use divider_round_rate, so would have to come up
with a very similar logic to work around it. Instead of having to do
something like this, and duplicate that logic everywhere, create a
divider_round_rate parent to allow caller to give an additional parameter
for the parent clock to consider.
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Diffstat (limited to 'drivers/clk/clk-divider.c')
-rw-r--r-- | drivers/clk/clk-divider.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 96386ffc8483..9bb472cccca6 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -275,7 +275,8 @@ static int _next_div(const struct clk_div_table *table, int div, return div; } -static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, +static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent, + unsigned long rate, unsigned long *best_parent_rate, const struct clk_div_table *table, u8 width, unsigned long flags) @@ -314,8 +315,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, *best_parent_rate = parent_rate_saved; return i; } - parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), - rate * i); + parent_rate = clk_hw_round_rate(parent, rate * i); now = DIV_ROUND_UP_ULL((u64)parent_rate, i); if (_is_best_div(rate, now, best, flags)) { bestdiv = i; @@ -326,23 +326,24 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, if (!bestdiv) { bestdiv = _get_maxdiv(table, width, flags); - *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1); + *best_parent_rate = clk_hw_round_rate(parent, 1); } return bestdiv; } -long divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate, const struct clk_div_table *table, - u8 width, unsigned long flags) +long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, + unsigned long rate, unsigned long *prate, + const struct clk_div_table *table, + u8 width, unsigned long flags) { int div; - div = clk_divider_bestdiv(hw, rate, prate, table, width, flags); + div = clk_divider_bestdiv(hw, parent, rate, prate, table, width, flags); return DIV_ROUND_UP_ULL((u64)*prate, div); } -EXPORT_SYMBOL_GPL(divider_round_rate); +EXPORT_SYMBOL_GPL(divider_round_rate_parent); static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) |