Skip to content

Commit

Permalink
clk: divider: fix selection of divider when rounding to closest
Browse files Browse the repository at this point in the history
It's an invalid approach to assume that among two divider values
the one nearer the exact divider is the better one.

Assume a parent rate of 1000 Hz, a divider with CLK_DIVIDER_POWER_OF_TWO
and a target rate of 89 Hz. The exact divider is ~ 11.236 so 8 and 16
are the candidates to choose from yielding rates 125 Hz and 62.5 Hz
respectivly. While 8 is nearer to 11.236 than 16 is, the latter is still
the better divider as 62.5 is nearer to 89 than 125 is.

Fixes: 774b514 (clk: divider: Add round to closest divider)
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Maxime Coquelin <maxime.coquelin@st.com>
Signed-off-by: Michael Turquette <mturquette@linaro.org>
  • Loading branch information
Uwe Kleine-König authored and Michael Turquette committed Mar 9, 2015
1 parent da32113 commit 26bac95
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion drivers/clk/clk-divider.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ static int _div_round_closest(const struct clk_div_table *table,
unsigned long flags)
{
int up, down, div;
unsigned long up_rate, down_rate;

up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);

Expand All @@ -231,7 +232,10 @@ static int _div_round_closest(const struct clk_div_table *table,
down = _round_down_table(table, div);
}

return (up - div) <= (div - down) ? up : down;
up_rate = DIV_ROUND_UP(parent_rate, up);
down_rate = DIV_ROUND_UP(parent_rate, down);

return (rate - up_rate) <= (down_rate - rate) ? up : down;
}

static int _div_round(const struct clk_div_table *table,
Expand Down

0 comments on commit 26bac95

Please sign in to comment.