serial: sh-sci: Use correct device for DMA mapping with IOMMU

To function correctly in the presence of an IOMMU, the DMA buffers must
be managed using the DMA channel's device instead of the platform
device's device.

Make sure to free the DMA memory before releasing the channel, not
after.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Geert Uytterhoeven 2015-08-21 20:02:40 +02:00 committed by Greg Kroah-Hartman
parent b925802026
commit 8e14ba8f8b
1 changed files with 8 additions and 6 deletions

View File

@ -1370,9 +1370,9 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
s->chan_rx = NULL;
s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
dma_release_channel(chan);
dma_free_coherent(port->dev, s->buf_len_rx * 2,
dma_free_coherent(chan->device->dev, s->buf_len_rx * 2,
sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
dma_release_channel(chan);
if (enable_pio)
sci_start_rx(port);
}
@ -1523,7 +1523,7 @@ static void work_fn_tx(struct work_struct *work)
return;
}
dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE);
dma_sync_sg_for_device(chan->device->dev, sg, 1, DMA_TO_DEVICE);
spin_lock_irq(&port->lock);
s->desc_tx = desc;
@ -1705,7 +1705,8 @@ static void sci_request_dma(struct uart_port *port)
sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
UART_XMIT_SIZE,
(uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
nent = dma_map_sg(chan->device->dev, &s->sg_tx, 1,
DMA_TO_DEVICE);
if (!nent) {
dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
dma_release_channel(chan);
@ -1737,8 +1738,9 @@ static void sci_request_dma(struct uart_port *port)
s->chan_rx = chan;
s->buf_len_rx = 2 * max(16, (int)port->fifosize);
buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2,
&dma[0], GFP_KERNEL);
buf[0] = dma_alloc_coherent(chan->device->dev,
s->buf_len_rx * 2, &dma[0],
GFP_KERNEL);
if (!buf[0]) {
dev_warn(port->dev,