Merge tag 'printk-for-5.10-fixup' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / iommu / dma-iommu.c
index cd6e3c7..0cbcd3f 100644 (file)
@@ -10,9 +10,8 @@
 
 #include <linux/acpi_iort.h>
 #include <linux/device.h>
-#include <linux/dma-contiguous.h>
+#include <linux/dma-map-ops.h>
 #include <linux/dma-iommu.h>
-#include <linux/dma-noncoherent.h>
 #include <linux/gfp.h>
 #include <linux/huge_mm.h>
 #include <linux/iommu.h>
@@ -572,6 +571,7 @@ static struct page **__iommu_dma_alloc_pages(struct device *dev,
  * @size: Size of buffer in bytes
  * @dma_handle: Out argument for allocated DMA handle
  * @gfp: Allocation flags
+ * @prot: pgprot_t to use for the remapped mapping
  * @attrs: DMA attributes for this allocation
  *
  * If @size is less than PAGE_SIZE, then a full CPU page will be allocated,
@@ -580,14 +580,14 @@ static struct page **__iommu_dma_alloc_pages(struct device *dev,
  * Return: Mapped virtual address, or NULL on failure.
  */
 static void *iommu_dma_alloc_remap(struct device *dev, size_t size,
-               dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+               dma_addr_t *dma_handle, gfp_t gfp, pgprot_t prot,
+               unsigned long attrs)
 {
        struct iommu_domain *domain = iommu_get_dma_domain(dev);
        struct iommu_dma_cookie *cookie = domain->iova_cookie;
        struct iova_domain *iovad = &cookie->iovad;
        bool coherent = dev_is_dma_coherent(dev);
        int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs);
-       pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs);
        unsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap;
        struct page **pages;
        struct sg_table sgt;
@@ -1030,8 +1030,10 @@ static void *iommu_dma_alloc(struct device *dev, size_t size,
        gfp |= __GFP_ZERO;
 
        if (IS_ENABLED(CONFIG_DMA_REMAP) && gfpflags_allow_blocking(gfp) &&
-           !(attrs & DMA_ATTR_FORCE_CONTIGUOUS))
-               return iommu_dma_alloc_remap(dev, size, handle, gfp, attrs);
+           !(attrs & DMA_ATTR_FORCE_CONTIGUOUS)) {
+               return iommu_dma_alloc_remap(dev, size, handle, gfp,
+                               dma_pgprot(dev, PAGE_KERNEL, attrs), attrs);
+       }
 
        if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
            !gfpflags_allow_blocking(gfp) && !coherent)
@@ -1052,6 +1054,34 @@ static void *iommu_dma_alloc(struct device *dev, size_t size,
        return cpu_addr;
 }
 
+#ifdef CONFIG_DMA_REMAP
+static void *iommu_dma_alloc_noncoherent(struct device *dev, size_t size,
+               dma_addr_t *handle, enum dma_data_direction dir, gfp_t gfp)
+{
+       if (!gfpflags_allow_blocking(gfp)) {
+               struct page *page;
+
+               page = dma_common_alloc_pages(dev, size, handle, dir, gfp);
+               if (!page)
+                       return NULL;
+               return page_address(page);
+       }
+
+       return iommu_dma_alloc_remap(dev, size, handle, gfp | __GFP_ZERO,
+                                    PAGE_KERNEL, 0);
+}
+
+static void iommu_dma_free_noncoherent(struct device *dev, size_t size,
+               void *cpu_addr, dma_addr_t handle, enum dma_data_direction dir)
+{
+       __iommu_dma_unmap(dev, handle, size);
+       __iommu_dma_free(dev, size, cpu_addr);
+}
+#else
+#define iommu_dma_alloc_noncoherent            NULL
+#define iommu_dma_free_noncoherent             NULL
+#endif /* CONFIG_DMA_REMAP */
+
 static int iommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
                void *cpu_addr, dma_addr_t dma_addr, size_t size,
                unsigned long attrs)
@@ -1120,6 +1150,10 @@ static unsigned long iommu_dma_get_merge_boundary(struct device *dev)
 static const struct dma_map_ops iommu_dma_ops = {
        .alloc                  = iommu_dma_alloc,
        .free                   = iommu_dma_free,
+       .alloc_pages            = dma_common_alloc_pages,
+       .free_pages             = dma_common_free_pages,
+       .alloc_noncoherent      = iommu_dma_alloc_noncoherent,
+       .free_noncoherent       = iommu_dma_free_noncoherent,
        .mmap                   = iommu_dma_mmap,
        .get_sgtable            = iommu_dma_get_sgtable,
        .map_page               = iommu_dma_map_page,