]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: ipu6: not override the dma_ops of device in driver
authorBingbu Cao <bingbu.cao@intel.com>
Wed, 16 Oct 2024 07:53:01 +0000 (15:53 +0800)
committerHans Verkuil <hverkuil@xs4all.nl>
Thu, 7 Nov 2024 08:05:56 +0000 (09:05 +0100)
DMA ops are a helper for architectures and not for drivers to override the
DMA implementation. Driver should not override the DMA implementation.

This patch removes the dma_ops override from auxiliary device and adds
driver-internal helpers that use the actual DMA mapping APIs.

Fixes: 9163d83573e4 ("media: intel/ipu6: add IPU6 DMA mapping API and MMU table")
Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
[Sakari Ailus: Fix the commit message a little.]
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
drivers/media/pci/intel/ipu6/ipu6-bus.c
drivers/media/pci/intel/ipu6/ipu6-buttress.c
drivers/media/pci/intel/ipu6/ipu6-cpd.c
drivers/media/pci/intel/ipu6/ipu6-dma.c
drivers/media/pci/intel/ipu6/ipu6-dma.h
drivers/media/pci/intel/ipu6/ipu6-fw-com.c

index 149ec098cdbfe1e67ca70b0fb9836ee164a05899..37d88ddb6ee7cda6340b6b591a376f8dc507c272 100644 (file)
@@ -94,8 +94,6 @@ ipu6_bus_initialize_device(struct pci_dev *pdev, struct device *parent,
        if (!adev)
                return ERR_PTR(-ENOMEM);
 
-       adev->dma_mask = DMA_BIT_MASK(isp->secure_mode ? IPU6_MMU_ADDR_BITS :
-                                     IPU6_MMU_ADDR_BITS_NON_SECURE);
        adev->isp = isp;
        adev->ctrl = ctrl;
        adev->pdata = pdata;
@@ -106,10 +104,6 @@ ipu6_bus_initialize_device(struct pci_dev *pdev, struct device *parent,
 
        auxdev->dev.parent = parent;
        auxdev->dev.release = ipu6_bus_release;
-       auxdev->dev.dma_ops = &ipu6_dma_ops;
-       auxdev->dev.dma_mask = &adev->dma_mask;
-       auxdev->dev.dma_parms = pdev->dev.dma_parms;
-       auxdev->dev.coherent_dma_mask = adev->dma_mask;
 
        ret = auxiliary_device_init(auxdev);
        if (ret < 0) {
index e47f84c30e10d6ebe38e75d2939078d54147372b..d66db537be4a6678227e2867e53aeaba8b46c9b2 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "ipu6.h"
 #include "ipu6-bus.h"
+#include "ipu6-dma.h"
 #include "ipu6-buttress.h"
 #include "ipu6-platform-buttress-regs.h"
 
@@ -553,6 +554,7 @@ int ipu6_buttress_map_fw_image(struct ipu6_bus_device *sys,
                               const struct firmware *fw, struct sg_table *sgt)
 {
        bool is_vmalloc = is_vmalloc_addr(fw->data);
+       struct pci_dev *pdev = sys->isp->pdev;
        struct page **pages;
        const void *addr;
        unsigned long n_pages;
@@ -588,14 +590,20 @@ int ipu6_buttress_map_fw_image(struct ipu6_bus_device *sys,
                goto out;
        }
 
-       ret = dma_map_sgtable(&sys->auxdev.dev, sgt, DMA_TO_DEVICE, 0);
-       if (ret < 0) {
-               ret = -ENOMEM;
+       ret = dma_map_sgtable(&pdev->dev, sgt, DMA_TO_DEVICE, 0);
+       if (ret) {
+               sg_free_table(sgt);
+               goto out;
+       }
+
+       ret = ipu6_dma_map_sgtable(sys, sgt, DMA_TO_DEVICE, 0);
+       if (ret) {
+               dma_unmap_sgtable(&pdev->dev, sgt, DMA_TO_DEVICE, 0);
                sg_free_table(sgt);
                goto out;
        }
 
-       dma_sync_sgtable_for_device(&sys->auxdev.dev, sgt, DMA_TO_DEVICE);
+       ipu6_dma_sync_sgtable(sys, sgt);
 
 out:
        kfree(pages);
@@ -607,7 +615,10 @@ EXPORT_SYMBOL_NS_GPL(ipu6_buttress_map_fw_image, INTEL_IPU6);
 void ipu6_buttress_unmap_fw_image(struct ipu6_bus_device *sys,
                                  struct sg_table *sgt)
 {
-       dma_unmap_sgtable(&sys->auxdev.dev, sgt, DMA_TO_DEVICE, 0);
+       struct pci_dev *pdev = sys->isp->pdev;
+
+       ipu6_dma_unmap_sgtable(sys, sgt, DMA_TO_DEVICE, 0);
+       dma_unmap_sgtable(&pdev->dev, sgt, DMA_TO_DEVICE, 0);
        sg_free_table(sgt);
 }
 EXPORT_SYMBOL_NS_GPL(ipu6_buttress_unmap_fw_image, INTEL_IPU6);
index 9b46b91cfc1acc6fcb84755c54a2dd7bf71b5bc4..55ffd988ae4f1c1ab5b431ddb3593792971ce18d 100644 (file)
@@ -15,6 +15,7 @@
 #include "ipu6.h"
 #include "ipu6-bus.h"
 #include "ipu6-cpd.h"
+#include "ipu6-dma.h"
 
 /* 15 entries + header*/
 #define MAX_PKG_DIR_ENT_CNT            16
@@ -162,7 +163,6 @@ int ipu6_cpd_create_pkg_dir(struct ipu6_bus_device *adev, const void *src)
 {
        dma_addr_t dma_addr_src = sg_dma_address(adev->fw_sgt.sgl);
        const struct ipu6_cpd_ent *ent, *man_ent, *met_ent;
-       struct device *dev = &adev->auxdev.dev;
        struct ipu6_device *isp = adev->isp;
        unsigned int man_sz, met_sz;
        void *pkg_dir_pos;
@@ -175,8 +175,8 @@ int ipu6_cpd_create_pkg_dir(struct ipu6_bus_device *adev, const void *src)
        met_sz = met_ent->len;
 
        adev->pkg_dir_size = PKG_DIR_SIZE + man_sz + met_sz;
-       adev->pkg_dir = dma_alloc_attrs(dev, adev->pkg_dir_size,
-                                       &adev->pkg_dir_dma_addr, GFP_KERNEL, 0);
+       adev->pkg_dir = ipu6_dma_alloc(adev, adev->pkg_dir_size,
+                                      &adev->pkg_dir_dma_addr, GFP_KERNEL, 0);
        if (!adev->pkg_dir)
                return -ENOMEM;
 
@@ -198,8 +198,8 @@ int ipu6_cpd_create_pkg_dir(struct ipu6_bus_device *adev, const void *src)
                                         met_ent->len);
        if (ret) {
                dev_err(&isp->pdev->dev, "Failed to parse module data\n");
-               dma_free_attrs(dev, adev->pkg_dir_size,
-                              adev->pkg_dir, adev->pkg_dir_dma_addr, 0);
+               ipu6_dma_free(adev, adev->pkg_dir_size,
+                             adev->pkg_dir, adev->pkg_dir_dma_addr, 0);
                return ret;
        }
 
@@ -211,8 +211,8 @@ int ipu6_cpd_create_pkg_dir(struct ipu6_bus_device *adev, const void *src)
        pkg_dir_pos += man_sz;
        memcpy(pkg_dir_pos, src + met_ent->offset, met_sz);
 
-       dma_sync_single_range_for_device(dev, adev->pkg_dir_dma_addr,
-                                        0, adev->pkg_dir_size, DMA_TO_DEVICE);
+       ipu6_dma_sync_single(adev, adev->pkg_dir_dma_addr,
+                            adev->pkg_dir_size);
 
        return 0;
 }
@@ -220,8 +220,8 @@ EXPORT_SYMBOL_NS_GPL(ipu6_cpd_create_pkg_dir, INTEL_IPU6);
 
 void ipu6_cpd_free_pkg_dir(struct ipu6_bus_device *adev)
 {
-       dma_free_attrs(&adev->auxdev.dev, adev->pkg_dir_size, adev->pkg_dir,
-                      adev->pkg_dir_dma_addr, 0);
+       ipu6_dma_free(adev, adev->pkg_dir_size, adev->pkg_dir,
+                     adev->pkg_dir_dma_addr, 0);
 }
 EXPORT_SYMBOL_NS_GPL(ipu6_cpd_free_pkg_dir, INTEL_IPU6);
 
index 801f6bd00a89149f9e6f11cef6207213e886364e..b71f66bd8c1fdbaf0d2c2ce2c833e3fe1fa02e2b 100644 (file)
@@ -39,8 +39,7 @@ static struct vm_info *get_vm_info(struct ipu6_mmu *mmu, dma_addr_t iova)
        return NULL;
 }
 
-static void __dma_clear_buffer(struct page *page, size_t size,
-                              unsigned long attrs)
+static void __clear_buffer(struct page *page, size_t size, unsigned long attrs)
 {
        void *ptr;
 
@@ -56,8 +55,7 @@ static void __dma_clear_buffer(struct page *page, size_t size,
                clflush_cache_range(ptr, size);
 }
 
-static struct page **__dma_alloc_buffer(struct device *dev, size_t size,
-                                       gfp_t gfp, unsigned long attrs)
+static struct page **__alloc_buffer(size_t size, gfp_t gfp, unsigned long attrs)
 {
        int count = PHYS_PFN(size);
        int array_size = count * sizeof(struct page *);
@@ -86,7 +84,7 @@ static struct page **__dma_alloc_buffer(struct device *dev, size_t size,
                                pages[i + j] = pages[i] + j;
                }
 
-               __dma_clear_buffer(pages[i], PAGE_SIZE << order, attrs);
+               __clear_buffer(pages[i], PAGE_SIZE << order, attrs);
                i += 1 << order;
                count -= 1 << order;
        }
@@ -100,29 +98,26 @@ error:
        return NULL;
 }
 
-static void __dma_free_buffer(struct device *dev, struct page **pages,
-                             size_t size, unsigned long attrs)
+static void __free_buffer(struct page **pages, size_t size, unsigned long attrs)
 {
        int count = PHYS_PFN(size);
        unsigned int i;
 
        for (i = 0; i < count && pages[i]; i++) {
-               __dma_clear_buffer(pages[i], PAGE_SIZE, attrs);
+               __clear_buffer(pages[i], PAGE_SIZE, attrs);
                __free_pages(pages[i], 0);
        }
 
        kvfree(pages);
 }
 
-static void ipu6_dma_sync_single_for_cpu(struct device *dev,
-                                        dma_addr_t dma_handle,
-                                        size_t size,
-                                        enum dma_data_direction dir)
+void ipu6_dma_sync_single(struct ipu6_bus_device *sys, dma_addr_t dma_handle,
+                         size_t size)
 {
        void *vaddr;
        u32 offset;
        struct vm_info *info;
-       struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
+       struct ipu6_mmu *mmu = sys->mmu;
 
        info = get_vm_info(mmu, dma_handle);
        if (WARN_ON(!info))
@@ -135,10 +130,10 @@ static void ipu6_dma_sync_single_for_cpu(struct device *dev,
        vaddr = info->vaddr + offset;
        clflush_cache_range(vaddr, size);
 }
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_single, INTEL_IPU6);
 
-static void ipu6_dma_sync_sg_for_cpu(struct device *dev,
-                                    struct scatterlist *sglist,
-                                    int nents, enum dma_data_direction dir)
+void ipu6_dma_sync_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist,
+                     int nents)
 {
        struct scatterlist *sg;
        int i;
@@ -146,14 +141,22 @@ static void ipu6_dma_sync_sg_for_cpu(struct device *dev,
        for_each_sg(sglist, sg, nents, i)
                clflush_cache_range(page_to_virt(sg_page(sg)), sg->length);
 }
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_sg, INTEL_IPU6);
 
-static void *ipu6_dma_alloc(struct device *dev, size_t size,
-                           dma_addr_t *dma_handle, gfp_t gfp,
-                           unsigned long attrs)
+void ipu6_dma_sync_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt)
 {
-       struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
-       struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
+       ipu6_dma_sync_sg(sys, sgt->sgl, sgt->orig_nents);
+}
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_sync_sgtable, INTEL_IPU6);
+
+void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size,
+                    dma_addr_t *dma_handle, gfp_t gfp,
+                    unsigned long attrs)
+{
+       struct device *dev = &sys->auxdev.dev;
+       struct pci_dev *pdev = sys->isp->pdev;
        dma_addr_t pci_dma_addr, ipu6_iova;
+       struct ipu6_mmu *mmu = sys->mmu;
        struct vm_info *info;
        unsigned long count;
        struct page **pages;
@@ -173,7 +176,7 @@ static void *ipu6_dma_alloc(struct device *dev, size_t size,
        if (!iova)
                goto out_kfree;
 
-       pages = __dma_alloc_buffer(dev, size, gfp, attrs);
+       pages = __alloc_buffer(size, gfp, attrs);
        if (!pages)
                goto out_free_iova;
 
@@ -227,7 +230,7 @@ out_unmap:
                ipu6_mmu_unmap(mmu->dmap->mmu_info, ipu6_iova, PAGE_SIZE);
        }
 
-       __dma_free_buffer(dev, pages, size, attrs);
+       __free_buffer(pages, size, attrs);
 
 out_free_iova:
        __free_iova(&mmu->dmap->iovad, iova);
@@ -236,13 +239,13 @@ out_kfree:
 
        return NULL;
 }
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_alloc, INTEL_IPU6);
 
-static void ipu6_dma_free(struct device *dev, size_t size, void *vaddr,
-                         dma_addr_t dma_handle,
-                         unsigned long attrs)
+void ipu6_dma_free(struct ipu6_bus_device *sys, size_t size, void *vaddr,
+                  dma_addr_t dma_handle, unsigned long attrs)
 {
-       struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
-       struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
+       struct ipu6_mmu *mmu = sys->mmu;
+       struct pci_dev *pdev = sys->isp->pdev;
        struct iova *iova = find_iova(&mmu->dmap->iovad, PHYS_PFN(dma_handle));
        dma_addr_t pci_dma_addr, ipu6_iova;
        struct vm_info *info;
@@ -281,7 +284,7 @@ static void ipu6_dma_free(struct device *dev, size_t size, void *vaddr,
        ipu6_mmu_unmap(mmu->dmap->mmu_info, PFN_PHYS(iova->pfn_lo),
                       PFN_PHYS(iova_size(iova)));
 
-       __dma_free_buffer(dev, pages, size, attrs);
+       __free_buffer(pages, size, attrs);
 
        mmu->tlb_invalidate(mmu);
 
@@ -289,13 +292,14 @@ static void ipu6_dma_free(struct device *dev, size_t size, void *vaddr,
 
        kfree(info);
 }
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_free, INTEL_IPU6);
 
-static int ipu6_dma_mmap(struct device *dev, struct vm_area_struct *vma,
-                        void *addr, dma_addr_t iova, size_t size,
-                        unsigned long attrs)
+int ipu6_dma_mmap(struct ipu6_bus_device *sys, struct vm_area_struct *vma,
+                 void *addr, dma_addr_t iova, size_t size,
+                 unsigned long attrs)
 {
-       struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
-       size_t count = PHYS_PFN(PAGE_ALIGN(size));
+       struct ipu6_mmu *mmu = sys->mmu;
+       size_t count = PFN_UP(size);
        struct vm_info *info;
        size_t i;
        int ret;
@@ -323,18 +327,17 @@ static int ipu6_dma_mmap(struct device *dev, struct vm_area_struct *vma,
        return 0;
 }
 
-static void ipu6_dma_unmap_sg(struct device *dev,
-                             struct scatterlist *sglist,
-                             int nents, enum dma_data_direction dir,
-                             unsigned long attrs)
+void ipu6_dma_unmap_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist,
+                      int nents, enum dma_data_direction dir,
+                      unsigned long attrs)
 {
-       struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
-       struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
+       struct device *dev = &sys->auxdev.dev;
+       struct ipu6_mmu *mmu = sys->mmu;
        struct iova *iova = find_iova(&mmu->dmap->iovad,
                                      PHYS_PFN(sg_dma_address(sglist)));
-       int i, npages, count;
        struct scatterlist *sg;
        dma_addr_t pci_dma_addr;
+       unsigned int i;
 
        if (!nents)
                return;
@@ -342,31 +345,15 @@ static void ipu6_dma_unmap_sg(struct device *dev,
        if (WARN_ON(!iova))
                return;
 
-       if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
-               ipu6_dma_sync_sg_for_cpu(dev, sglist, nents, DMA_BIDIRECTIONAL);
-
-       /* get the nents as orig_nents given by caller */
-       count = 0;
-       npages = iova_size(iova);
-       for_each_sg(sglist, sg, nents, i) {
-               if (sg_dma_len(sg) == 0 ||
-                   sg_dma_address(sg) == DMA_MAPPING_ERROR)
-                       break;
-
-               npages -= PHYS_PFN(PAGE_ALIGN(sg_dma_len(sg)));
-               count++;
-               if (npages <= 0)
-                       break;
-       }
-
        /*
         * Before IPU6 mmu unmap, return the pci dma address back to sg
         * assume the nents is less than orig_nents as the least granule
         * is 1 SZ_4K page
         */
-       dev_dbg(dev, "trying to unmap concatenated %u ents\n", count);
-       for_each_sg(sglist, sg, count, i) {
-               dev_dbg(dev, "ipu unmap sg[%d] %pad\n", i, &sg_dma_address(sg));
+       dev_dbg(dev, "trying to unmap concatenated %u ents\n", nents);
+       for_each_sg(sglist, sg, nents, i) {
+               dev_dbg(dev, "unmap sg[%d] %pad size %u\n", i,
+                       &sg_dma_address(sg), sg_dma_len(sg));
                pci_dma_addr = ipu6_mmu_iova_to_phys(mmu->dmap->mmu_info,
                                                     sg_dma_address(sg));
                dev_dbg(dev, "return pci_dma_addr %pad back to sg[%d]\n",
@@ -380,23 +367,21 @@ static void ipu6_dma_unmap_sg(struct device *dev,
                       PFN_PHYS(iova_size(iova)));
 
        mmu->tlb_invalidate(mmu);
-
-       dma_unmap_sg_attrs(&pdev->dev, sglist, nents, dir, attrs);
-
        __free_iova(&mmu->dmap->iovad, iova);
 }
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_unmap_sg, INTEL_IPU6);
 
-static int ipu6_dma_map_sg(struct device *dev, struct scatterlist *sglist,
-                          int nents, enum dma_data_direction dir,
-                          unsigned long attrs)
+int ipu6_dma_map_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist,
+                   int nents, enum dma_data_direction dir,
+                   unsigned long attrs)
 {
-       struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
-       struct pci_dev *pdev = to_ipu6_bus_device(dev)->isp->pdev;
+       struct device *dev = &sys->auxdev.dev;
+       struct ipu6_mmu *mmu = sys->mmu;
        struct scatterlist *sg;
        struct iova *iova;
        size_t npages = 0;
        unsigned long iova_addr;
-       int i, count;
+       int i;
 
        for_each_sg(sglist, sg, nents, i) {
                if (sg->offset) {
@@ -406,18 +391,12 @@ static int ipu6_dma_map_sg(struct device *dev, struct scatterlist *sglist,
                }
        }
 
-       dev_dbg(dev, "pci_dma_map_sg trying to map %d ents\n", nents);
-       count  = dma_map_sg_attrs(&pdev->dev, sglist, nents, dir, attrs);
-       if (count <= 0) {
-               dev_err(dev, "pci_dma_map_sg %d ents failed\n", nents);
-               return 0;
-       }
-
-       dev_dbg(dev, "pci_dma_map_sg %d ents mapped\n", count);
-
-       for_each_sg(sglist, sg, count, i)
+       for_each_sg(sglist, sg, nents, i)
                npages += PHYS_PFN(PAGE_ALIGN(sg_dma_len(sg)));
 
+       dev_dbg(dev, "dmamap trying to map %d ents %zu pages\n",
+               nents, npages);
+
        iova = alloc_iova(&mmu->dmap->iovad, npages,
                          PHYS_PFN(dma_get_mask(dev)), 0);
        if (!iova)
@@ -427,7 +406,7 @@ static int ipu6_dma_map_sg(struct device *dev, struct scatterlist *sglist,
                iova->pfn_hi);
 
        iova_addr = iova->pfn_lo;
-       for_each_sg(sglist, sg, count, i) {
+       for_each_sg(sglist, sg, nents, i) {
                phys_addr_t iova_pa;
                int ret;
 
@@ -446,25 +425,48 @@ static int ipu6_dma_map_sg(struct device *dev, struct scatterlist *sglist,
                iova_addr += PHYS_PFN(PAGE_ALIGN(sg_dma_len(sg)));
        }
 
-       if ((attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
-               ipu6_dma_sync_sg_for_cpu(dev, sglist, nents, DMA_BIDIRECTIONAL);
+       dev_dbg(dev, "dmamap %d ents %zu pages mapped\n", nents, npages);
 
-       return count;
+       return nents;
 
 out_fail:
-       ipu6_dma_unmap_sg(dev, sglist, i, dir, attrs);
+       ipu6_dma_unmap_sg(sys, sglist, i, dir, attrs);
 
        return 0;
 }
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_map_sg, INTEL_IPU6);
+
+int ipu6_dma_map_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt,
+                        enum dma_data_direction dir, unsigned long attrs)
+{
+       int nents;
+
+       nents = ipu6_dma_map_sg(sys, sgt->sgl, sgt->nents, dir, attrs);
+       if (nents < 0)
+               return nents;
+
+       sgt->nents = nents;
+
+       return 0;
+}
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_map_sgtable, INTEL_IPU6);
+
+void ipu6_dma_unmap_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt,
+                           enum dma_data_direction dir, unsigned long attrs)
+{
+       ipu6_dma_unmap_sg(sys, sgt->sgl, sgt->nents, dir, attrs);
+}
+EXPORT_SYMBOL_NS_GPL(ipu6_dma_unmap_sgtable, INTEL_IPU6);
 
 /*
  * Create scatter-list for the already allocated DMA buffer
  */
-static int ipu6_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
-                               void *cpu_addr, dma_addr_t handle, size_t size,
-                               unsigned long attrs)
+int ipu6_dma_get_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt,
+                        void *cpu_addr, dma_addr_t handle, size_t size,
+                        unsigned long attrs)
 {
-       struct ipu6_mmu *mmu = to_ipu6_bus_device(dev)->mmu;
+       struct device *dev = &sys->auxdev.dev;
+       struct ipu6_mmu *mmu = sys->mmu;
        struct vm_info *info;
        int n_pages;
        int ret = 0;
@@ -484,20 +486,7 @@ static int ipu6_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
        ret = sg_alloc_table_from_pages(sgt, info->pages, n_pages, 0, size,
                                        GFP_KERNEL);
        if (ret)
-               dev_warn(dev, "IPU6 get sgt table failed\n");
+               dev_warn(dev, "get sgt table failed\n");
 
        return ret;
 }
-
-const struct dma_map_ops ipu6_dma_ops = {
-       .alloc = ipu6_dma_alloc,
-       .free = ipu6_dma_free,
-       .mmap = ipu6_dma_mmap,
-       .map_sg = ipu6_dma_map_sg,
-       .unmap_sg = ipu6_dma_unmap_sg,
-       .sync_single_for_cpu = ipu6_dma_sync_single_for_cpu,
-       .sync_single_for_device = ipu6_dma_sync_single_for_cpu,
-       .sync_sg_for_cpu = ipu6_dma_sync_sg_for_cpu,
-       .sync_sg_for_device = ipu6_dma_sync_sg_for_cpu,
-       .get_sgtable = ipu6_dma_get_sgtable,
-};
index 847ea5b7c925c39e025666b416dfcc85bcd526a7..b51244add9e611d1e3e5fc982c2381948340a530 100644 (file)
@@ -5,7 +5,13 @@
 #define IPU6_DMA_H
 
 #include <linux/dma-map-ops.h>
+#include <linux/dma-mapping.h>
 #include <linux/iova.h>
+#include <linux/iova.h>
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+
+#include "ipu6-bus.h"
 
 struct ipu6_mmu_info;
 
@@ -14,6 +20,30 @@ struct ipu6_dma_mapping {
        struct iova_domain iovad;
 };
 
-extern const struct dma_map_ops ipu6_dma_ops;
-
+void ipu6_dma_sync_single(struct ipu6_bus_device *sys, dma_addr_t dma_handle,
+                         size_t size);
+void ipu6_dma_sync_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist,
+                     int nents);
+void ipu6_dma_sync_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt);
+void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size,
+                    dma_addr_t *dma_handle, gfp_t gfp,
+                    unsigned long attrs);
+void ipu6_dma_free(struct ipu6_bus_device *sys, size_t size, void *vaddr,
+                  dma_addr_t dma_handle, unsigned long attrs);
+int ipu6_dma_mmap(struct ipu6_bus_device *sys, struct vm_area_struct *vma,
+                 void *addr, dma_addr_t iova, size_t size,
+                 unsigned long attrs);
+int ipu6_dma_map_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist,
+                   int nents, enum dma_data_direction dir,
+                   unsigned long attrs);
+void ipu6_dma_unmap_sg(struct ipu6_bus_device *sys, struct scatterlist *sglist,
+                      int nents, enum dma_data_direction dir,
+                      unsigned long attrs);
+int ipu6_dma_map_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt,
+                        enum dma_data_direction dir, unsigned long attrs);
+void ipu6_dma_unmap_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt,
+                           enum dma_data_direction dir, unsigned long attrs);
+int ipu6_dma_get_sgtable(struct ipu6_bus_device *sys, struct sg_table *sgt,
+                        void *cpu_addr, dma_addr_t handle, size_t size,
+                        unsigned long attrs);
 #endif /* IPU6_DMA_H */
index 958196a6b2631edb7294db18e5c756545a82ff2f..53edb445d9395b01fee392c2f8820fe86a14a438 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 
 #include "ipu6-bus.h"
+#include "ipu6-dma.h"
 #include "ipu6-fw-com.h"
 
 /*
@@ -88,7 +89,6 @@ struct ipu6_fw_com_context {
        void *dma_buffer;
        dma_addr_t dma_addr;
        unsigned int dma_size;
-       unsigned long attrs;
 
        struct ipu6_fw_sys_queue *input_queue;  /* array of host to SP queues */
        struct ipu6_fw_sys_queue *output_queue; /* array of SP to host */
@@ -164,7 +164,6 @@ void *ipu6_fw_com_prepare(struct ipu6_fw_com_cfg *cfg,
        struct ipu6_fw_com_context *ctx;
        struct device *dev = &adev->auxdev.dev;
        size_t sizeall, offset;
-       unsigned long attrs = 0;
        void *specific_host_addr;
        unsigned int i;
 
@@ -206,9 +205,8 @@ void *ipu6_fw_com_prepare(struct ipu6_fw_com_cfg *cfg,
 
        sizeall += sizeinput + sizeoutput;
 
-       ctx->dma_buffer = dma_alloc_attrs(dev, sizeall, &ctx->dma_addr,
-                                         GFP_KERNEL, attrs);
-       ctx->attrs = attrs;
+       ctx->dma_buffer = ipu6_dma_alloc(adev, sizeall, &ctx->dma_addr,
+                                        GFP_KERNEL, 0);
        if (!ctx->dma_buffer) {
                dev_err(dev, "failed to allocate dma memory\n");
                kfree(ctx);
@@ -239,6 +237,8 @@ void *ipu6_fw_com_prepare(struct ipu6_fw_com_cfg *cfg,
                memcpy(specific_host_addr, cfg->specific_addr,
                       cfg->specific_size);
 
+       ipu6_dma_sync_single(adev, ctx->config_vied_addr, sizeall);
+
        /* initialize input queues */
        offset += specific_size;
        res.reg = SYSCOM_QPR_BASE_REG;
@@ -315,8 +315,8 @@ int ipu6_fw_com_release(struct ipu6_fw_com_context *ctx, unsigned int force)
        if (!force && !ctx->cell_ready(ctx->adev))
                return -EBUSY;
 
-       dma_free_attrs(&ctx->adev->auxdev.dev, ctx->dma_size,
-                      ctx->dma_buffer, ctx->dma_addr, ctx->attrs);
+       ipu6_dma_free(ctx->adev, ctx->dma_size,
+                     ctx->dma_buffer, ctx->dma_addr, 0);
        kfree(ctx);
        return 0;
 }