Skip to content

Commit c110395

Browse files
Ronaldo Nunezgregkh
authored andcommitted
pwm: imx27: Fix variable truncation in .apply()
[ Upstream commit dc9e08f ] 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: a25351e ("pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle") Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 13db458 commit c110395

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

drivers/pwm/pwm-imx27.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,15 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
200200
static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
201201
const struct pwm_state *state)
202202
{
203-
unsigned long period_cycles, duty_cycles, prescale, period_us, tmp;
203+
unsigned long period_cycles, duty_cycles, prescale, period_us;
204204
struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
205205
unsigned long long c;
206206
unsigned long long clkrate;
207207
unsigned long flags;
208208
int val;
209209
int ret;
210210
u32 cr;
211+
u64 tmp;
211212

212213
clkrate = clk_get_rate(imx->clks[PWM_IMX27_PER].clk);
213214
c = clkrate * state->period;
@@ -249,6 +250,11 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
249250
val = readl(imx->mmio_base + MX3_PWMPR);
250251
val = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val;
251252
cr = readl(imx->mmio_base + MX3_PWMCR);
253+
254+
/*
255+
* tmp stores period in nanoseconds. Result fits in u64 since
256+
* val <= 0xfffe and prescaler in [1, 0x1000].
257+
*/
252258
tmp = NSEC_PER_SEC * (u64)(val + 2) * MX3_PWMCR_PRESCALER_GET(cr);
253259
tmp = DIV_ROUND_UP_ULL(tmp, clkrate);
254260
period_us = DIV_ROUND_UP_ULL(tmp, 1000);

0 commit comments

Comments
 (0)