* [PATCH] pwm: iqs620a: Correct a stale state variable
@ 2021-01-15 5:00 Jeff LaBundy
2021-01-15 7:45 ` Uwe Kleine-König
0 siblings, 1 reply; 5+ messages in thread
From: Jeff LaBundy @ 2021-01-15 5:00 UTC (permalink / raw)
To: thierry.reding; +Cc: u.kleine-koenig, lee.jones, linux-pwm, Jeff LaBundy
If duty cycle is first set to a value that is sufficiently high to
enable the output (e.g. 10000 ns) but then lowered to a value that
is quantized to zero (e.g. 1000 ns), the output is disabled as the
device cannot drive a constant zero (as expected).
However if the device is later re-initialized due to watchdog bite,
the output is re-enabled at the next-to-last duty cycle (10000 ns).
This is because the iqs620_pwm->out_en flag unconditionally tracks
state->enabled instead of what was actually written to the device.
To solve this problem, force the iqs620_pwm->out_en flag to follow
the IQS620_PWR_SETTINGS_PWM_OUT field instead, as was the original
design intent.
Fixes: 6f0841a8197b ("pwm: Add support for Azoteq IQS620A PWM generator")
Signed-off-by: Jeff LaBundy <jeff@labundy.com>
---
drivers/pwm/pwm-iqs620a.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
index 5ede825..5eb8fa4 100644
--- a/drivers/pwm/pwm-iqs620a.c
+++ b/drivers/pwm/pwm-iqs620a.c
@@ -79,6 +79,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
IQS620_PWR_SETTINGS_PWM_OUT, 0);
if (ret)
goto err_mutex;
+
+ iqs620_pwm->out_en = false;
}
if (duty_scale) {
@@ -97,9 +99,9 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
if (ret)
goto err_mutex;
- }
- iqs620_pwm->out_en = state->enabled;
+ iqs620_pwm->out_en = true;
+ }
err_mutex:
mutex_unlock(&iqs620_pwm->lock);
--
2.7.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] pwm: iqs620a: Correct a stale state variable
2021-01-15 5:00 [PATCH] pwm: iqs620a: Correct a stale state variable Jeff LaBundy
@ 2021-01-15 7:45 ` Uwe Kleine-König
2021-01-18 4:30 ` Jeff LaBundy
0 siblings, 1 reply; 5+ messages in thread
From: Uwe Kleine-König @ 2021-01-15 7:45 UTC (permalink / raw)
To: Jeff LaBundy; +Cc: thierry.reding, lee.jones, linux-pwm
[-- Attachment #1: Type: text/plain, Size: 2282 bytes --]
On Thu, Jan 14, 2021 at 11:00:34PM -0600, Jeff LaBundy wrote:
> If duty cycle is first set to a value that is sufficiently high to
> enable the output (e.g. 10000 ns) but then lowered to a value that
> is quantized to zero (e.g. 1000 ns), the output is disabled as the
> device cannot drive a constant zero (as expected).
>
> However if the device is later re-initialized due to watchdog bite,
> the output is re-enabled at the next-to-last duty cycle (10000 ns).
> This is because the iqs620_pwm->out_en flag unconditionally tracks
> state->enabled instead of what was actually written to the device.
>
> To solve this problem, force the iqs620_pwm->out_en flag to follow
> the IQS620_PWR_SETTINGS_PWM_OUT field instead, as was the original
> design intent.
>
> Fixes: 6f0841a8197b ("pwm: Add support for Azoteq IQS620A PWM generator")
> Signed-off-by: Jeff LaBundy <jeff@labundy.com>
> ---
> drivers/pwm/pwm-iqs620a.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
> index 5ede825..5eb8fa4 100644
> --- a/drivers/pwm/pwm-iqs620a.c
> +++ b/drivers/pwm/pwm-iqs620a.c
> @@ -79,6 +79,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> IQS620_PWR_SETTINGS_PWM_OUT, 0);
> if (ret)
> goto err_mutex;
> +
> + iqs620_pwm->out_en = false;
> }
>
> if (duty_scale) {
> @@ -97,9 +99,9 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
> if (ret)
> goto err_mutex;
> - }
>
> - iqs620_pwm->out_en = state->enabled;
> + iqs620_pwm->out_en = true;
> + }
I got the problem and I agree it needs fixing. Are you aware you change
the semantic of out_en here and so the behaviour of .get_state()? IMHO
the change is fine however, and unless I miss something this patch makes
the comment in iqs620_pwm_get_state true.
Other than that I wonder if it would make more sense to track duty_scale
in the driver struct instead of duty_val and out_en.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] pwm: iqs620a: Correct a stale state variable
2021-01-15 7:45 ` Uwe Kleine-König
@ 2021-01-18 4:30 ` Jeff LaBundy
2021-01-18 8:02 ` Uwe Kleine-König
0 siblings, 1 reply; 5+ messages in thread
From: Jeff LaBundy @ 2021-01-18 4:30 UTC (permalink / raw)
To: Uwe Kleine-König; +Cc: thierry.reding, lee.jones, linux-pwm
Hi Uwe,
Thank you for taking a look; actually I came across this problem while
testing your patch, so I owe you even more gratitude :)
On Fri, Jan 15, 2021 at 08:45:09AM +0100, Uwe Kleine-König wrote:
> On Thu, Jan 14, 2021 at 11:00:34PM -0600, Jeff LaBundy wrote:
> > If duty cycle is first set to a value that is sufficiently high to
> > enable the output (e.g. 10000 ns) but then lowered to a value that
> > is quantized to zero (e.g. 1000 ns), the output is disabled as the
> > device cannot drive a constant zero (as expected).
> >
> > However if the device is later re-initialized due to watchdog bite,
> > the output is re-enabled at the next-to-last duty cycle (10000 ns).
> > This is because the iqs620_pwm->out_en flag unconditionally tracks
> > state->enabled instead of what was actually written to the device.
> >
> > To solve this problem, force the iqs620_pwm->out_en flag to follow
> > the IQS620_PWR_SETTINGS_PWM_OUT field instead, as was the original
> > design intent.
> >
> > Fixes: 6f0841a8197b ("pwm: Add support for Azoteq IQS620A PWM generator")
> > Signed-off-by: Jeff LaBundy <jeff@labundy.com>
> > ---
> > drivers/pwm/pwm-iqs620a.c | 6 ++++--
> > 1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
> > index 5ede825..5eb8fa4 100644
> > --- a/drivers/pwm/pwm-iqs620a.c
> > +++ b/drivers/pwm/pwm-iqs620a.c
> > @@ -79,6 +79,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > IQS620_PWR_SETTINGS_PWM_OUT, 0);
> > if (ret)
> > goto err_mutex;
> > +
> > + iqs620_pwm->out_en = false;
> > }
> >
> > if (duty_scale) {
> > @@ -97,9 +99,9 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
> > if (ret)
> > goto err_mutex;
> > - }
> >
> > - iqs620_pwm->out_en = state->enabled;
> > + iqs620_pwm->out_en = true;
> > + }
>
> I got the problem and I agree it needs fixing. Are you aware you change
> the semantic of out_en here and so the behaviour of .get_state()? IMHO
> the change is fine however, and unless I miss something this patch makes
> the comment in iqs620_pwm_get_state true.
Agreed on all counts; in fact I saw this as an improvement because the
get_state callback now reflects the actual state of the hardware under
all circumstances.
As you mention, the comment in iqs620_pwm_get_state() is fully correct
now too. Previously it was incorrect in this particular corner case.
>
> Other than that I wonder if it would make more sense to track duty_scale
> in the driver struct instead of duty_val and out_en.
You would still have to cache state->enabled because it's required for
decoding duty_scale at the time it was cached, so there is not much to
gain. I prefer this solution because the get_state callback is correct
across all cases now, and the change is small.
>
> Best regards
> Uwe
>
> --
> Pengutronix e.K. | Uwe Kleine-König |
> Industrial Linux Solutions | https://www.pengutronix.de/ |
Kind regards,
Jeff LaBundy
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] pwm: iqs620a: Correct a stale state variable
2021-01-18 4:30 ` Jeff LaBundy
@ 2021-01-18 8:02 ` Uwe Kleine-König
2021-01-19 2:55 ` Jeff LaBundy
0 siblings, 1 reply; 5+ messages in thread
From: Uwe Kleine-König @ 2021-01-18 8:02 UTC (permalink / raw)
To: Jeff LaBundy; +Cc: thierry.reding, lee.jones, linux-pwm, kernel
[-- Attachment #1: Type: text/plain, Size: 3501 bytes --]
Hello Jeff,
On Sun, Jan 17, 2021 at 10:30:05PM -0600, Jeff LaBundy wrote:
> Thank you for taking a look; actually I came across this problem while
> testing your patch, so I owe you even more gratitude :)
:-)
> On Fri, Jan 15, 2021 at 08:45:09AM +0100, Uwe Kleine-König wrote:
> > On Thu, Jan 14, 2021 at 11:00:34PM -0600, Jeff LaBundy wrote:
> > > If duty cycle is first set to a value that is sufficiently high to
> > > enable the output (e.g. 10000 ns) but then lowered to a value that
> > > is quantized to zero (e.g. 1000 ns), the output is disabled as the
> > > device cannot drive a constant zero (as expected).
> > >
> > > However if the device is later re-initialized due to watchdog bite,
> > > the output is re-enabled at the next-to-last duty cycle (10000 ns).
> > > This is because the iqs620_pwm->out_en flag unconditionally tracks
> > > state->enabled instead of what was actually written to the device.
> > >
> > > To solve this problem, force the iqs620_pwm->out_en flag to follow
> > > the IQS620_PWR_SETTINGS_PWM_OUT field instead, as was the original
> > > design intent.
> > >
> > > Fixes: 6f0841a8197b ("pwm: Add support for Azoteq IQS620A PWM generator")
> > > Signed-off-by: Jeff LaBundy <jeff@labundy.com>
> > > ---
> > > drivers/pwm/pwm-iqs620a.c | 6 ++++--
> > > 1 file changed, 4 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
> > > index 5ede825..5eb8fa4 100644
> > > --- a/drivers/pwm/pwm-iqs620a.c
> > > +++ b/drivers/pwm/pwm-iqs620a.c
> > > @@ -79,6 +79,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > > IQS620_PWR_SETTINGS_PWM_OUT, 0);
> > > if (ret)
> > > goto err_mutex;
> > > +
> > > + iqs620_pwm->out_en = false;
> > > }
> > >
> > > if (duty_scale) {
> > > @@ -97,9 +99,9 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > > IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
> > > if (ret)
> > > goto err_mutex;
> > > - }
> > >
> > > - iqs620_pwm->out_en = state->enabled;
> > > + iqs620_pwm->out_en = true;
> > > + }
> >
> > I got the problem and I agree it needs fixing. Are you aware you change
> > the semantic of out_en here and so the behaviour of .get_state()? IMHO
> > the change is fine however, and unless I miss something this patch makes
> > the comment in iqs620_pwm_get_state true.
>
> Agreed on all counts; in fact I saw this as an improvement because the
> get_state callback now reflects the actual state of the hardware under
> all circumstances.
>
> As you mention, the comment in iqs620_pwm_get_state() is fully correct
> now too. Previously it was incorrect in this particular corner case.
ok, I wondered if I missed something.
> > Other than that I wonder if it would make more sense to track duty_scale
> > in the driver struct instead of duty_val and out_en.
>
> You would still have to cache state->enabled because it's required for
> decoding duty_scale at the time it was cached, so there is not much to
> gain. I prefer this solution because the get_state callback is correct
> across all cases now, and the change is small.
Can't we cope for this by just doing
if (!state->enabled)
duty_scale = 0;
?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] pwm: iqs620a: Correct a stale state variable
2021-01-18 8:02 ` Uwe Kleine-König
@ 2021-01-19 2:55 ` Jeff LaBundy
0 siblings, 0 replies; 5+ messages in thread
From: Jeff LaBundy @ 2021-01-19 2:55 UTC (permalink / raw)
To: Uwe Kleine-König; +Cc: thierry.reding, lee.jones, linux-pwm, kernel
Hi Uwe,
On Mon, Jan 18, 2021 at 09:02:19AM +0100, Uwe Kleine-König wrote:
> Hello Jeff,
>
> On Sun, Jan 17, 2021 at 10:30:05PM -0600, Jeff LaBundy wrote:
> > Thank you for taking a look; actually I came across this problem while
> > testing your patch, so I owe you even more gratitude :)
>
> :-)
>
> > On Fri, Jan 15, 2021 at 08:45:09AM +0100, Uwe Kleine-König wrote:
> > > On Thu, Jan 14, 2021 at 11:00:34PM -0600, Jeff LaBundy wrote:
> > > > If duty cycle is first set to a value that is sufficiently high to
> > > > enable the output (e.g. 10000 ns) but then lowered to a value that
> > > > is quantized to zero (e.g. 1000 ns), the output is disabled as the
> > > > device cannot drive a constant zero (as expected).
> > > >
> > > > However if the device is later re-initialized due to watchdog bite,
> > > > the output is re-enabled at the next-to-last duty cycle (10000 ns).
> > > > This is because the iqs620_pwm->out_en flag unconditionally tracks
> > > > state->enabled instead of what was actually written to the device.
> > > >
> > > > To solve this problem, force the iqs620_pwm->out_en flag to follow
> > > > the IQS620_PWR_SETTINGS_PWM_OUT field instead, as was the original
> > > > design intent.
> > > >
> > > > Fixes: 6f0841a8197b ("pwm: Add support for Azoteq IQS620A PWM generator")
> > > > Signed-off-by: Jeff LaBundy <jeff@labundy.com>
> > > > ---
> > > > drivers/pwm/pwm-iqs620a.c | 6 ++++--
> > > > 1 file changed, 4 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
> > > > index 5ede825..5eb8fa4 100644
> > > > --- a/drivers/pwm/pwm-iqs620a.c
> > > > +++ b/drivers/pwm/pwm-iqs620a.c
> > > > @@ -79,6 +79,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > > > IQS620_PWR_SETTINGS_PWM_OUT, 0);
> > > > if (ret)
> > > > goto err_mutex;
> > > > +
> > > > + iqs620_pwm->out_en = false;
> > > > }
> > > >
> > > > if (duty_scale) {
> > > > @@ -97,9 +99,9 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > > > IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
> > > > if (ret)
> > > > goto err_mutex;
> > > > - }
> > > >
> > > > - iqs620_pwm->out_en = state->enabled;
> > > > + iqs620_pwm->out_en = true;
> > > > + }
> > >
> > > I got the problem and I agree it needs fixing. Are you aware you change
> > > the semantic of out_en here and so the behaviour of .get_state()? IMHO
> > > the change is fine however, and unless I miss something this patch makes
> > > the comment in iqs620_pwm_get_state true.
> >
> > Agreed on all counts; in fact I saw this as an improvement because the
> > get_state callback now reflects the actual state of the hardware under
> > all circumstances.
> >
> > As you mention, the comment in iqs620_pwm_get_state() is fully correct
> > now too. Previously it was incorrect in this particular corner case.
>
> ok, I wondered if I missed something.
>
> > > Other than that I wonder if it would make more sense to track duty_scale
> > > in the driver struct instead of duty_val and out_en.
> >
> > You would still have to cache state->enabled because it's required for
> > decoding duty_scale at the time it was cached, so there is not much to
> > gain. I prefer this solution because the get_state callback is correct
> > across all cases now, and the change is small.
>
> Can't we cope for this by just doing
>
> if (!state->enabled)
> duty_scale = 0;
>
> ?
This is an excellent idea, and simplifies the driver significantly. I'll
send a v2 shortly.
>
> Best regards
> Uwe
>
> --
> Pengutronix e.K. | Uwe Kleine-König |
> Industrial Linux Solutions | https://www.pengutronix.de/ |
Kind regards,
Jeff LaBundy
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-01-19 2:56 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-01-15 5:00 [PATCH] pwm: iqs620a: Correct a stale state variable Jeff LaBundy
2021-01-15 7:45 ` Uwe Kleine-König
2021-01-18 4:30 ` Jeff LaBundy
2021-01-18 8:02 ` Uwe Kleine-König
2021-01-19 2:55 ` Jeff LaBundy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox