pwm: atmel: Fix disabling of PWM channels
authorGuillermo Rodriguez <guille.rodriguez@gmail.com>
Fri, 13 May 2016 11:09:37 +0000 (13:09 +0200)
committerThierry Reding <thierry.reding@gmail.com>
Mon, 11 Jul 2016 10:49:35 +0000 (12:49 +0200)
When disabling a PWM channel, the PWM clock was being stopped
immediately after writing to PWM_DIS. As a result, the disabling
of the PWM channel did not complete properly, and the PWM output
might be left at the wrong level.

Fix this by waiting for the channel to be effectively disabled
(by checking the PWM_SR register) before disabling the clock.

Signed-off-by: Guillermo Rodriguez <guille.rodriguez@gmail.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-atmel.c

index 0e4bd4e8e5823727c03b7701ad893b4cae1f7e7e..f3df529737f29676d4092f50623bcaa98542f3b5 100644 (file)
@@ -271,6 +271,16 @@ static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        mutex_unlock(&atmel_pwm->isr_lock);
        atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);
 
+       /*
+        * Wait for the PWM channel disable operation to be effective before
+        * stopping the clock.
+        */
+       timeout = jiffies + 2 * HZ;
+
+       while ((atmel_pwm_readl(atmel_pwm, PWM_SR) & (1 << pwm->hwpwm)) &&
+              time_before(jiffies, timeout))
+               usleep_range(10, 100);
+
        clk_disable(atmel_pwm->clk);
 }