Skip to content

Commit 92f69e5

Browse files
Uwe Kleine-Königthierryreding
authored andcommitted
pwm: Prevent a glitch for legacy drivers
If a running PWM is reconfigured to disabled calling the ->config() callback before disabling the hardware might result in a glitch where the (maybe) new period and duty_cycle are visible on the output before disabling the hardware. So handle disabling before calling ->config(). Also exit early in this case which is possible because period and duty_cycle don't matter for disabled PWMs. In return however ->config has to be called even if state->period == pwm->state.period && state->duty_cycle != pwm->state.duty_cycle because setting these might have been skipped in the previous call. Signed-off-by: Uwe Kleine-König <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent 77965c9 commit 92f69e5

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

drivers/pwm/core.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -555,26 +555,33 @@ static int pwm_apply_legacy(struct pwm_chip *chip, struct pwm_device *pwm,
555555
pwm->state.polarity = state->polarity;
556556
}
557557

558-
if (state->period != pwm->state.period ||
559-
state->duty_cycle != pwm->state.duty_cycle) {
560-
err = chip->ops->config(pwm->chip, pwm,
561-
state->duty_cycle,
562-
state->period);
563-
if (err)
564-
return err;
558+
if (!state->enabled) {
559+
if (pwm->state.enabled)
560+
chip->ops->disable(chip, pwm);
565561

566-
pwm->state.period = state->period;
567-
pwm->state.duty_cycle = state->duty_cycle;
562+
return 0;
568563
}
569564

570-
if (state->enabled != pwm->state.enabled) {
571-
if (!pwm->state.enabled) {
572-
err = chip->ops->enable(chip, pwm);
573-
if (err)
574-
return err;
575-
} else {
576-
chip->ops->disable(chip, pwm);
577-
}
565+
/*
566+
* We cannot skip calling ->config even if state->period ==
567+
* pwm->state.period && state->duty_cycle == pwm->state.duty_cycle
568+
* because we might have exited early in the last call to
569+
* pwm_apply_state because of !state->enabled and so the two values in
570+
* pwm->state might not be configured in hardware.
571+
*/
572+
err = chip->ops->config(pwm->chip, pwm,
573+
state->duty_cycle,
574+
state->period);
575+
if (err)
576+
return err;
577+
578+
pwm->state.period = state->period;
579+
pwm->state.duty_cycle = state->duty_cycle;
580+
581+
if (!pwm->state.enabled) {
582+
err = chip->ops->enable(chip, pwm);
583+
if (err)
584+
return err;
578585
}
579586

580587
return 0;

0 commit comments

Comments
 (0)