Skip to content

Commit a514bb1

Browse files
nunojsajic23
authored andcommitted
iio: buffer: support getting dma channel from the buffer
Add a new buffer accessor .get_dma_dev() in order to get the struct device responsible for actually providing the dma channel. We cannot assume that we can use the parent of the IIO device for mapping the DMA buffer. This becomes important on systems (like the Xilinx/AMD zynqMP Ultrascale) where memory (or part of it) is mapped above the 32 bit range. On such systems and given that a device by default has a dma mask of 32 bits we would then need to rely on bounce buffers (to swiotlb) for mapping memory above the dma mask limit. In the process, add an iio_buffer_get_dma_dev() helper function to get the proper DMA device. Cc: stable@vger.kernel.org Reviewed-by: David Lechner <dlechner@baylibre.com> Signed-off-by: Nuno Sá <nuno.sa@analog.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1 parent 0bf1bfd commit a514bb1

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

drivers/iio/industrialio-buffer.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,19 +1623,28 @@ static int iio_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock)
16231623
return 0;
16241624
}
16251625

1626+
static struct device *iio_buffer_get_dma_dev(const struct iio_dev *indio_dev,
1627+
struct iio_buffer *buffer)
1628+
{
1629+
if (buffer->access->get_dma_dev)
1630+
return buffer->access->get_dma_dev(buffer);
1631+
1632+
return indio_dev->dev.parent;
1633+
}
1634+
16261635
static struct dma_buf_attachment *
16271636
iio_buffer_find_attachment(struct iio_dev_buffer_pair *ib,
16281637
struct dma_buf *dmabuf, bool nonblock)
16291638
{
1630-
struct device *dev = ib->indio_dev->dev.parent;
16311639
struct iio_buffer *buffer = ib->buffer;
1640+
struct device *dma_dev = iio_buffer_get_dma_dev(ib->indio_dev, buffer);
16321641
struct dma_buf_attachment *attach = NULL;
16331642
struct iio_dmabuf_priv *priv;
16341643

16351644
guard(mutex)(&buffer->dmabufs_mutex);
16361645

16371646
list_for_each_entry(priv, &buffer->dmabufs, entry) {
1638-
if (priv->attach->dev == dev
1647+
if (priv->attach->dev == dma_dev
16391648
&& priv->attach->dmabuf == dmabuf) {
16401649
attach = priv->attach;
16411650
break;
@@ -1653,6 +1662,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
16531662
{
16541663
struct iio_dev *indio_dev = ib->indio_dev;
16551664
struct iio_buffer *buffer = ib->buffer;
1665+
struct device *dma_dev = iio_buffer_get_dma_dev(indio_dev, buffer);
16561666
struct dma_buf_attachment *attach;
16571667
struct iio_dmabuf_priv *priv, *each;
16581668
struct dma_buf *dmabuf;
@@ -1679,7 +1689,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
16791689
goto err_free_priv;
16801690
}
16811691

1682-
attach = dma_buf_attach(dmabuf, indio_dev->dev.parent);
1692+
attach = dma_buf_attach(dmabuf, dma_dev);
16831693
if (IS_ERR(attach)) {
16841694
err = PTR_ERR(attach);
16851695
goto err_dmabuf_put;
@@ -1719,7 +1729,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
17191729
* combo. If we do, refuse to attach.
17201730
*/
17211731
list_for_each_entry(each, &buffer->dmabufs, entry) {
1722-
if (each->attach->dev == indio_dev->dev.parent
1732+
if (each->attach->dev == dma_dev
17231733
&& each->attach->dmabuf == dmabuf) {
17241734
/*
17251735
* We unlocked the reservation object, so going through
@@ -1758,6 +1768,7 @@ static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib,
17581768
{
17591769
struct iio_buffer *buffer = ib->buffer;
17601770
struct iio_dev *indio_dev = ib->indio_dev;
1771+
struct device *dma_dev = iio_buffer_get_dma_dev(indio_dev, buffer);
17611772
struct iio_dmabuf_priv *priv;
17621773
struct dma_buf *dmabuf;
17631774
int dmabuf_fd, ret = -EPERM;
@@ -1772,7 +1783,7 @@ static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib,
17721783
guard(mutex)(&buffer->dmabufs_mutex);
17731784

17741785
list_for_each_entry(priv, &buffer->dmabufs, entry) {
1775-
if (priv->attach->dev == indio_dev->dev.parent
1786+
if (priv->attach->dev == dma_dev
17761787
&& priv->attach->dmabuf == dmabuf) {
17771788
list_del(&priv->entry);
17781789

include/linux/iio/buffer_impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct sg_table;
5050
* @enqueue_dmabuf: called from userspace via ioctl to queue this DMABUF
5151
* object to this buffer. Requires a valid DMABUF fd, that
5252
* was previouly attached to this buffer.
53+
* @get_dma_dev: called to get the DMA channel associated with this buffer.
5354
* @lock_queue: called when the core needs to lock the buffer queue;
5455
* it is used when enqueueing DMABUF objects.
5556
* @unlock_queue: used to unlock a previously locked buffer queue
@@ -90,6 +91,7 @@ struct iio_buffer_access_funcs {
9091
struct iio_dma_buffer_block *block,
9192
struct dma_fence *fence, struct sg_table *sgt,
9293
size_t size, bool cyclic);
94+
struct device * (*get_dma_dev)(struct iio_buffer *buffer);
9395
void (*lock_queue)(struct iio_buffer *buffer);
9496
void (*unlock_queue)(struct iio_buffer *buffer);
9597

0 commit comments

Comments
 (0)