Skip to content

Commit aef1a37

Browse files
Uwe Kleine-Königthierryreding
authored andcommitted
pwm: imx27: Fix rounding behavior
To not trigger the warnings provided by CONFIG_PWM_DEBUG - use up-rounding in .get_state() - don't divide by the result of a division - don't use the rounded counter value for the period length to calculate the counter value for the duty cycle Signed-off-by: Uwe Kleine-König <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent cad0f29 commit aef1a37

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

drivers/pwm/pwm-imx27.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,12 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
150150

151151
prescaler = MX3_PWMCR_PRESCALER_GET(val);
152152
pwm_clk = clk_get_rate(imx->clk_per);
153-
pwm_clk = DIV_ROUND_CLOSEST_ULL(pwm_clk, prescaler);
154153
val = readl(imx->mmio_base + MX3_PWMPR);
155154
period = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val;
156155

157156
/* PWMOUT (Hz) = PWMCLK / (PWMPR + 2) */
158-
tmp = NSEC_PER_SEC * (u64)(period + 2);
159-
state->period = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
157+
tmp = NSEC_PER_SEC * (u64)(period + 2) * prescaler;
158+
state->period = DIV_ROUND_UP_ULL(tmp, pwm_clk);
160159

161160
/*
162161
* PWMSAR can be read only if PWM is enabled. If the PWM is disabled,
@@ -167,8 +166,8 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
167166
else
168167
val = imx->duty_cycle;
169168

170-
tmp = NSEC_PER_SEC * (u64)(val);
171-
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
169+
tmp = NSEC_PER_SEC * (u64)(val) * prescaler;
170+
state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk);
172171

173172
pwm_imx27_clk_disable_unprepare(imx);
174173
}
@@ -220,22 +219,23 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
220219
struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
221220
struct pwm_state cstate;
222221
unsigned long long c;
222+
unsigned long long clkrate;
223223
int ret;
224224
u32 cr;
225225

226226
pwm_get_state(pwm, &cstate);
227227

228-
c = clk_get_rate(imx->clk_per);
229-
c *= state->period;
228+
clkrate = clk_get_rate(imx->clk_per);
229+
c = clkrate * state->period;
230230

231-
do_div(c, 1000000000);
231+
do_div(c, NSEC_PER_SEC);
232232
period_cycles = c;
233233

234234
prescale = period_cycles / 0x10000 + 1;
235235

236236
period_cycles /= prescale;
237-
c = (unsigned long long)period_cycles * state->duty_cycle;
238-
do_div(c, state->period);
237+
c = clkrate * state->duty_cycle;
238+
do_div(c, NSEC_PER_SEC * prescale);
239239
duty_cycles = c;
240240

241241
/*

0 commit comments

Comments
 (0)