[...] > +static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, > + unsigned long *best_parent_rate) > +{ > + struct clk_divider *divider = to_clk_divider(hw); > + int i, bestdiv = 0; > + unsigned long parent_rate, best = 0, now, maxdiv; > + > + if (!rate) > + rate = 1; > + > + maxdiv = (1 << divider->width); > + > + if (divider->flags & CLK_DIVIDER_ONE_BASED) > + maxdiv--; > + > + if (!best_parent_rate) { > + parent_rate = __clk_get_rate(__clk_get_parent(hw->clk)); > + bestdiv = DIV_ROUND_UP(parent_rate, rate); > + bestdiv = bestdiv == 0 ? 1 : bestdiv; > + bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; > + return bestdiv; > + } > + > + /* > + * The maximum divider we can use without overflowing > + * unsigned long in rate * i below > + */ > + maxdiv = min(ULONG_MAX / rate, maxdiv); > + > + for (i = 1; i <= maxdiv; i++) { > + parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), > + MULT_ROUND_UP(rate, i)); > + now = parent_rate / i; > + if (now <= rate && now > best) { > + bestdiv = i; > + best = now; > + *best_parent_rate = parent_rate; Better add if (now == rate) break; There may be more than one hit for (now == rate). We'd better select smallest div, thus smallest parent_rate.
It's the same comment for v6, but not show stopper. Thanks Richard > + } > + } > + > + if (!bestdiv) { > + bestdiv = (1 << divider->width); > + if (divider->flags & CLK_DIVIDER_ONE_BASED) > + bestdiv--; > + *best_parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), > 1); > + } > + > + return bestdiv; > +} _______________________________________________ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev