Hi Geert-san, > From: Geert Uytterhoeven, Sent: Tuesday, January 8, 2019 5:22 PM > > Hi Shimoda-san, > > On Tue, Jan 8, 2019 at 4:31 AM Yoshihiro Shimoda > <yoshihiro.shimoda.uh@xxxxxxxxxxx> wrote: > > The rcar_pwm_get_clock_division() has a loop to calculate the divider, > > but the value of div should be calculatable without a loop. So, > > this patch improves it. > > > > This algorithm is suggested by Uwe Kleine-König and Laurent Pinchart. > > > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx> > > --- > > drivers/pwm/pwm-rcar.c | 16 +++++++--------- > > 1 file changed, 7 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c > > index 6dbb70c..0498a93 100644 > > --- a/drivers/pwm/pwm-rcar.c > > +++ b/drivers/pwm/pwm-rcar.c > > @@ -8,6 +8,8 @@ > > #include <linux/clk.h> > > #include <linux/err.h> > > #include <linux/io.h> > > +#include <linux/log2.h> > > +#include <linux/math64.h> > > #include <linux/module.h> > > #include <linux/of.h> > > #include <linux/platform_device.h> > > @@ -68,19 +70,15 @@ static void rcar_pwm_update(struct rcar_pwm_chip *rp, u32 mask, u32 data, > > static int rcar_pwm_get_clock_division(struct rcar_pwm_chip *rp, int period_ns) > > { > > unsigned long clk_rate = clk_get_rate(rp->clk); > > - unsigned long long max; /* max cycle / nanoseconds */ > > - unsigned int div; > > + u64 div, tmp; > > > > if (clk_rate == 0) > > return -EINVAL; > > > > - for (div = 0; div <= RCAR_PWM_MAX_DIVISION; div++) { > > - max = (unsigned long long)NSEC_PER_SEC * RCAR_PWM_MAX_CYCLE * > > - (1 << div); > > - do_div(max, clk_rate); > > - if (period_ns <= max) > > - break; > > - } > > + div = NSEC_PER_SEC * RCAR_PWM_MAX_CYCLE; > > As we have: > > #define NSEC_PER_SEC 1000000000L > #define RCAR_PWM_MAX_CYCLE 1023 > > NSEC_PER_SEC is 64-bit on arm64, and 32-bit on arm32. > > Hence you should use > > div = (u64)NSEC_PER_SEC * RCAR_PWM_MAX_CYCLE; > > to avoid overflow on arm32. Thank you for the comment! I'll fix this. Best regards, Yoshihiro Shimoda > > + tmp = (u64)period_ns * clk_rate + div - 1; > > + tmp = div64_u64(tmp, div); > > + div = ilog2(tmp - 1) + 1; > > > > return (div <= RCAR_PWM_MAX_DIVISION) ? div : -ERANGE; > > } > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like that. > -- Linus Torvalds