Skip to content

Commit 00e53d0

Browse files
ukleinekUwe Kleine-König
authored andcommitted
pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up
Waveform parameters are supposed to be rounded down to the next value possible for the hardware. However when a requested value is too small, .round_waveform_tohw() is supposed to pick the next bigger value and return 1. Let pwm_set_waveform() behave in the same way. This creates consistency between pwm_set_waveform_might_sleep() with exact=false and pwm_round_waveform_might_sleep() + pwm_set_waveform_might_sleep() with exact=true. The PWM_DEBUG rounding check has to be adapted to only trigger if no uprounding happend. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Tested-by: Trevor Gamblin <tgamblin@baylibre.com> Link: https://lore.kernel.org/r/353dc6ae31be815e41fd3df89c257127ca0d1a09.1743844730.git.u.kleine-koenig@baylibre.com Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
1 parent 928446a commit 00e53d0

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

drivers/pwm/core.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
322322
const struct pwm_ops *ops = chip->ops;
323323
char wfhw[WFHWSIZE];
324324
struct pwm_waveform wf_rounded;
325-
int err;
325+
int err, ret_tohw;
326326

327327
BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
328328

@@ -332,16 +332,16 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
332332
if (!pwm_wf_valid(wf))
333333
return -EINVAL;
334334

335-
err = __pwm_round_waveform_tohw(chip, pwm, wf, &wfhw);
336-
if (err)
337-
return err;
335+
ret_tohw = __pwm_round_waveform_tohw(chip, pwm, wf, &wfhw);
336+
if (ret_tohw < 0)
337+
return ret_tohw;
338338

339339
if ((IS_ENABLED(CONFIG_PWM_DEBUG) || exact) && wf->period_length_ns) {
340340
err = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf_rounded);
341341
if (err)
342342
return err;
343343

344-
if (IS_ENABLED(CONFIG_PWM_DEBUG) && !pwm_check_rounding(wf, &wf_rounded))
344+
if (IS_ENABLED(CONFIG_PWM_DEBUG) && ret_tohw == 0 && !pwm_check_rounding(wf, &wf_rounded))
345345
dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu]\n",
346346
wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
347347
wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns);
@@ -382,7 +382,8 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
382382
wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns,
383383
wf_set.duty_length_ns, wf_set.period_length_ns, wf_set.duty_offset_ns);
384384
}
385-
return 0;
385+
386+
return ret_tohw;
386387
}
387388

388389
/**

0 commit comments

Comments
 (0)