diff options
author | Clément Péron <peron.clem@gmail.com> | 2020-01-13 10:23:13 +0100 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2020-01-20 13:17:33 +0100 |
commit | 3e954d9626895d374704bb49a8fb538a974ebcf5 (patch) | |
tree | c16e336d98282ca0a00a6aec8a62e69d6403d147 /drivers/pwm | |
parent | 9f2919e9b40ec480609ee1f45567531de06ab3fe (diff) |
pwm: sun4i: Move pwm_calculate() out of spin_lock()
pwm_calculate() calls clk_get_rate() while holding a spin_lock().
This create an issue as clk_get_rate() may sleep.
Move pwm_calculate() out of this spin_lock().
Fixes: c32c5c50d4fe ("pwm: sun4i: Switch to atomic PWM")
Reported-by: Alexander Finger <alex.mobigo@gmail.com>
Sugested-by: Vasily Khoruzhick <anarsoul@gmail.com>
Tested-by: Alexander Finger <alex.mobigo@gmail.com>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/pwm-sun4i.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index 1afd41ebd3fd..6b230029dc49 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -248,19 +248,18 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, } } - spin_lock(&sun4i_pwm->ctrl_lock); - ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); - ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler, &bypass); if (ret) { dev_err(chip->dev, "period exceeds the maximum value\n"); - spin_unlock(&sun4i_pwm->ctrl_lock); if (!cstate.enabled) clk_disable_unprepare(sun4i_pwm->clk); return ret; } + spin_lock(&sun4i_pwm->ctrl_lock); + ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); + if (sun4i_pwm->data->has_direct_mod_clk_output) { if (bypass) { ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm); |