Message ID | 20211001172033.122329-1-paul@crapouillou.net (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | clk: ingenic: Fix bugs with divided dividers | expand |
Quoting Paul Cercueil (2021-10-01 10:20:33) > Two fixes in one: > > - In the "impose hardware constraints" block, the "logical" divider > value (aka. not translated to the hardware) was clamped to fit in the > register area, but this totally ignored the fact that the divider > value can itself have a fixed divider. > > - The code that made sure that the divider value returned by the > function was a multiple of its own fixed divider could result in a > wrong value being calculated, because it was rounded down instead of > rounded up. > > Fixes: 4afe2d1a6ed5 ("clk: ingenic: Allow divider value to be divided") > Co-developed-by: Artur Rojek <contact@artur-rojek.eu> > Signed-off-by: Artur Rojek <contact@artur-rojek.eu> > Signed-off-by: Paul Cercueil <paul@crapouillou.net> > --- Applied to clk-next
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 266c7595d330..af31633a8862 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -453,15 +453,15 @@ ingenic_clk_calc_div(struct clk_hw *hw, } /* Impose hardware constraints */ - div = min_t(unsigned, div, 1 << clk_info->div.bits); - div = max_t(unsigned, div, 1); + div = clamp_t(unsigned int, div, clk_info->div.div, + clk_info->div.div << clk_info->div.bits); /* * If the divider value itself must be divided before being written to * the divider register, we must ensure we don't have any bits set that * would be lost as a result of doing so. */ - div /= clk_info->div.div; + div = DIV_ROUND_UP(div, clk_info->div.div); div *= clk_info->div.div; return div;