We're going to re-use these in the next commit.  No functional changes,
just some ugly callbacks.

Signed-off-by: Rob Clark <[email protected]>
---
 drivers/gpu/drm/msm/msm_iommu.c | 150 ++++++++++++++++++++------------
 1 file changed, 93 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index da6782fca6bd..a658493f8007 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -52,9 +52,8 @@ static struct msm_iommu_pagetable *to_pagetable(struct 
msm_mmu *mmu)
 }
 
 /* based on iommu_pgsize() in iommu.c: */
-static size_t calc_pgsize(struct msm_iommu_pagetable *pagetable,
-                          unsigned long iova, phys_addr_t paddr,
-                          size_t size, size_t *count)
+static size_t calc_pgsize(unsigned long pgsize_bitmap, unsigned long iova,
+                         phys_addr_t paddr, size_t size, size_t *count)
 {
        unsigned int pgsize_idx, pgsize_idx_next;
        unsigned long pgsizes;
@@ -62,7 +61,7 @@ static size_t calc_pgsize(struct msm_iommu_pagetable 
*pagetable,
        unsigned long addr_merge = paddr | iova;
 
        /* Page sizes supported by the hardware and small enough for @size */
-       pgsizes = pagetable->pgsize_bitmap & GENMASK(__fls(size), 0);
+       pgsizes = pgsize_bitmap & GENMASK(__fls(size), 0);
 
        /* Constrain the page sizes further based on the maximum alignment */
        if (likely(addr_merge))
@@ -78,7 +77,7 @@ static size_t calc_pgsize(struct msm_iommu_pagetable 
*pagetable,
                return pgsize;
 
        /* Find the next biggest support page size, if it exists */
-       pgsizes = pagetable->pgsize_bitmap & ~GENMASK(pgsize_idx, 0);
+       pgsizes = pgsize_bitmap & ~GENMASK(pgsize_idx, 0);
        if (!pgsizes)
                goto out_set_count;
 
@@ -107,24 +106,27 @@ static size_t calc_pgsize(struct msm_iommu_pagetable 
*pagetable,
        return pgsize;
 }
 
-static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova,
-               size_t size)
+typedef size_t (*unmap_fn)(void *arg, u64 iova, size_t pgsize, size_t count);
+typedef int (*map_fn)(void *arg, phys_addr_t paddr, u64 iova, size_t pgsize,
+                     size_t pgcount, int prot, size_t *mapped);
+
+static inline int
+__do_unmap(unsigned long pgsize_bitmap, u64 iova, size_t size,
+          void *arg, unmap_fn unmap)
 {
-       struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
-       struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
        int ret = 0;
 
        while (size) {
                size_t pgsize, count;
                ssize_t unmapped;
 
-               pgsize = calc_pgsize(pagetable, iova, iova, size, &count);
+               pgsize = calc_pgsize(pgsize_bitmap, iova, iova, size, &count);
 
-               unmapped = ops->unmap_pages(ops, iova, pgsize, count, NULL);
+               unmapped = unmap(arg, iova, pgsize, count);
                if (unmapped <= 0) {
                        ret = -EINVAL;
                        /*
-                        * Continue attempting to unamp the remained of the
+                        * Continue attempting to unmap the remained of the
                         * range, so we don't end up with some dangling
                         * mapped pages
                         */
@@ -135,55 +137,18 @@ static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, 
u64 iova,
                size -= unmapped;
        }
 
-       iommu_flush_iotlb_all(to_msm_iommu(pagetable->parent)->domain);
-
        return ret;
 }
 
-static int msm_iommu_pagetable_map_prr(struct msm_mmu *mmu, u64 iova, size_t 
len, int prot)
-{
-       struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
-       struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
-       struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
-       phys_addr_t phys = page_to_phys(iommu->prr_page);
-       u64 addr = iova;
-
-       while (len) {
-               size_t mapped = 0;
-               size_t size = PAGE_SIZE;
-               int ret;
-
-               ret = ops->map_pages(ops, addr, phys, size, 1, prot, 
GFP_KERNEL, &mapped);
-
-               /* map_pages could fail after mapping some of the pages,
-                * so update the counters before error handling.
-                */
-               addr += mapped;
-               len  -= mapped;
-
-               if (ret) {
-                       msm_iommu_pagetable_unmap(mmu, iova, addr - iova);
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
-                                  struct sg_table *sgt, size_t off, size_t len,
-                                  int prot)
+static inline int
+__do_map(unsigned long pgsize_bitmap, u64 iova, struct sg_table *sgt, size_t 
off,
+        size_t len, int prot, void *arg, map_fn map, unmap_fn unmap)
 {
-       struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
-       struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
        struct scatterlist *sg;
        u64 addr = iova;
        unsigned int i;
 
-       if (!sgt)
-               return msm_iommu_pagetable_map_prr(mmu, iova, len, prot);
-
-       for_each_sgtable_sg(sgt, sg, i) {
+       for_each_sgtable_sg (sgt, sg, i) {
                size_t size = sg->length;
                phys_addr_t phys = sg_phys(sg);
 
@@ -204,10 +169,9 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, 
u64 iova,
                        size_t pgsize, count, mapped = 0;
                        int ret;
 
-                       pgsize = calc_pgsize(pagetable, addr, phys, size, 
&count);
+                       pgsize = calc_pgsize(pgsize_bitmap, addr, phys, size, 
&count);
 
-                       ret = ops->map_pages(ops, addr, phys, pgsize, count,
-                                            prot, GFP_KERNEL, &mapped);
+                       ret = map(arg, phys, addr, pgsize, count, prot, 
&mapped);
 
                        /* map_pages could fail after mapping some of the pages,
                         * so update the counters before error handling.
@@ -218,7 +182,7 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 
iova,
                        len  -= mapped;
 
                        if (ret) {
-                               msm_iommu_pagetable_unmap(mmu, iova, addr - 
iova);
+                               __do_unmap(pgsize_bitmap, iova, addr - iova, 
arg, unmap);
                                return -EINVAL;
                        }
                }
@@ -227,6 +191,78 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, 
u64 iova,
        return 0;
 }
 
+static size_t
+__unmap_pgtable(void *arg, u64 iova, size_t pgsize, size_t pgcount)
+{
+       struct io_pgtable_ops *ops = arg;
+       return ops->unmap_pages(ops, iova, pgsize, pgcount, NULL);
+}
+
+static int
+__map_pgtable(void *arg, phys_addr_t paddr, u64 iova, size_t pgsize,
+             size_t pgcount, int prot, size_t *mapped)
+{
+       struct io_pgtable_ops *ops = arg;
+       return ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot, 
GFP_KERNEL, mapped);
+}
+
+static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova, size_t 
size)
+{
+       struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+       struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+       int ret = 0;
+
+       ret = __do_unmap(pagetable->pgsize_bitmap, iova, size, ops, 
__unmap_pgtable);
+
+       iommu_flush_iotlb_all(to_msm_iommu(pagetable->parent)->domain);
+
+       return ret;
+}
+
+static int msm_iommu_pagetable_map_prr(struct msm_mmu *mmu, u64 iova, size_t 
len, int prot)
+{
+       struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+       struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+       struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
+       phys_addr_t phys = page_to_phys(iommu->prr_page);
+       u64 addr = iova;
+
+       while (len) {
+               size_t mapped = 0;
+               size_t size = PAGE_SIZE;
+               int ret;
+
+               ret = ops->map_pages(ops, addr, phys, size, 1, prot, 
GFP_KERNEL, &mapped);
+
+               /* map_pages could fail after mapping some of the pages,
+                * so update the counters before error handling.
+                */
+               addr += mapped;
+               len  -= mapped;
+
+               if (ret) {
+                       msm_iommu_pagetable_unmap(mmu, iova, addr - iova);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
+                                  struct sg_table *sgt, size_t off, size_t len,
+                                  int prot)
+{
+       struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+       struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+
+       if (!sgt)
+               return msm_iommu_pagetable_map_prr(mmu, iova, len, prot);
+
+       return __do_map(pagetable->pgsize_bitmap, iova, sgt, off, len, prot,
+                       ops, __map_pgtable, __unmap_pgtable);
+}
+
 static void msm_iommu_pagetable_destroy(struct msm_mmu *mmu)
 {
        struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
-- 
2.55.0

Reply via email to