| From b1f44af2ea1ec518755b47779bf3bec50e75ff1e Mon Sep 17 00:00:00 2001 |
| From: Geert Uytterhoeven <geert+renesas@glider.be> |
| Date: Fri, 11 Jul 2014 17:56:22 +0200 |
| Subject: spi: sh-msiof: Use correct device for DMA mapping with IOMMU |
| |
| To function correctly in the presence of an IOMMU, the DMA buffers must be |
| mapped using the DMA channel's device instead of the MSIOF platform |
| device's device. |
| |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| Signed-off-by: Mark Brown <broonie@linaro.org> |
| (cherry picked from commit 5dabcf2f27ded864cf79204c4a3cca1516b66026) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/spi/spi-sh-msiof.c | 26 ++++++++++++++++---------- |
| 1 file changed, 16 insertions(+), 10 deletions(-) |
| |
| diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c |
| index 373de70baf08..2a4354dcd661 100644 |
| --- a/drivers/spi/spi-sh-msiof.c |
| +++ b/drivers/spi/spi-sh-msiof.c |
| @@ -638,8 +638,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, |
| |
| if (tx) { |
| ier_bits |= IER_TDREQE | IER_TDMAE; |
| - dma_sync_single_for_device(&p->pdev->dev, p->tx_dma_addr, len, |
| - DMA_TO_DEVICE); |
| + dma_sync_single_for_device(p->master->dma_tx->device->dev, |
| + p->tx_dma_addr, len, DMA_TO_DEVICE); |
| desc_tx = dmaengine_prep_slave_single(p->master->dma_tx, |
| p->tx_dma_addr, len, DMA_TO_DEVICE, |
| DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| @@ -717,7 +717,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, |
| } |
| |
| if (rx) |
| - dma_sync_single_for_cpu(&p->pdev->dev, p->rx_dma_addr, len, |
| + dma_sync_single_for_cpu(p->master->dma_rx->device->dev, |
| + p->rx_dma_addr, len, |
| DMA_FROM_DEVICE); |
| |
| return 0; |
| @@ -1003,6 +1004,7 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p) |
| const struct sh_msiof_spi_info *info = dev_get_platdata(dev); |
| const struct resource *res; |
| struct spi_master *master; |
| + struct device *tx_dev, *rx_dev; |
| |
| if (!info || !info->dma_tx_id || !info->dma_rx_id) |
| return 0; /* The driver assumes no error */ |
| @@ -1033,21 +1035,23 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p) |
| if (!p->rx_dma_page) |
| goto free_tx_page; |
| |
| - p->tx_dma_addr = dma_map_single(dev, p->tx_dma_page, PAGE_SIZE, |
| + tx_dev = master->dma_tx->device->dev; |
| + p->tx_dma_addr = dma_map_single(tx_dev, p->tx_dma_page, PAGE_SIZE, |
| DMA_TO_DEVICE); |
| - if (dma_mapping_error(dev, p->tx_dma_addr)) |
| + if (dma_mapping_error(tx_dev, p->tx_dma_addr)) |
| goto free_rx_page; |
| |
| - p->rx_dma_addr = dma_map_single(dev, p->rx_dma_page, PAGE_SIZE, |
| + rx_dev = master->dma_rx->device->dev; |
| + p->rx_dma_addr = dma_map_single(rx_dev, p->rx_dma_page, PAGE_SIZE, |
| DMA_FROM_DEVICE); |
| - if (dma_mapping_error(dev, p->rx_dma_addr)) |
| + if (dma_mapping_error(rx_dev, p->rx_dma_addr)) |
| goto unmap_tx_page; |
| |
| dev_info(dev, "DMA available"); |
| return 0; |
| |
| unmap_tx_page: |
| - dma_unmap_single(dev, p->tx_dma_addr, PAGE_SIZE, DMA_TO_DEVICE); |
| + dma_unmap_single(tx_dev, p->tx_dma_addr, PAGE_SIZE, DMA_TO_DEVICE); |
| free_rx_page: |
| free_page((unsigned long)p->rx_dma_page); |
| free_tx_page: |
| @@ -1069,8 +1073,10 @@ static void sh_msiof_release_dma(struct sh_msiof_spi_priv *p) |
| return; |
| |
| dev = &p->pdev->dev; |
| - dma_unmap_single(dev, p->rx_dma_addr, PAGE_SIZE, DMA_FROM_DEVICE); |
| - dma_unmap_single(dev, p->tx_dma_addr, PAGE_SIZE, DMA_TO_DEVICE); |
| + dma_unmap_single(master->dma_rx->device->dev, p->rx_dma_addr, |
| + PAGE_SIZE, DMA_FROM_DEVICE); |
| + dma_unmap_single(master->dma_tx->device->dev, p->tx_dma_addr, |
| + PAGE_SIZE, DMA_TO_DEVICE); |
| free_page((unsigned long)p->rx_dma_page); |
| free_page((unsigned long)p->tx_dma_page); |
| dma_release_channel(master->dma_rx); |
| -- |
| 2.1.2 |
| |