|
@@ -144,12 +144,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
|
|
|
divider->flags);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * The reverse of DIV_ROUND_UP: The maximum number which
|
|
|
- * divided by m is r
|
|
|
- */
|
|
|
-#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
|
|
|
-
|
|
|
static bool _is_valid_table_div(const struct clk_div_table *table,
|
|
|
unsigned int div)
|
|
|
{
|
|
@@ -225,19 +219,24 @@ static int _div_round_closest(const struct clk_div_table *table,
|
|
|
unsigned long parent_rate, unsigned long rate,
|
|
|
unsigned long flags)
|
|
|
{
|
|
|
- int up, down, div;
|
|
|
+ int up, down;
|
|
|
+ unsigned long up_rate, down_rate;
|
|
|
|
|
|
- up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
|
|
+ up = DIV_ROUND_UP(parent_rate, rate);
|
|
|
+ down = parent_rate / rate;
|
|
|
|
|
|
if (flags & CLK_DIVIDER_POWER_OF_TWO) {
|
|
|
- up = __roundup_pow_of_two(div);
|
|
|
- down = __rounddown_pow_of_two(div);
|
|
|
+ up = __roundup_pow_of_two(up);
|
|
|
+ down = __rounddown_pow_of_two(down);
|
|
|
} else if (table) {
|
|
|
- up = _round_up_table(table, div);
|
|
|
- down = _round_down_table(table, div);
|
|
|
+ up = _round_up_table(table, up);
|
|
|
+ down = _round_down_table(table, down);
|
|
|
}
|
|
|
|
|
|
- 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,
|
|
@@ -313,7 +312,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
|
|
|
return i;
|
|
|
}
|
|
|
parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
|
|
|
- MULT_ROUND_UP(rate, i));
|
|
|
+ rate * i);
|
|
|
now = DIV_ROUND_UP(parent_rate, i);
|
|
|
if (_is_best_div(rate, now, best, flags)) {
|
|
|
bestdiv = i;
|
|
@@ -353,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
|
|
|
bestdiv = readl(divider->reg) >> divider->shift;
|
|
|
bestdiv &= div_mask(divider->width);
|
|
|
bestdiv = _get_div(divider->table, bestdiv, divider->flags);
|
|
|
- return bestdiv;
|
|
|
+ return DIV_ROUND_UP(*prate, bestdiv);
|
|
|
}
|
|
|
|
|
|
return divider_round_rate(hw, rate, prate, divider->table,
|