diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index b48e1d01eaa3..0ebc10418e0d 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -106,6 +106,24 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), &m, &n); + /* + * When compensation the fractional divider, + * the [1:0] bits of the numerator register are omitted, + * which will lead to a large deviation in the result. + * Therefore, it is required that the numerator must + * be greater than 4. + */ + if (m < 4 && m != 0) { + val = DIV_ROUND_UP(4, m); + n *= val; + m *= val; + if (n > fd->nmask) { + pr_debug("%s n(%ld) is overflow, use mask value\n", + __func__, n); + n = fd->nmask; + } + } + if (fd->lock) spin_lock_irqsave(fd->lock, flags); else