diff options
Diffstat (limited to 'drivers/clk/mmp/clk-frac.c')
-rw-r--r-- | drivers/clk/mmp/clk-frac.c | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 1b90867b60c4..6556f6ada2e8 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c @@ -26,14 +26,15 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, { struct mmp_clk_factor *factor = to_clk_factor(hw); u64 rate = 0, prev_rate; + struct u32_fract *d; int i; for (i = 0; i < factor->ftbl_cnt; i++) { - prev_rate = rate; - rate = *prate; - rate *= factor->ftbl[i].den; - do_div(rate, factor->ftbl[i].num * factor->masks->factor); + d = &factor->ftbl[i]; + prev_rate = rate; + rate = (u64)(*prate) * d->denominator; + do_div(rate, d->numerator * factor->masks->factor); if (rate > drate) break; } @@ -52,23 +53,22 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, { struct mmp_clk_factor *factor = to_clk_factor(hw); struct mmp_clk_factor_masks *masks = factor->masks; - unsigned int val, num, den; + struct u32_fract d; + unsigned int val; u64 rate; val = readl_relaxed(factor->base); /* calculate numerator */ - num = (val >> masks->num_shift) & masks->num_mask; + d.numerator = (val >> masks->num_shift) & masks->num_mask; /* calculate denominator */ - den = (val >> masks->den_shift) & masks->den_mask; - - if (!den) + d.denominator = (val >> masks->den_shift) & masks->den_mask; + if (!d.denominator) return 0; - rate = parent_rate; - rate *= den; - do_div(rate, num * factor->masks->factor); + rate = (u64)parent_rate * d.denominator; + do_div(rate, d.numerator * factor->masks->factor); return rate; } @@ -82,18 +82,18 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, int i; unsigned long val; unsigned long flags = 0; + struct u32_fract *d; u64 rate = 0; for (i = 0; i < factor->ftbl_cnt; i++) { - rate = prate; - rate *= factor->ftbl[i].den; - do_div(rate, factor->ftbl[i].num * factor->masks->factor); + d = &factor->ftbl[i]; + rate = (u64)prate * d->denominator; + do_div(rate, d->numerator * factor->masks->factor); if (rate > drate) break; } - if (i > 0) - i--; + d = i ? &factor->ftbl[i - 1] : &factor->ftbl[0]; if (factor->lock) spin_lock_irqsave(factor->lock, flags); @@ -101,10 +101,10 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, val = readl_relaxed(factor->base); val &= ~(masks->num_mask << masks->num_shift); - val |= (factor->ftbl[i].num & masks->num_mask) << masks->num_shift; + val |= (d->numerator & masks->num_mask) << masks->num_shift; val &= ~(masks->den_mask << masks->den_shift); - val |= (factor->ftbl[i].den & masks->den_mask) << masks->den_shift; + val |= (d->denominator & masks->den_mask) << masks->den_shift; writel_relaxed(val, factor->base); @@ -118,7 +118,8 @@ static int clk_factor_init(struct clk_hw *hw) { struct mmp_clk_factor *factor = to_clk_factor(hw); struct mmp_clk_factor_masks *masks = factor->masks; - u32 val, num, den; + struct u32_fract d; + u32 val; int i; unsigned long flags = 0; @@ -128,23 +129,22 @@ static int clk_factor_init(struct clk_hw *hw) val = readl(factor->base); /* calculate numerator */ - num = (val >> masks->num_shift) & masks->num_mask; + d.numerator = (val >> masks->num_shift) & masks->num_mask; /* calculate denominator */ - den = (val >> masks->den_shift) & masks->den_mask; + d.denominator = (val >> masks->den_shift) & masks->den_mask; for (i = 0; i < factor->ftbl_cnt; i++) - if (den == factor->ftbl[i].den && num == factor->ftbl[i].num) + if (d.denominator == factor->ftbl[i].denominator && + d.numerator == factor->ftbl[i].numerator) break; if (i >= factor->ftbl_cnt) { val &= ~(masks->num_mask << masks->num_shift); - val |= (factor->ftbl[0].num & masks->num_mask) << - masks->num_shift; + val |= (factor->ftbl[0].numerator & masks->num_mask) << masks->num_shift; val &= ~(masks->den_mask << masks->den_shift); - val |= (factor->ftbl[0].den & masks->den_mask) << - masks->den_shift; + val |= (factor->ftbl[0].denominator & masks->den_mask) << masks->den_shift; } if (!(val & masks->enable_mask) || i >= factor->ftbl_cnt) { @@ -168,8 +168,7 @@ static const struct clk_ops clk_factor_ops = { struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, unsigned long flags, void __iomem *base, struct mmp_clk_factor_masks *masks, - struct mmp_clk_factor_tbl *ftbl, - unsigned int ftbl_cnt, spinlock_t *lock) + struct u32_fract *ftbl, unsigned int ftbl_cnt, spinlock_t *lock) { struct mmp_clk_factor *factor; struct clk_init_data init; |