diff options
Diffstat (limited to 'drivers/clk/sunxi-ng/ccu_mult.c')
-rw-r--r-- | drivers/clk/sunxi-ng/ccu_mult.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 010e9424691d..678b6cb49f01 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c @@ -13,10 +13,23 @@ #include "ccu_gate.h" #include "ccu_mult.h" +struct _ccu_mult { + unsigned long mult, min, max; +}; + static void ccu_mult_find_best(unsigned long parent, unsigned long rate, - unsigned int max_n, unsigned int *n) + struct _ccu_mult *mult) { - *n = rate / parent; + int _mult; + + _mult = rate / parent; + if (_mult < mult->min) + _mult = mult->min; + + if (_mult > mult->max) + _mult = mult->max; + + mult->mult = _mult; } static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, @@ -25,11 +38,13 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, void *data) { struct ccu_mult *cm = data; - unsigned int n; + struct _ccu_mult _cm; - ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n); + _cm.min = 1; + _cm.max = 1 << cm->mult.width; + ccu_mult_find_best(parent_rate, rate, &_cm); - return parent_rate * n; + return parent_rate * _cm.mult; } static void ccu_mult_disable(struct clk_hw *hw) @@ -83,21 +98,23 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct ccu_mult *cm = hw_to_ccu_mult(hw); + struct _ccu_mult _cm; unsigned long flags; - unsigned int n; u32 reg; ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, &parent_rate); - ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n); + _cm.min = cm->mult.min; + _cm.max = 1 << cm->mult.width; + ccu_mult_find_best(parent_rate, rate, &_cm); spin_lock_irqsave(cm->common.lock, flags); reg = readl(cm->common.base + cm->common.reg); reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift); - writel(reg | ((n - 1) << cm->mult.shift), + writel(reg | ((_cm.mult - 1) << cm->mult.shift), cm->common.base + cm->common.reg); spin_unlock_irqrestore(cm->common.lock, flags); |