diff options
| author | Doug Brown <doug@schmorgal.com> | 2022-12-02 19:35:21 +0100 | 
|---|---|---|
| committer | Thierry Reding <thierry.reding@gmail.com> | 2022-12-06 12:46:13 +0100 | 
| commit | 152f2d1def5e4b974947877126ff292a68a8c521 (patch) | |
| tree | d4c2be676ea7464f4d2578d88a6347ee2b8e4ba5 /drivers/pwm/pwm-pxa.c | |
| parent | f956b838934ab06deeee2ce9d5c8dfe64e4beb24 (diff) | |
pwm: pxa: Set duty cycle to 0 when disabling PWM
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>
Diffstat (limited to 'drivers/pwm/pwm-pxa.c')
| -rw-r--r-- | drivers/pwm/pwm-pxa.c | 25 | 
1 files changed, 16 insertions, 9 deletions
| diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index 0ac052652c62..9ee9b41d62b8 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c @@ -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;  } | 
