[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID:
<TYCPR01MB120934E8A094DD3185573B9C9C2482@TYCPR01MB12093.jpnprd01.prod.outlook.com>
Date: Mon, 12 Feb 2024 20:09:02 +0000
From: Fabrizio Castro <fabrizio.castro.jz@...esas.com>
To: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>
CC: Philipp Zabel <p.zabel@...gutronix.de>, Geert Uytterhoeven
<geert+renesas@...der.be>, Biju Das <biju.das.jz@...renesas.com>, Magnus Damm
<magnus.damm@...il.com>, "linux-kernel@...r.kernel.org"
<linux-kernel@...r.kernel.org>, "linux-pwm@...r.kernel.org"
<linux-pwm@...r.kernel.org>, "linux-renesas-soc@...r.kernel.org"
<linux-renesas-soc@...r.kernel.org>
Subject: RE: [PATCH v6 2/4] pwm: Add support for RZ/V2M PWM driver
Hello Uwe,
Thanks for your reply!
> From: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>
> Sent: Saturday, February 10, 2024 5:27 PM
> To: Fabrizio Castro <fabrizio.castro.jz@...esas.com>
> Subject: Re: [PATCH v6 2/4] pwm: Add support for RZ/V2M PWM driver
>
> Hello Fabrizio,
>
> On Thu, Feb 08, 2024 at 11:24:09PM +0000, Fabrizio Castro wrote:
> > +static inline u64 rzv2m_pwm_mul_u64_u64_div_u64_roundup(u64 a, u64 b,
> u64 c)
> > +{
> > + u64 ab = a * b;
>
> This might overflow.
In the context of this driver, this cannot overflow.
The 2 formulas the above is needed for are:
1) period = (cyc + 1)*(NSEC_PER_SEC * frequency_divisor)/rate
2) duty_cycle = (cyc + 1 - low)*(NSEC_PER_SEC * frequency_divisor)/rate
With respect to 1), the dividend overflows when period * rate also
overflows (its product is calculated in rzv2m_pwm_config).
However, limiting the period to a maximum value of U64_MAX / rate
prevents the calculations from overflowing (in both directions, from period to cyc, and from cyc to period). v6 uses max_period for this.
The situation for 2) is very similar to 1), with duty_cycle<=period,
therefore limiting period to a max value (and clamping the duty cycle
accordingly) will ensure that the calculation for duty_cycle won't
overflow, either.
>
> > + return ab / c + (ab % c ? 1 : 0);
>
> This division triggered the kernel build bot error. If you want to
> divide a u64, you must not use /.
Right!
I have replicated the problem locally, and confirmed that also other divisions from the same patch are problematic.
Clearly, % can't work either.
I am going to replace / with div64_u64.
For rounding up, I think I'll go with something like:
u64 ab = a * b;
u64 d = div64_u64(ab, c);
u64 e = d * c;
return d + ((ab - e) ? 1 : 0);
I am aware that I could use DIV64_U64_ROUND_UP instead of the above,
however, the above allows for larger dividends than when using DIV64_U64_ROUND_UP.
If I were to use DIV64_U64_ROUND_UP instead, I would have to limit
max_period further to (U64_MAX + 1 - rate)/rate, which I rather avoid.
I'll send v7 to address this build issue for 32 bit platforms.
Cheers,
Fab
>
> Best regards
> Uwe
>
> --
> Pengutronix e.K. | Uwe Kleine-König |
> Industrial Linux Solutions | https://www.pengutronix.de/ |
Powered by blists - more mailing lists