mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
pwm: imx27: Fix variable truncation in .apply()
Fix a variable truncation when calculating period in microseconds as
part of the solution for the ERR051198 in .apply() callback.
Example scenario:
- Period of 3us (PWMPR = 196 and prescaler = 1)
- Expected value in tmp: 198000000000 (NSEC_PER_SEC * (196 + 2) * 1)
- Actual value is 431504384 (truncation to u32)
Signed-off-by: Ronaldo Nunez <rnunez@baylibre.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260522191348.6227-1-rnunez@baylibre.com
Fixes: a25351e4c7 ("pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle")
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
This commit is contained in:
parent
c84291ce0e
commit
dc9e08fdbc
|
|
@ -200,7 +200,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
|
|||
static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
const struct pwm_state *state)
|
||||
{
|
||||
unsigned long period_cycles, duty_cycles, prescale, period_us, tmp;
|
||||
unsigned long period_cycles, duty_cycles, prescale, period_us;
|
||||
struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
|
||||
unsigned long long c;
|
||||
unsigned long long clkrate;
|
||||
|
|
@ -208,6 +208,7 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
|||
int val;
|
||||
int ret;
|
||||
u32 cr;
|
||||
u64 tmp;
|
||||
|
||||
clkrate = clk_get_rate(imx->clks[PWM_IMX27_PER].clk);
|
||||
c = clkrate * state->period;
|
||||
|
|
@ -249,6 +250,11 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
|||
val = readl(imx->mmio_base + MX3_PWMPR);
|
||||
val = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val;
|
||||
cr = readl(imx->mmio_base + MX3_PWMCR);
|
||||
|
||||
/*
|
||||
* tmp stores period in nanoseconds. Result fits in u64 since
|
||||
* val <= 0xfffe and prescaler in [1, 0x1000].
|
||||
*/
|
||||
tmp = NSEC_PER_SEC * (u64)(val + 2) * MX3_PWMCR_PRESCALER_GET(cr);
|
||||
tmp = DIV_ROUND_UP_ULL(tmp, clkrate);
|
||||
period_us = DIV_ROUND_UP_ULL(tmp, 1000);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user