]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
pwm: imx27: Fix overflow for bigger periods
authorUwe Kleine-König <uwe@kleine-koenig.org>
Mon, 7 Dec 2020 14:13:24 +0000 (15:13 +0100)
committerThierry Reding <thierry.reding@gmail.com>
Thu, 17 Dec 2020 13:19:01 +0000 (14:19 +0100)
The second parameter of do_div is an u32 and NSEC_PER_SEC * prescale
overflows this for bigger periods. Assuming the usual pwm input clk rate
of 66 MHz this happens starting at requested period > 606060 ns.

Splitting the division into two operations doesn't loose any precision.
It doesn't need to be feared that c / NSEC_PER_SEC doesn't fit into the
unsigned long variable "duty_cycles" because in this case the assignment
above to period_cycles would already have been overflowing as
period >= duty_cycle and then the calculation is moot anyhow.

Fixes: aef1a3799b5c ("pwm: imx27: Fix rounding behavior")
Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Tested-by: Johannes Pointner <johannes.pointner@br-automation.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-imx27.c

index ceaed0378de7059d1e1c983d0de15cc290d4a28e..18055326a2f38b1d4f520b2a12b4db17de5f4c16 100644 (file)
@@ -235,8 +235,9 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 
        period_cycles /= prescale;
        c = clkrate * state->duty_cycle;
-       do_div(c, NSEC_PER_SEC * prescale);
+       do_div(c, NSEC_PER_SEC);
        duty_cycles = c;
+       duty_cycles /= prescale;
 
        /*
         * according to imx pwm RM, the real period value should be PERIOD