public inbox for linux-iio@vger.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Lorenzo Bianconi <lorenzo@kernel.org>
Cc: lorenzo.bianconi@redhat.com, linux-iio@vger.kernel.org,
	linus.walleij@linaro.org, denis.ciocca@st.com
Subject: Re: [PATCH v3] iio: common: st_sensors: fix possible infinite loop in st_sensors_irq_thread
Date: Sun, 13 Dec 2020 15:04:47 +0000	[thread overview]
Message-ID: <20201213150447.119eec7c@archlinux> (raw)
In-Reply-To: <c9ec69ed349e7200c779fd7a5bf04c1aaa2817aa.1607438132.git.lorenzo@kernel.org>

On Tue,  8 Dec 2020 15:36:40 +0100
Lorenzo Bianconi <lorenzo@kernel.org> wrote:

> Return a boolean value in st_sensors_new_samples_available routine in
> order to avoid an infinite loop in st_sensors_irq_thread if
> stat_drdy.addr is not defined or stat_drdy read fails
> 
> Fixes: 90efe05562921 ("iio: st_sensors: harden interrupt handling")
> Reported-by: Jonathan Cameron <jic23@kernel.org>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

One trivial inline. Note I'm looking for an Ack form Dennis on this one
as it may result in a some breakage if any devices are using
edge interrupts.

It's possible we would be better falling back to interrupt free support
in that case rather than failing to probe at all.
I think that would be best done by moving the check out to the
various per type drivers so we fail in the same fashion as no irq
provided + a warning.

thanks,

Jonathan


> ---
> Changes since v2:
> - return -EOPNOTSUPP if the drv requests edge IRQ and the sensor does not support
>   status register
> 
> Changes since v1:
> - return true if the sensor does not have stat_drdy register
> ---
>  .../common/st_sensors/st_sensors_trigger.c    | 31 ++++++++++---------
>  1 file changed, 17 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c
> index 0507283bd4c1..2dbd2646e44e 100644
> --- a/drivers/iio/common/st_sensors/st_sensors_trigger.c
> +++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c
> @@ -23,35 +23,31 @@
>   * @sdata: Sensor data.
>   *
>   * returns:
> - * 0 - no new samples available
> - * 1 - new samples available
> - * negative - error or unknown
> + * false - no new samples available or read error
> + * true - new samples available
>   */
> -static int st_sensors_new_samples_available(struct iio_dev *indio_dev,
> -					    struct st_sensor_data *sdata)
> +static bool st_sensors_new_samples_available(struct iio_dev *indio_dev,
> +					     struct st_sensor_data *sdata)
>  {
>  	int ret, status;
>  
>  	/* How would I know if I can't check it? */
>  	if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr)
> -		return -EINVAL;
> +		return true;
>  
>  	/* No scan mask, no interrupt */
>  	if (!indio_dev->active_scan_mask)
> -		return 0;
> +		return false;
>  
>  	ret = regmap_read(sdata->regmap,
>  			  sdata->sensor_settings->drdy_irq.stat_drdy.addr,
>  			  &status);
>  	if (ret < 0) {
>  		dev_err(sdata->dev, "error checking samples available\n");
> -		return ret;
> +		return false;
>  	}
>  
> -	if (status & sdata->sensor_settings->drdy_irq.stat_drdy.mask)
> -		return 1;
> -
> -	return 0;
> +	return !!(status & sdata->sensor_settings->drdy_irq.stat_drdy.mask);

No need for the !! as you can rely on type conversion to a boolean.

>  }
>  
>  /**
> @@ -180,9 +176,15 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
>  
>  	/* Tell the interrupt handler that we're dealing with edges */
>  	if (irq_trig == IRQF_TRIGGER_FALLING ||
> -	    irq_trig == IRQF_TRIGGER_RISING)
> +	    irq_trig == IRQF_TRIGGER_RISING) {
> +		if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) {
> +			dev_err(&indio_dev->dev,
> +				"edge IRQ not supported w/o stat register.\n");
> +			err = -EOPNOTSUPP;
> +			goto iio_trigger_free;
> +		}
>  		sdata->edge_irq = true;
> -	else
> +	} else {
>  		/*
>  		 * If we're not using edges (i.e. level interrupts) we
>  		 * just mask off the IRQ, handle one interrupt, then
> @@ -190,6 +192,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
>  		 * interrupt handler top half again and start over.
>  		 */
>  		irq_trig |= IRQF_ONESHOT;
> +	}
>  
>  	/*
>  	 * If the interrupt pin is Open Drain, by definition this


  parent reply	other threads:[~2020-12-13 15:05 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-08 14:36 [PATCH v3] iio: common: st_sensors: fix possible infinite loop in st_sensors_irq_thread Lorenzo Bianconi
2020-12-09 14:41 ` Andy Shevchenko
2020-12-09 14:42   ` Andy Shevchenko
2020-12-13 15:04 ` Jonathan Cameron [this message]
2020-12-13 19:23   ` Lorenzo Bianconi
2020-12-22 10:53     ` Lorenzo Bianconi
2020-12-30 12:08       ` Jonathan Cameron
2021-01-11  8:21         ` Lorenzo Bianconi
2021-01-11 13:10           ` Jonathan Cameron
2021-01-11 13:26             ` Lorenzo Bianconi

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=20201213150447.119eec7c@archlinux \
    --to=jic23@kernel.org \
    --cc=denis.ciocca@st.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=lorenzo.bianconi@redhat.com \
    --cc=lorenzo@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox