patch "iio: adc: stm32-adc: fix sleep in atomic context" added to staging-linus
Subsystems (3)
This is a note to let you know that I've just added the patch titled
iio: adc: stm32-adc: fix sleep in atomic context
to my staging git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
in the staging-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From e2042d2936dfc84e9c600fe9b9d0039ca0e54b7d Mon Sep 17 00:00:00 2001
From: Olivier Moysan <[email protected]>
Date: Mon, 9 Mar 2020 11:02:12 +0100
Subject: iio: adc: stm32-adc: fix sleep in atomic context
This commit fixes the following error:
"BUG: sleeping function called from invalid context at kernel/irq/chip.c"
In DMA mode suppress the trigger irq handler, and make the buffer transfers directly in DMA callback, instead.
--- drivers/iio/adc/stm32-adc.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-)
drivers/iio/adc/stm32-adc.c +28 -3
@@ -1418,8 +1418,30 @@ static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc)static void stm32_adc_dma_buffer_done (void *data) {struct iio_dev *indio_dev = data; +struct stm32_adc *adc =iio_priv (indio_dev); +int residue =stm32_adc_dma_residue (adc); + +/* +* 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). +*/ +dev_dbg (&indio_dev->dev,"%s bufi=%d\n" , __func__, adc->bufi); -iio_trigger_poll_chained (indio_dev->trig); +while (residue >= indio_dev->scan_bytes) { +u16 *buffer = (u16 *)&adc->rx_buf[adc->bufi]; + +iio_push_to_buffers (indio_dev, buffer); + + residue -= indio_dev->scan_bytes; + adc->bufi += indio_dev->scan_bytes; +if (adc->bufi >= adc->rx_buf_sz) + adc->bufi =0 ; + } }static int stm32_adc_dma_start (struct iio_dev *indio_dev)
@@ -1845,6 +1867,7 @@ static int stm32_adc_probe(struct platform_device *pdev) {struct iio_dev *indio_dev;struct device *dev = &pdev->dev; +irqreturn_t (*handler)(int irq,void *p) =NULL ;struct stm32_adc *adc;int ret;
@@ -1911,9 +1934,11 @@ static int stm32_adc_probe(struct platform_device *pdev)if (ret <0 )return ret; +if (!adc->dma_chan) + handler = &stm32_adc_trigger_handler; + ret =iio_triggered_buffer_setup (indio_dev, - &iio_pollfunc_store_time, - &stm32_adc_trigger_handler, + &iio_pollfunc_store_time, handler, &stm32_adc_buffer_setup_ops);if (ret) {dev_err (&pdev->dev,"buffer setup failed\n" );
Signature · 1 line
2.26.1