diff mbox series

[RFC,4/4] pwm: sun4i: Delay after writing the period

Message ID 20200317155906.31288-5-dev@pascalroeleven.nl
State Deferred
Headers show
Series [RFC,1/4] pwm: sun4i: Remove redundant needs_delay | expand

Commit Message

Pascal Roeleven March 17, 2020, 3:59 p.m. UTC
When disabling, ensure the period write is complete before continuing.
This fixes an issue on some devices when the write isn't complete before
the panel is turned off but the clock gate is still on.

Signed-off-by: Pascal Roeleven <dev@pascalroeleven.nl>
---
 drivers/pwm/pwm-sun4i.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Chen-Yu Tsai April 9, 2020, 3:20 p.m. UTC | #1
On Wed, Mar 18, 2020 at 12:00 AM Pascal Roeleven <dev@pascalroeleven.nl> wrote:
>
> When disabling, ensure the period write is complete before continuing.
> This fixes an issue on some devices when the write isn't complete before
> the panel is turned off but the clock gate is still on.
>
> Signed-off-by: Pascal Roeleven <dev@pascalroeleven.nl>

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Samuel Holland April 22, 2020, 3:43 a.m. UTC | #2
Hello Pascal,

On 3/17/20 10:59 AM, Pascal Roeleven wrote:
> When disabling, ensure the period write is complete before continuing.
> This fixes an issue on some devices when the write isn't complete before
> the panel is turned off but the clock gate is still on.
> 
> Signed-off-by: Pascal Roeleven <dev@pascalroeleven.nl>
> ---
>  drivers/pwm/pwm-sun4i.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
> index a11d00f96..75250fd4c 100644
> --- a/drivers/pwm/pwm-sun4i.c
> +++ b/drivers/pwm/pwm-sun4i.c
> @@ -299,6 +299,10 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>  	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
>  	next_period = jiffies + usecs_to_jiffies(cstate.period / 1000 + 1);
>  
> +	/* When disabling, make sure the period register is written first */
> +	if (!state->enabled && cstate.enabled)
> +		sun4i_pwm_wait(next_period);
> +

It is not visible from the context of this patch, but this call to
sun4i_pwm_wait() ends up calling msleep() inside a spinlock, which isn't
allowed. The spinlock should probably be converted to a mutex, considering that
sun4i_pwm_apply() already sleeps and takes mutexes.

Regards,
Samuel

>  	if (state->polarity != PWM_POLARITY_NORMAL)
>  		ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
>  	else
> @@ -320,6 +324,7 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>  		return 0;
>  
>  	/* We need a full period to elapse before disabling the channel. */
> +	next_period = jiffies + usecs_to_jiffies(cstate.period / 1000 + 1);
>  	sun4i_pwm_wait(next_period);
>  
>  	spin_lock(&sun4i_pwm->ctrl_lock);
>
Pascal Roeleven April 22, 2020, 8:40 a.m. UTC | #3
On 2020-04-22 05:43, Samuel Holland wrote:
> Hello Pascal,
> 
> On 3/17/20 10:59 AM, Pascal Roeleven wrote:
>> When disabling, ensure the period write is complete before continuing.
>> This fixes an issue on some devices when the write isn't complete 
>> before
>> the panel is turned off but the clock gate is still on.
>> 
>> Signed-off-by: Pascal Roeleven <dev@pascalroeleven.nl>
>> ---
>>  drivers/pwm/pwm-sun4i.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>> 
>> diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
>> index a11d00f96..75250fd4c 100644
>> --- a/drivers/pwm/pwm-sun4i.c
>> +++ b/drivers/pwm/pwm-sun4i.c
>> @@ -299,6 +299,10 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, 
>> struct pwm_device *pwm,
>>  	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
>>  	next_period = jiffies + usecs_to_jiffies(cstate.period / 1000 + 1);
>> 
>> +	/* When disabling, make sure the period register is written first */
>> +	if (!state->enabled && cstate.enabled)
>> +		sun4i_pwm_wait(next_period);
>> +
> 
> It is not visible from the context of this patch, but this call to
> sun4i_pwm_wait() ends up calling msleep() inside a spinlock, which 
> isn't
> allowed. The spinlock should probably be converted to a mutex, 
> considering that
> sun4i_pwm_apply() already sleeps and takes mutexes.
> 
> Regards,
> Samuel
> 

Yes you're right. A different implementation of this patch series is 
being worked on, in which I'll take this into account. Unfortunately I 
have other things to work on at the moment, so it might take a while.

Regards,
Pascal
diff mbox series

Patch

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index a11d00f96..75250fd4c 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -299,6 +299,10 @@  static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
 	next_period = jiffies + usecs_to_jiffies(cstate.period / 1000 + 1);
 
+	/* When disabling, make sure the period register is written first */
+	if (!state->enabled && cstate.enabled)
+		sun4i_pwm_wait(next_period);
+
 	if (state->polarity != PWM_POLARITY_NORMAL)
 		ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
 	else
@@ -320,6 +324,7 @@  static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 		return 0;
 
 	/* We need a full period to elapse before disabling the channel. */
+	next_period = jiffies + usecs_to_jiffies(cstate.period / 1000 + 1);
 	sun4i_pwm_wait(next_period);
 
 	spin_lock(&sun4i_pwm->ctrl_lock);