linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] Fix IRQ issue by setting IRQ_DISABLE_UNLAZY flag
@ 2023-04-14 10:27 Masahiro Honda
  2023-04-18 11:08 ` Nuno Sá
  0 siblings, 1 reply; 3+ messages in thread
From: Masahiro Honda @ 2023-04-14 10:27 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron
  Cc: linux-iio, linux-kernel, Masahiro Honda

The Sigma-Delta ADCs supported by this driver can use SDO as an interrupt
line to indicate the completion of a conversion. However, some devices
cannot properly detect the completion of a conversion by an interrupt.
This is for the reason mentioned in the following commit.

commit e9849777d0e2 ("genirq: Add flag to force mask in
                      disable_irq[_nosync]()")

A read operation is performed by an extra interrupt before the complete
conversion. This patch provides an option to fix the issue by setting
IRQ_DISABLE_UNLAZY flag.

Signed-off-by: Masahiro Honda <honda@mechatrax.com>
---
v2:
 - Rework commit message.
 - Add a new entry in the Kconfig.
 - Call irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY) when freeing the IRQ.
v1: https://lore.kernel.org/linux-iio/20230306044737.862-1-honda@mechatrax.com/

 drivers/iio/adc/Kconfig          | 14 ++++++++++++++
 drivers/iio/adc/ad_sigma_delta.c | 31 ++++++++++++++++++++++++++-----
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 45af2302b..78ab6e2d8 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -21,6 +21,20 @@ config AD_SIGMA_DELTA
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 
+if AD_SIGMA_DELTA
+
+config AD_SIGMA_DELTA_USE_LAZY_IRQ
+	bool "Use lazy IRQ for sigma-delta ADCs"
+	depends on AD_SIGMA_DELTA
+	default n
+	help
+	  Some interrupt controllers have data read problem with ADCs depends on
+	  AD_SIGMA_DELTA.
+	  Say yes here to avoid the problem at the cost of performance overhead.
+	  If unsure, say N (but it's safe to say "Y").
+
+endif # if AD_SIGMA_DELTA
+
 config AD4130
 	tristate "Analog Device AD4130 ADC Driver"
 	depends on SPI
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index d8570f620..b9eae1e80 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -565,6 +565,16 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig)
 }
 EXPORT_SYMBOL_NS_GPL(ad_sd_validate_trigger, IIO_AD_SIGMA_DELTA);
 
+static void ad_sd_free_irq(void *sd)
+{
+	struct ad_sigma_delta *sigma_delta = sd;
+
+#ifdef CONFIG_AD_SIGMA_DELTA_USE_LAZY_IRQ
+	irq_clear_status_flags(sigma_delta->spi->irq, IRQ_DISABLE_UNLAZY);
+#endif
+	free_irq(sigma_delta->spi->irq, sigma_delta);
+}
+
 static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_dev)
 {
 	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
@@ -584,11 +594,22 @@ static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_de
 	init_completion(&sigma_delta->completion);
 
 	sigma_delta->irq_dis = true;
-	ret = devm_request_irq(dev, sigma_delta->spi->irq,
-			       ad_sd_data_rdy_trig_poll,
-			       sigma_delta->info->irq_flags | IRQF_NO_AUTOEN,
-			       indio_dev->name,
-			       sigma_delta);
+#ifdef CONFIG_AD_SIGMA_DELTA_USE_LAZY_IRQ
+	irq_set_status_flags(sigma_delta->spi->irq, IRQ_DISABLE_UNLAZY);
+#endif
+	ret = request_irq(sigma_delta->spi->irq,
+			  ad_sd_data_rdy_trig_poll,
+			  sigma_delta->info->irq_flags | IRQF_NO_AUTOEN,
+			  indio_dev->name,
+			  sigma_delta);
+	if (ret) {
+#ifdef CONFIG_AD_SIGMA_DELTA_USE_LAZY_IRQ
+		irq_clear_status_flags(sigma_delta->spi->irq, IRQ_DISABLE_UNLAZY);
+#endif
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(dev, ad_sd_free_irq, sigma_delta);
 	if (ret)
 		return ret;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] Fix IRQ issue by setting IRQ_DISABLE_UNLAZY flag
  2023-04-14 10:27 [PATCH v2] Fix IRQ issue by setting IRQ_DISABLE_UNLAZY flag Masahiro Honda
@ 2023-04-18 11:08 ` Nuno Sá
  2023-04-19 11:58   ` Masahiro Honda
  0 siblings, 1 reply; 3+ messages in thread
From: Nuno Sá @ 2023-04-18 11:08 UTC (permalink / raw)
  To: Masahiro Honda, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron
  Cc: linux-iio, linux-kernel

On Fri, 2023-04-14 at 19:27 +0900, Masahiro Honda wrote:
> The Sigma-Delta ADCs supported by this driver can use SDO as an interrupt
> line to indicate the completion of a conversion. However, some devices
> cannot properly detect the completion of a conversion by an interrupt.
> This is for the reason mentioned in the following commit.
> 
> commit e9849777d0e2 ("genirq: Add flag to force mask in
>                       disable_irq[_nosync]()")
> 
> A read operation is performed by an extra interrupt before the complete
> conversion. This patch provides an option to fix the issue by setting
> IRQ_DISABLE_UNLAZY flag.
> 
> Signed-off-by: Masahiro Honda <honda@mechatrax.com>
> ---
> v2:
>  - Rework commit message.
>  - Add a new entry in the Kconfig.
>  - Call irq_clear_status_flags(irq, IRQ_DISABLE_UNLAZY) when freeing the IRQ.
> v1:
> https://lore.kernel.org/linux-iio/20230306044737.862-1-honda@mechatrax.com/
> 
>  drivers/iio/adc/Kconfig          | 14 ++++++++++++++
>  drivers/iio/adc/ad_sigma_delta.c | 31 ++++++++++++++++++++++++++-----
>  2 files changed, 40 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 45af2302b..78ab6e2d8 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -21,6 +21,20 @@ config AD_SIGMA_DELTA
>         select IIO_BUFFER
>         select IIO_TRIGGERED_BUFFER
>  
> +if AD_SIGMA_DELTA
> +
> +config AD_SIGMA_DELTA_USE_LAZY_IRQ
> +       bool "Use lazy IRQ for sigma-delta ADCs"
> +       depends on AD_SIGMA_DELTA
> +       default n
> +       help
> +         Some interrupt controllers have data read problem with ADCs depends
> on
> +         AD_SIGMA_DELTA.
> +         Say yes here to avoid the problem at the cost of performance
> overhead.
> +         If unsure, say N (but it's safe to say "Y").
> +
> +endif # if AD_SIGMA_DELTA
> +
>  config AD4130
>         tristate "Analog Device AD4130 ADC Driver"
>         depends on SPI
> diff --git a/drivers/iio/adc/ad_sigma_delta.c
> b/drivers/iio/adc/ad_sigma_delta.c
> index d8570f620..b9eae1e80 100644
> --- a/drivers/iio/adc/ad_sigma_delta.c
> +++ b/drivers/iio/adc/ad_sigma_delta.c
> @@ -565,6 +565,16 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev,
> struct iio_trigger *trig)
>  }
>  EXPORT_SYMBOL_NS_GPL(ad_sd_validate_trigger, IIO_AD_SIGMA_DELTA);
>  
> +static void ad_sd_free_irq(void *sd)
> +{
> +       struct ad_sigma_delta *sigma_delta = sd;
> +
> +#ifdef CONFIG_AD_SIGMA_DELTA_USE_LAZY_IRQ
> +       irq_clear_status_flags(sigma_delta->spi->irq, IRQ_DISABLE_UNLAZY);
> +#endif
> +       free_irq(sigma_delta->spi->irq, sigma_delta);
> +}
> +
>  static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev
> *indio_dev)
>  {
>         struct ad_sigma_delta *sigma_delta =
> iio_device_get_drvdata(indio_dev);
> @@ -584,11 +594,22 @@ static int devm_ad_sd_probe_trigger(struct device *dev,
> struct iio_dev *indio_de
>         init_completion(&sigma_delta->completion);
>  
>         sigma_delta->irq_dis = true;
> -       ret = devm_request_irq(dev, sigma_delta->spi->irq,
> -                              ad_sd_data_rdy_trig_poll,
> -                              sigma_delta->info->irq_flags | IRQF_NO_AUTOEN,
> -                              indio_dev->name,
> -                              sigma_delta);
> +#ifdef CONFIG_AD_SIGMA_DELTA_USE_LAZY_IRQ
> +       irq_set_status_flags(sigma_delta->spi->irq, IRQ_DISABLE_UNLAZY);
> +#endif
> +       ret = request_irq(sigma_delta->spi->irq,
> +                         ad_sd_data_rdy_trig_poll,
> +                         sigma_delta->info->irq_flags | IRQF_NO_AUTOEN,
> +                         indio_dev->name,
> +                         sigma_delta);
> +       if (ret) {
> +#ifdef CONFIG_AD_SIGMA_DELTA_USE_LAZY_IRQ
> +               irq_clear_status_flags(sigma_delta->spi->irq,
> IRQ_DISABLE_UNLAZY);

I'm not really keen with having the Kconfig option. I'm fairly convinced that
this might be a problem affecting all sigma delta ADCs and even if they aren't
affected, I do not think that setting this IRQ flag will do any arm (other than
less efficiency maybe).


If you really want to be on the safe side, we could add a new boolean to 'struct
ad_sigma_delta_info' that would be enabled for your device and when true, the
LAZY bit is set. Once we prove that all devices might be affected by this issue,
we could remove the boolean and make it a default setting.

- Nuno Sá

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] Fix IRQ issue by setting IRQ_DISABLE_UNLAZY flag
  2023-04-18 11:08 ` Nuno Sá
@ 2023-04-19 11:58   ` Masahiro Honda
  0 siblings, 0 replies; 3+ messages in thread
From: Masahiro Honda @ 2023-04-19 11:58 UTC (permalink / raw)
  To: Nuno Sá
  Cc: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	linux-iio, linux-kernel

Hi Nuno,

Thank you for your advice.

On Tue, Apr 18, 2023 at 8:06 PM Nuno Sá <noname.nuno@gmail.com> wrote:
>
> I'm not really keen with having the Kconfig option. I'm fairly convinced that
> this might be a problem affecting all sigma delta ADCs and even if they aren't
> affected, I do not think that setting this IRQ flag will do any arm (other than
> less efficiency maybe).
>
>
> If you really want to be on the safe side, we could add a new boolean to 'struct
> ad_sigma_delta_info' that would be enabled for your device and when true, the
> LAZY bit is set. Once we prove that all devices might be affected by this issue,
> we could remove the boolean and make it a default setting.
>
> - Nuno Sá

I understand. I'll only set and clear the IRQ flag.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-04-19 11:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-14 10:27 [PATCH v2] Fix IRQ issue by setting IRQ_DISABLE_UNLAZY flag Masahiro Honda
2023-04-18 11:08 ` Nuno Sá
2023-04-19 11:58   ` Masahiro Honda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).