]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iio: adc: nxp-sar-adc: Fix DMA channel leak in trigger mode
authorFelix Gu <ustc.gu@gmail.com>
Sun, 22 Feb 2026 09:45:39 +0000 (17:45 +0800)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 22 Mar 2026 12:15:31 +0000 (12:15 +0000)
The DMA channel was requested in nxp_sar_adc_buffer_postenable() but
was only released in nxp_sar_adc_buffer_software_do_predisable().
This caused a DMA channel resource leak when operating in trigger mode.

Fix this by moving dma_request_chan() from
nxp_sar_adc_buffer_postenable() into
nxp_sar_adc_buffer_software_do_postenable(), ensuring the DMA channel
is only requested in software mode.

Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/nxp-sar-adc.c

index 9efa883c277d23583523059cd983e509a4dbb241..58103bf16affb4c35b81a161b2498586c07e3503 100644 (file)
@@ -718,6 +718,10 @@ static int nxp_sar_adc_buffer_software_do_postenable(struct iio_dev *indio_dev)
        struct nxp_sar_adc *info = iio_priv(indio_dev);
        int ret;
 
+       info->dma_chan = dma_request_chan(indio_dev->dev.parent, "rx");
+       if (IS_ERR(info->dma_chan))
+               return PTR_ERR(info->dma_chan);
+
        nxp_sar_adc_dma_channels_enable(info, *indio_dev->active_scan_mask);
 
        nxp_sar_adc_dma_cfg(info, true);
@@ -738,6 +742,7 @@ out_stop_cyclic_dma:
 out_dma_channels_disable:
        nxp_sar_adc_dma_cfg(info, false);
        nxp_sar_adc_dma_channels_disable(info, *indio_dev->active_scan_mask);
+       dma_release_channel(info->dma_chan);
 
        return ret;
 }
@@ -765,10 +770,6 @@ static int nxp_sar_adc_buffer_postenable(struct iio_dev *indio_dev)
        unsigned long channel;
        int ret;
 
-       info->dma_chan = dma_request_chan(indio_dev->dev.parent, "rx");
-       if (IS_ERR(info->dma_chan))
-               return PTR_ERR(info->dma_chan);
-
        info->channels_used = 0;
 
        /*