All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding@gmail.com>
To: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>,
	Haavard Skinnemoen <hskinnemoen@gmail.com>,
	Hans-Christian Egtvedt <egtvedt@samfundet.no>,
	linux-pwm@vger.kernel.org, linux-sh@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-omap@vger.kernel.org,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] pwm: Fix period and polarity in pwm_get() for non-perfect matches
Date: Mon, 18 Aug 2014 10:20:40 +0200	[thread overview]
Message-ID: <20140818082039.GA31171@ulmo> (raw)
In-Reply-To: <1407943133-18170-1-git-send-email-geert+renesas@glider.be>

[-- Attachment #1: Type: text/plain, Size: 2767 bytes --]

On Wed, Aug 13, 2014 at 05:18:53PM +0200, Geert Uytterhoeven wrote:
> If pwm_get() finds a look-up entry with a perfect match (both dev_id and
> con_id match), the loop is aborted, and "p" still points to the correct
> struct pwm_lookup.
> 
> If only an entry with a matching dev_id or con_id is found, the loop
> terminates after traversing the whole list, and "p" now points to
> arbitrary memory, not part of the pwm_lookup list.
> Then pwm_set_period() and pwm_set_polarity() will set random values for
> period resp. polarity.
> 
> To fix this, save period and polarity when finding a new best match,
> just like is done for chip (for the provider) and index.
> 
> This fixes the LCD backlight on r8a7740/armadillo-legacy, which was fed
> period 0 and polarity -1068821144 instead of 33333 resp. 1.
> 
> Fixes: 3796ce1d4d4b330a75005c5eda105603ce9d4071 ("pwm: add period and polarity to struct pwm_lookup")
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: stable@vger.kernel.org
> ---
>  drivers/pwm/core.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)

Good catch! One comment below.

> diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
> index 4b66bf09ee55..d2c35920ff08 100644
> --- a/drivers/pwm/core.c
> +++ b/drivers/pwm/core.c
> @@ -606,6 +606,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  	unsigned int best = 0;
>  	struct pwm_lookup *p;
>  	unsigned int match;
> +	unsigned int period;
> +	enum pwm_polarity polarity;
>  
>  	/* look up via DT first */
>  	if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
> @@ -653,6 +655,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  		if (match > best) {
>  			chip = pwmchip_find_by_name(p->provider);
>  			index = p->index;
> +			period = p->period;
> +			polarity = p->polarity;
>  
>  			if (match != 3)
>  				best = match;
> @@ -668,8 +672,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  	if (IS_ERR(pwm))
>  		return pwm;
>  
> -	pwm_set_period(pwm, p->period);
> -	pwm_set_polarity(pwm, p->polarity);
> +	pwm_set_period(pwm, period);
> +	pwm_set_polarity(pwm, polarity);

Could we achieve the same by storing a pointer to the best match and
then use that instead of p? Perhaps something like this:

	struct pwm_lookup *entry;

	...

		if (match > best) {
			chip = pwmchip_find_by_name(p->provider);
			entry = p;

			if (match != 3)
				best = match;
			else
				break;
		}

	...

	if (chip)
		pwm = pwm_request_from_chip(chip, entry->index,
					    con_id ?: dev_id);
	if (IS_ERR(pwm))
		return pwm;

	pwm_set_period(pwm, entry->period);
	pwm_set_polarity(pwm, entry->polarity);

?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Thierry Reding <thierry.reding@gmail.com>
To: linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] pwm: Fix period and polarity in pwm_get() for non-perfect matches
Date: Mon, 18 Aug 2014 08:20:40 +0000	[thread overview]
Message-ID: <20140818082039.GA31171@ulmo> (raw)
In-Reply-To: <1407943133-18170-1-git-send-email-geert+renesas@glider.be>

[-- Attachment #1: Type: text/plain, Size: 2767 bytes --]

On Wed, Aug 13, 2014 at 05:18:53PM +0200, Geert Uytterhoeven wrote:
> If pwm_get() finds a look-up entry with a perfect match (both dev_id and
> con_id match), the loop is aborted, and "p" still points to the correct
> struct pwm_lookup.
> 
> If only an entry with a matching dev_id or con_id is found, the loop
> terminates after traversing the whole list, and "p" now points to
> arbitrary memory, not part of the pwm_lookup list.
> Then pwm_set_period() and pwm_set_polarity() will set random values for
> period resp. polarity.
> 
> To fix this, save period and polarity when finding a new best match,
> just like is done for chip (for the provider) and index.
> 
> This fixes the LCD backlight on r8a7740/armadillo-legacy, which was fed
> period 0 and polarity -1068821144 instead of 33333 resp. 1.
> 
> Fixes: 3796ce1d4d4b330a75005c5eda105603ce9d4071 ("pwm: add period and polarity to struct pwm_lookup")
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: stable@vger.kernel.org
> ---
>  drivers/pwm/core.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)

Good catch! One comment below.

> diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
> index 4b66bf09ee55..d2c35920ff08 100644
> --- a/drivers/pwm/core.c
> +++ b/drivers/pwm/core.c
> @@ -606,6 +606,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  	unsigned int best = 0;
>  	struct pwm_lookup *p;
>  	unsigned int match;
> +	unsigned int period;
> +	enum pwm_polarity polarity;
>  
>  	/* look up via DT first */
>  	if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
> @@ -653,6 +655,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  		if (match > best) {
>  			chip = pwmchip_find_by_name(p->provider);
>  			index = p->index;
> +			period = p->period;
> +			polarity = p->polarity;
>  
>  			if (match != 3)
>  				best = match;
> @@ -668,8 +672,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  	if (IS_ERR(pwm))
>  		return pwm;
>  
> -	pwm_set_period(pwm, p->period);
> -	pwm_set_polarity(pwm, p->polarity);
> +	pwm_set_period(pwm, period);
> +	pwm_set_polarity(pwm, polarity);

Could we achieve the same by storing a pointer to the best match and
then use that instead of p? Perhaps something like this:

	struct pwm_lookup *entry;

	...

		if (match > best) {
			chip = pwmchip_find_by_name(p->provider);
			entry = p;

			if (match != 3)
				best = match;
			else
				break;
		}

	...

	if (chip)
		pwm = pwm_request_from_chip(chip, entry->index,
					    con_id ?: dev_id);
	if (IS_ERR(pwm))
		return pwm;

	pwm_set_period(pwm, entry->period);
	pwm_set_polarity(pwm, entry->polarity);

?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: thierry.reding@gmail.com (Thierry Reding)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] pwm: Fix period and polarity in pwm_get() for non-perfect matches
Date: Mon, 18 Aug 2014 10:20:40 +0200	[thread overview]
Message-ID: <20140818082039.GA31171@ulmo> (raw)
In-Reply-To: <1407943133-18170-1-git-send-email-geert+renesas@glider.be>

On Wed, Aug 13, 2014 at 05:18:53PM +0200, Geert Uytterhoeven wrote:
> If pwm_get() finds a look-up entry with a perfect match (both dev_id and
> con_id match), the loop is aborted, and "p" still points to the correct
> struct pwm_lookup.
> 
> If only an entry with a matching dev_id or con_id is found, the loop
> terminates after traversing the whole list, and "p" now points to
> arbitrary memory, not part of the pwm_lookup list.
> Then pwm_set_period() and pwm_set_polarity() will set random values for
> period resp. polarity.
> 
> To fix this, save period and polarity when finding a new best match,
> just like is done for chip (for the provider) and index.
> 
> This fixes the LCD backlight on r8a7740/armadillo-legacy, which was fed
> period 0 and polarity -1068821144 instead of 33333 resp. 1.
> 
> Fixes: 3796ce1d4d4b330a75005c5eda105603ce9d4071 ("pwm: add period and polarity to struct pwm_lookup")
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: stable at vger.kernel.org
> ---
>  drivers/pwm/core.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)

Good catch! One comment below.

> diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
> index 4b66bf09ee55..d2c35920ff08 100644
> --- a/drivers/pwm/core.c
> +++ b/drivers/pwm/core.c
> @@ -606,6 +606,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  	unsigned int best = 0;
>  	struct pwm_lookup *p;
>  	unsigned int match;
> +	unsigned int period;
> +	enum pwm_polarity polarity;
>  
>  	/* look up via DT first */
>  	if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
> @@ -653,6 +655,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  		if (match > best) {
>  			chip = pwmchip_find_by_name(p->provider);
>  			index = p->index;
> +			period = p->period;
> +			polarity = p->polarity;
>  
>  			if (match != 3)
>  				best = match;
> @@ -668,8 +672,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
>  	if (IS_ERR(pwm))
>  		return pwm;
>  
> -	pwm_set_period(pwm, p->period);
> -	pwm_set_polarity(pwm, p->polarity);
> +	pwm_set_period(pwm, period);
> +	pwm_set_polarity(pwm, polarity);

Could we achieve the same by storing a pointer to the best match and
then use that instead of p? Perhaps something like this:

	struct pwm_lookup *entry;

	...

		if (match > best) {
			chip = pwmchip_find_by_name(p->provider);
			entry = p;

			if (match != 3)
				best = match;
			else
				break;
		}

	...

	if (chip)
		pwm = pwm_request_from_chip(chip, entry->index,
					    con_id ?: dev_id);
	if (IS_ERR(pwm))
		return pwm;

	pwm_set_period(pwm, entry->period);
	pwm_set_polarity(pwm, entry->polarity);

?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140818/34f48aa0/attachment.sig>

  reply	other threads:[~2014-08-18  8:20 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-13 15:18 [PATCH] pwm: Fix period and polarity in pwm_get() for non-perfect matches Geert Uytterhoeven
2014-08-13 15:18 ` Geert Uytterhoeven
2014-08-13 15:18 ` Geert Uytterhoeven
2014-08-18  8:20 ` Thierry Reding [this message]
2014-08-18  8:20   ` Thierry Reding
2014-08-18  8:20   ` Thierry Reding
2014-08-18  8:38   ` Geert Uytterhoeven
2014-08-18  8:38     ` Geert Uytterhoeven
2014-08-18  8:38     ` Geert Uytterhoeven
2014-08-18  8:57     ` Thierry Reding
2014-08-18  8:57       ` Thierry Reding
2014-08-18  8:57       ` Thierry Reding

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140818082039.GA31171@ulmo \
    --to=thierry.reding@gmail.com \
    --cc=alexandre.belloni@free-electrons.com \
    --cc=egtvedt@samfundet.no \
    --cc=geert+renesas@glider.be \
    --cc=hskinnemoen@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=linux-sh@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.