ipq806x: do not allocate coherent memory in dma engine hotpath
[openwrt/staging/florian.git] / target / linux / ipq806x / patches-4.9 / 0002-dmaengine-Add-ADM-driver.patch
index 212a90290526a3179c9d3dac6afd58cbe68b18f3..4ad025c9c7fb0dad64609dc788dbee4b3b6044fd 100644 (file)
@@ -49,7 +49,7 @@ Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
 +obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
 --- /dev/null
 +++ b/drivers/dma/qcom/qcom_adm.c
-@@ -0,0 +1,900 @@
+@@ -0,0 +1,914 @@
 +/*
 + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 + *
@@ -406,6 +406,7 @@ Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
 +      struct adm_device *adev = achan->adev;
 +      struct adm_async_desc *async_desc;
 +      struct scatterlist *sg;
++      dma_addr_t cple_addr;
 +      u32 i, burst;
 +      u32 single_count = 0, box_count = 0, crci = 0;
 +      void *desc;
@@ -454,7 +455,7 @@ Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
 +              }
 +      }
 +
-+      async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
++      async_desc = kzalloc(sizeof(*async_desc), GFP_ATOMIC);
 +      if (!async_desc)
 +              return ERR_PTR(-ENOMEM);
 +
@@ -467,13 +468,9 @@ Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
 +                              box_count * sizeof(struct adm_desc_hw_box) +
 +                              sizeof(*cple) + 2 * ADM_DESC_ALIGN;
 +
-+      async_desc->cpl = dma_alloc_writecombine(adev->dev, async_desc->dma_len,
-+                              &async_desc->dma_addr, GFP_NOWAIT);
-+
-+      if (!async_desc->cpl) {
-+              kfree(async_desc);
-+              return ERR_PTR(-ENOMEM);
-+      }
++      async_desc->cpl = kzalloc(async_desc->dma_len, GFP_ATOMIC);
++      if (!async_desc->cpl)
++              goto free;
 +
 +      async_desc->adev = adev;
 +
@@ -481,10 +478,6 @@ Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
 +      cple = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN);
 +      desc = PTR_ALIGN(cple + 1, ADM_DESC_ALIGN);
 +
-+      /* init cmd list */
-+      *cple = ADM_CPLE_LP;
-+      *cple |= (desc - async_desc->cpl + async_desc->dma_addr) >> 3;
-+
 +      for_each_sg(sgl, sg, sg_len, i) {
 +              async_desc->length += sg_dma_len(sg);
 +
@@ -496,7 +489,27 @@ Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
 +                                                         direction);
 +      }
 +
++      async_desc->dma_addr = dma_map_single(adev->dev, async_desc->cpl,
++                                            async_desc->dma_len,
++                                            DMA_TO_DEVICE);
++      if (dma_mapping_error(adev->dev, async_desc->dma_addr))
++              goto free;
++
++      cple_addr = async_desc->dma_addr + ((void *)cple - async_desc->cpl);
++
++      /* init cmd list */
++      dma_sync_single_for_cpu(adev->dev, cple_addr, sizeof(*cple),
++                              DMA_TO_DEVICE);
++      *cple = ADM_CPLE_LP;
++      *cple |= (async_desc->dma_addr + ADM_DESC_ALIGN) >> 3;
++      dma_sync_single_for_device(adev->dev, cple_addr, sizeof(*cple),
++                                 DMA_TO_DEVICE);
++
 +      return vchan_tx_prep(&achan->vc, &async_desc->vd, flags);
++
++free:
++      kfree(async_desc);
++      return ERR_PTR(-ENOMEM);
 +}
 +
 +/**
@@ -721,8 +734,9 @@ Signed-off-by: Thomas Pedersen <twp@codeaurora.org>
 +      struct adm_async_desc *async_desc = container_of(vd,
 +                      struct adm_async_desc, vd);
 +
-+      dma_free_writecombine(async_desc->adev->dev, async_desc->dma_len,
-+              async_desc->cpl, async_desc->dma_addr);
++      dma_unmap_single(async_desc->adev->dev, async_desc->dma_addr,
++                       async_desc->dma_len, DMA_TO_DEVICE);
++      kfree(async_desc->cpl);
 +      kfree(async_desc);
 +}
 +