From: Jonathan Cameron <jic23@kernel.org>
To: Olivier Moysan <olivier.moysan@st.com>
Cc: <knaack.h@gmx.de>, <lars@metafoo.de>, <pmeerw@pmeerw.net>,
<mcoquelin.stm32@gmail.com>, <alexandre.torgue@st.com>,
<fabrice.gasnier@st.com>, <linux-iio@vger.kernel.org>,
<linux-stm32@st-md-mailman.stormreply.com>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] iio: adc: stm32-dfsdm: fix sleep in atomic context
Date: Sun, 2 Feb 2020 14:08:23 +0000 [thread overview]
Message-ID: <20200202140823.531aad39@archlinux> (raw)
In-Reply-To: <20200121110256.12415-1-olivier.moysan@st.com>
On Tue, 21 Jan 2020 12:02:56 +0100
Olivier Moysan <olivier.moysan@st.com> wrote:
> This commit fixes the error message:
> "BUG: sleeping function called from invalid context at kernel/irq/chip.c"
> Suppress the trigger irq handler. Make the buffer transfers directly
> in DMA callback, instead.
> Push buffers without timestamps, as timestamps are not supported
> in DFSDM driver.
>
> Fixes: 11646e81d775 ("iio: adc: stm32-dfsdm: add support for buffer modes")
>
> Signed-off-by: Olivier Moysan <olivier.moysan@st.com>
Applied to the fixes-togreg branch of iio.git and marked for stable.
Thanks,
Jonathan
> ---
> There is the same issue on STM32 ADC driver.
> The solution for ADC driver has been already discussed in the thread
> https://lkml.org/lkml/2019/3/30/171
> The current patch for STM32 DFSDM driver, bypasses the IIO IRQ trigger
> handler, as proposed in this thread.
> ---
> drivers/iio/adc/stm32-dfsdm-adc.c | 43 +++++++------------------------
> 1 file changed, 10 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> index 2aad2cda6943..76a60d93fe23 100644
> --- a/drivers/iio/adc/stm32-dfsdm-adc.c
> +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> @@ -842,31 +842,6 @@ static inline void stm32_dfsdm_process_data(struct stm32_dfsdm_adc *adc,
> }
> }
>
> -static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p)
> -{
> - struct iio_poll_func *pf = p;
> - struct iio_dev *indio_dev = pf->indio_dev;
> - struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> - int available = stm32_dfsdm_adc_dma_residue(adc);
> -
> - while (available >= indio_dev->scan_bytes) {
> - s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi];
> -
> - stm32_dfsdm_process_data(adc, buffer);
> -
> - iio_push_to_buffers_with_timestamp(indio_dev, buffer,
> - pf->timestamp);
> - available -= indio_dev->scan_bytes;
> - adc->bufi += indio_dev->scan_bytes;
> - if (adc->bufi >= adc->buf_sz)
> - adc->bufi = 0;
> - }
> -
> - iio_trigger_notify_done(indio_dev->trig);
> -
> - return IRQ_HANDLED;
> -}
> -
> static void stm32_dfsdm_dma_buffer_done(void *data)
> {
> struct iio_dev *indio_dev = data;
> @@ -874,11 +849,6 @@ static void stm32_dfsdm_dma_buffer_done(void *data)
> int available = stm32_dfsdm_adc_dma_residue(adc);
> size_t old_pos;
>
> - if (indio_dev->currentmode & INDIO_BUFFER_TRIGGERED) {
> - iio_trigger_poll_chained(indio_dev->trig);
> - return;
> - }
> -
> /*
> * FIXME: In Kernel interface does not support cyclic DMA buffer,and
> * offers only an interface to push data samples per samples.
> @@ -906,7 +876,15 @@ static void stm32_dfsdm_dma_buffer_done(void *data)
> adc->bufi = 0;
> old_pos = 0;
> }
> - /* regular iio buffer without trigger */
> + /*
> + * In DMA mode the trigger services of IIO are not used
> + * (e.g. no call to iio_trigger_poll).
> + * Calling irq handler associated to the hardware trigger is not
> + * relevant as the conversions have already been done. Data
> + * transfers are performed directly in DMA callback instead.
> + * This implementation avoids to call trigger irq handler that
> + * may sleep, in an atomic context (DMA irq handler context).
> + */
> if (adc->dev_data->type == DFSDM_IIO)
> iio_push_to_buffers(indio_dev, buffer);
> }
> @@ -1536,8 +1514,7 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
> }
>
> ret = iio_triggered_buffer_setup(indio_dev,
> - &iio_pollfunc_store_time,
> - &stm32_dfsdm_adc_trigger_handler,
> + &iio_pollfunc_store_time, NULL,
> &stm32_dfsdm_buffer_setup_ops);
> if (ret) {
> stm32_dfsdm_dma_release(indio_dev);
WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron <jic23@kernel.org>
To: Olivier Moysan <olivier.moysan@st.com>
Cc: lars@metafoo.de, alexandre.torgue@st.com,
linux-iio@vger.kernel.org, pmeerw@pmeerw.net,
linux-kernel@vger.kernel.org, mcoquelin.stm32@gmail.com,
knaack.h@gmx.de, fabrice.gasnier@st.com,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] iio: adc: stm32-dfsdm: fix sleep in atomic context
Date: Sun, 2 Feb 2020 14:08:23 +0000 [thread overview]
Message-ID: <20200202140823.531aad39@archlinux> (raw)
In-Reply-To: <20200121110256.12415-1-olivier.moysan@st.com>
On Tue, 21 Jan 2020 12:02:56 +0100
Olivier Moysan <olivier.moysan@st.com> wrote:
> This commit fixes the error message:
> "BUG: sleeping function called from invalid context at kernel/irq/chip.c"
> Suppress the trigger irq handler. Make the buffer transfers directly
> in DMA callback, instead.
> Push buffers without timestamps, as timestamps are not supported
> in DFSDM driver.
>
> Fixes: 11646e81d775 ("iio: adc: stm32-dfsdm: add support for buffer modes")
>
> Signed-off-by: Olivier Moysan <olivier.moysan@st.com>
Applied to the fixes-togreg branch of iio.git and marked for stable.
Thanks,
Jonathan
> ---
> There is the same issue on STM32 ADC driver.
> The solution for ADC driver has been already discussed in the thread
> https://lkml.org/lkml/2019/3/30/171
> The current patch for STM32 DFSDM driver, bypasses the IIO IRQ trigger
> handler, as proposed in this thread.
> ---
> drivers/iio/adc/stm32-dfsdm-adc.c | 43 +++++++------------------------
> 1 file changed, 10 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> index 2aad2cda6943..76a60d93fe23 100644
> --- a/drivers/iio/adc/stm32-dfsdm-adc.c
> +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> @@ -842,31 +842,6 @@ static inline void stm32_dfsdm_process_data(struct stm32_dfsdm_adc *adc,
> }
> }
>
> -static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p)
> -{
> - struct iio_poll_func *pf = p;
> - struct iio_dev *indio_dev = pf->indio_dev;
> - struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> - int available = stm32_dfsdm_adc_dma_residue(adc);
> -
> - while (available >= indio_dev->scan_bytes) {
> - s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi];
> -
> - stm32_dfsdm_process_data(adc, buffer);
> -
> - iio_push_to_buffers_with_timestamp(indio_dev, buffer,
> - pf->timestamp);
> - available -= indio_dev->scan_bytes;
> - adc->bufi += indio_dev->scan_bytes;
> - if (adc->bufi >= adc->buf_sz)
> - adc->bufi = 0;
> - }
> -
> - iio_trigger_notify_done(indio_dev->trig);
> -
> - return IRQ_HANDLED;
> -}
> -
> static void stm32_dfsdm_dma_buffer_done(void *data)
> {
> struct iio_dev *indio_dev = data;
> @@ -874,11 +849,6 @@ static void stm32_dfsdm_dma_buffer_done(void *data)
> int available = stm32_dfsdm_adc_dma_residue(adc);
> size_t old_pos;
>
> - if (indio_dev->currentmode & INDIO_BUFFER_TRIGGERED) {
> - iio_trigger_poll_chained(indio_dev->trig);
> - return;
> - }
> -
> /*
> * FIXME: In Kernel interface does not support cyclic DMA buffer,and
> * offers only an interface to push data samples per samples.
> @@ -906,7 +876,15 @@ static void stm32_dfsdm_dma_buffer_done(void *data)
> adc->bufi = 0;
> old_pos = 0;
> }
> - /* regular iio buffer without trigger */
> + /*
> + * In DMA mode the trigger services of IIO are not used
> + * (e.g. no call to iio_trigger_poll).
> + * Calling irq handler associated to the hardware trigger is not
> + * relevant as the conversions have already been done. Data
> + * transfers are performed directly in DMA callback instead.
> + * This implementation avoids to call trigger irq handler that
> + * may sleep, in an atomic context (DMA irq handler context).
> + */
> if (adc->dev_data->type == DFSDM_IIO)
> iio_push_to_buffers(indio_dev, buffer);
> }
> @@ -1536,8 +1514,7 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
> }
>
> ret = iio_triggered_buffer_setup(indio_dev,
> - &iio_pollfunc_store_time,
> - &stm32_dfsdm_adc_trigger_handler,
> + &iio_pollfunc_store_time, NULL,
> &stm32_dfsdm_buffer_setup_ops);
> if (ret) {
> stm32_dfsdm_dma_release(indio_dev);
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-02-02 14:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-21 11:02 [PATCH] iio: adc: stm32-dfsdm: fix sleep in atomic context Olivier Moysan
2020-01-21 11:02 ` Olivier Moysan
2020-02-02 14:08 ` Jonathan Cameron [this message]
2020-02-02 14:08 ` Jonathan Cameron
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=20200202140823.531aad39@archlinux \
--to=jic23@kernel.org \
--cc=alexandre.torgue@st.com \
--cc=fabrice.gasnier@st.com \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=olivier.moysan@st.com \
--cc=pmeerw@pmeerw.net \
/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.