Skip to content

Commit

Permalink
clk: at91: optimization of the set_rate callback
Browse files Browse the repository at this point in the history
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
  • Loading branch information
Jean-Jacques Hiblot authored and Mike Turquette committed Mar 19, 2014
1 parent cce6db8 commit 141c71d
Showing 1 changed file with 8 additions and 30 deletions.
38 changes: 8 additions & 30 deletions drivers/clk/at91/clk-programmable.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,43 +139,21 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
struct clk_programmable *prog = to_clk_programmable(hw);
struct at91_pmc *pmc = prog->pmc;
const struct clk_programmable_layout *layout = prog->layout;
unsigned long best_rate = parent_rate;
unsigned long best_diff;
unsigned long new_diff;
unsigned long cur_rate;
unsigned long div = parent_rate / rate;
int shift = 0;
u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
~(PROG_PRES_MASK << layout->pres_shift);

if (rate > parent_rate)
return parent_rate;
else
best_diff = parent_rate - rate;
if (!div)
return -EINVAL;

if (!best_diff) {
pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | shift);
return 0;
}

for (shift = 1; shift < PROG_PRES_MASK; shift++) {
cur_rate = parent_rate >> shift;

if (cur_rate > rate)
new_diff = cur_rate - rate;
else
new_diff = rate - cur_rate;

if (!new_diff)
break;
shift = fls(div) - 1;

if (new_diff < best_diff) {
best_diff = new_diff;
best_rate = cur_rate;
}
if (div != (1<<shift))
return -EINVAL;

if (rate > cur_rate)
break;
}
if (shift >= PROG_PRES_MASK)
return -EINVAL;

pmc_write(pmc, AT91_PMC_PCKR(prog->id),
tmp | (shift << layout->pres_shift));
Expand Down

0 comments on commit 141c71d

Please sign in to comment.