Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / drivers / clk / clk-multiplier.c
index 9e449c7b751c328e23b074186e1bebf426172087..dc037c957acd8a1dc1f74f3c0407567a09fa66cd 100644 (file)
@@ -52,14 +52,28 @@ static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
                                unsigned long *best_parent_rate,
                                u8 width, unsigned long flags)
 {
+       struct clk_multiplier *mult = to_clk_multiplier(hw);
        unsigned long orig_parent_rate = *best_parent_rate;
        unsigned long parent_rate, current_rate, best_rate = ~0;
        unsigned int i, bestmult = 0;
+       unsigned int maxmult = (1 << width) - 1;
+
+       if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+               bestmult = rate / orig_parent_rate;
+
+               /* Make sure we don't end up with a 0 multiplier */
+               if ((bestmult == 0) &&
+                   !(mult->flags & CLK_MULTIPLIER_ZERO_BYPASS))
+                       bestmult = 1;
 
-       if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
-               return rate / *best_parent_rate;
+               /* Make sure we don't overflow the multiplier */
+               if (bestmult > maxmult)
+                       bestmult = maxmult;
+
+               return bestmult;
+       }
 
-       for (i = 1; i < ((1 << width) - 1); i++) {
+       for (i = 1; i < maxmult; i++) {
                if (rate == orig_parent_rate * i) {
                        /*
                         * This is the best case for us if we have a