pwm: pxa: Set duty cycle to 0 when disabling PWM
authorDoug Brown <doug@schmorgal.com>
Fri, 2 Dec 2022 18:35:21 +0000 (19:35 +0100)
committerThierry Reding <thierry.reding@gmail.com>
Tue, 6 Dec 2022 11:46:13 +0000 (12:46 +0100)
When disabling PWM, the duty cycle needs to be set to 0. This prevents
the previous duty cycle from showing up momentarily when the clock is
re-enabled next time.

Because the clock has to be running in order to configure the duty
cycle, unconditionally enable it early in pxa_pwm_apply and account for
the correct enable count at the end.

Suggested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Doug Brown <doug@schmorgal.com>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20221113233639.24244-3-doug@schmorgal.com
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-pxa.c

index 0ac052652c62726d19790d36b190e0d384d3e694..9ee9b41d62b8b226d90c907a6f92539de353ad52 100644 (file)
@@ -105,24 +105,31 @@ static int pxa_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                         const struct pwm_state *state)
 {
        struct pxa_pwm_chip *pc = to_pxa_pwm_chip(chip);
+       u64 duty_cycle;
        int err;
 
        if (state->polarity != PWM_POLARITY_NORMAL)
                return -EINVAL;
 
-       if (!state->enabled) {
-               if (pwm->state.enabled)
-                       clk_disable_unprepare(pc->clk);
+       err = clk_prepare_enable(pc->clk);
+       if (err)
+               return err;
 
-               return 0;
-       }
+       duty_cycle = state->enabled ? state->duty_cycle : 0;
 
-       err = pxa_pwm_config(chip, pwm, state->duty_cycle, state->period);
-       if (err)
+       err = pxa_pwm_config(chip, pwm, duty_cycle, state->period);
+       if (err) {
+               clk_disable_unprepare(pc->clk);
                return err;
+       }
+
+       if (state->enabled && !pwm->state.enabled)
+               return 0;
+
+       clk_disable_unprepare(pc->clk);
 
-       if (!pwm->state.enabled)
-               return clk_prepare_enable(pc->clk);
+       if (!state->enabled && pwm->state.enabled)
+               clk_disable_unprepare(pc->clk);
 
        return 0;
 }