Message ID | 20230403154800.215924-6-paul@crapouillou.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | iio: new DMABUF based API, v3 | expand |
On Mon, 3 Apr 2023 17:47:54 +0200 Paul Cercueil <paul@crapouillou.net> wrote: > Update the devm_iio_dmaengine_buffer_setup() function to support > specifying the buffer direction. > > Update the iio_dmaengine_buffer_submit() function to handle input > buffers as well as output buffers. > > Signed-off-by: Paul Cercueil <paul@crapouillou.net> > Reviewed-by: Alexandru Ardelean <ardeleanalex@gmail.com> Just one trivial question inline. Jonathan > diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c > index 5f85ba38e6f6..592d2aa9044c 100644 > --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c > +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c > @@ -64,14 +64,25 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, > struct dmaengine_buffer *dmaengine_buffer = > iio_buffer_to_dmaengine_buffer(&queue->buffer); > struct dma_async_tx_descriptor *desc; > + enum dma_transfer_direction dma_dir; > + size_t max_size; > dma_cookie_t cookie; > > - block->bytes_used = min(block->size, dmaengine_buffer->max_size); > - block->bytes_used = round_down(block->bytes_used, > - dmaengine_buffer->align); > + max_size = min(block->size, dmaengine_buffer->max_size); > + max_size = round_down(max_size, dmaengine_buffer->align); > + > + if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) { > + block->bytes_used = max_size; > + dma_dir = DMA_DEV_TO_MEM; > + } else { > + dma_dir = DMA_MEM_TO_DEV; > + } > + > + if (!block->bytes_used || block->bytes_used > max_size) > + return -EINVAL; Two paths to here. Either DIRECTION_IN in which we just set things up so conditions being checked are always fine (unless max_size == 0? Can that happen?), or !DIRECTION_IN. So why not move this into the else {} branch above? > > desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, > - block->phys_addr, block->bytes_used, DMA_DEV_TO_MEM, > + block->phys_addr, block->bytes_used, dma_dir, > DMA_PREP_INTERRUPT); > if (!desc) > return -ENOMEM;
diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index e8a8ea4140f1..d33574b5417a 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -114,7 +114,8 @@ static int adi_axi_adc_config_dma_buffer(struct device *dev, dma_name = "rx"; return devm_iio_dmaengine_buffer_setup(indio_dev->dev.parent, - indio_dev, dma_name); + indio_dev, dma_name, + IIO_BUFFER_DIRECTION_IN); } static int adi_axi_adc_read_raw(struct iio_dev *indio_dev, diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 5f85ba38e6f6..592d2aa9044c 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -64,14 +64,25 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, struct dmaengine_buffer *dmaengine_buffer = iio_buffer_to_dmaengine_buffer(&queue->buffer); struct dma_async_tx_descriptor *desc; + enum dma_transfer_direction dma_dir; + size_t max_size; dma_cookie_t cookie; - block->bytes_used = min(block->size, dmaengine_buffer->max_size); - block->bytes_used = round_down(block->bytes_used, - dmaengine_buffer->align); + max_size = min(block->size, dmaengine_buffer->max_size); + max_size = round_down(max_size, dmaengine_buffer->align); + + if (queue->buffer.direction == IIO_BUFFER_DIRECTION_IN) { + block->bytes_used = max_size; + dma_dir = DMA_DEV_TO_MEM; + } else { + dma_dir = DMA_MEM_TO_DEV; + } + + if (!block->bytes_used || block->bytes_used > max_size) + return -EINVAL; desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, - block->phys_addr, block->bytes_used, DMA_DEV_TO_MEM, + block->phys_addr, block->bytes_used, dma_dir, DMA_PREP_INTERRUPT); if (!desc) return -ENOMEM; @@ -275,7 +286,8 @@ static struct iio_buffer *devm_iio_dmaengine_buffer_alloc(struct device *dev, */ int devm_iio_dmaengine_buffer_setup(struct device *dev, struct iio_dev *indio_dev, - const char *channel) + const char *channel, + enum iio_buffer_direction dir) { struct iio_buffer *buffer; @@ -286,6 +298,8 @@ int devm_iio_dmaengine_buffer_setup(struct device *dev, indio_dev->modes |= INDIO_BUFFER_HARDWARE; + buffer->direction = dir; + return iio_device_attach_buffer(indio_dev, buffer); } EXPORT_SYMBOL_GPL(devm_iio_dmaengine_buffer_setup); diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h index 5c355be89814..538d0479cdd6 100644 --- a/include/linux/iio/buffer-dmaengine.h +++ b/include/linux/iio/buffer-dmaengine.h @@ -7,11 +7,14 @@ #ifndef __IIO_DMAENGINE_H__ #define __IIO_DMAENGINE_H__ +#include <linux/iio/buffer.h> + struct iio_dev; struct device; int devm_iio_dmaengine_buffer_setup(struct device *dev, struct iio_dev *indio_dev, - const char *channel); + const char *channel, + enum iio_buffer_direction dir); #endif