arm_iommu_create_mapping() allocates two separate things: address space
bookkeeping tracking allocated IOVA ranges; and the corresponding IOMMU
domain.

Split out the former into __arm_iommu_alloc_mapping(), with a matching
__arm_iommu_free_mapping(), so that the bookkeeping can be created
independently when a domain is allocated outside the ARM dma-mapping
code. A later patch uses this to turn struct dma_iommu_mapping into an
IOMMU domain cookie.

No functional change.

Signed-off-by: Mikko Perttunen <[email protected]>
---
 arch/arm/mm/dma-mapping.c | 76 +++++++++++++++++++++++++++++------------------
 1 file changed, 47 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f9bc53b60f99..a7ad194960ce 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1470,21 +1470,8 @@ static const struct dma_map_ops iommu_ops = {
        .sync_sg_for_device     = arm_iommu_sync_sg_for_device,
 };
 
-/**
- * arm_iommu_create_mapping
- * @dev: pointer to the client device (for IOMMU calls)
- * @base: start address of the valid IO address space
- * @size: maximum size of the valid IO address space
- *
- * Creates a mapping structure which holds information about used/unused
- * IO address ranges, which is required to perform memory allocation and
- * mapping with IOMMU aware functions.
- *
- * The client device need to be attached to the mapping with
- * arm_iommu_attach_device function.
- */
-struct dma_iommu_mapping *
-arm_iommu_create_mapping(struct device *dev, dma_addr_t base, u64 size)
+static struct dma_iommu_mapping *
+__arm_iommu_alloc_mapping(dma_addr_t base, u64 size)
 {
        unsigned int bits = size >> PAGE_SHIFT;
        unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long);
@@ -1525,16 +1512,7 @@ arm_iommu_create_mapping(struct device *dev, dma_addr_t 
base, u64 size)
 
        spin_lock_init(&mapping->lock);
 
-       mapping->domain = iommu_paging_domain_alloc(dev);
-       if (IS_ERR(mapping->domain)) {
-               err = PTR_ERR(mapping->domain);
-               goto err4;
-       }
-
-       kref_init(&mapping->kref);
        return mapping;
-err4:
-       kfree(mapping->bitmaps[0]);
 err3:
        kfree(mapping->bitmaps);
 err2:
@@ -1542,21 +1520,61 @@ arm_iommu_create_mapping(struct device *dev, dma_addr_t 
base, u64 size)
 err:
        return ERR_PTR(err);
 }
-EXPORT_SYMBOL_GPL(arm_iommu_create_mapping);
 
-static void release_iommu_mapping(struct kref *kref)
+static void __arm_iommu_free_mapping(struct dma_iommu_mapping *mapping)
 {
        int i;
-       struct dma_iommu_mapping *mapping =
-               container_of(kref, struct dma_iommu_mapping, kref);
 
-       iommu_domain_free(mapping->domain);
        for (i = 0; i < mapping->nr_bitmaps; i++)
                kfree(mapping->bitmaps[i]);
        kfree(mapping->bitmaps);
        kfree(mapping);
 }
 
+/**
+ * arm_iommu_create_mapping
+ * @dev: pointer to the client device (for IOMMU calls)
+ * @base: start address of the valid IO address space
+ * @size: maximum size of the valid IO address space
+ *
+ * Creates a mapping structure which holds information about used/unused
+ * IO address ranges, which is required to perform memory allocation and
+ * mapping with IOMMU aware functions.
+ *
+ * The client device need to be attached to the mapping with
+ * arm_iommu_attach_device function.
+ */
+struct dma_iommu_mapping *
+arm_iommu_create_mapping(struct device *dev, dma_addr_t base, u64 size)
+{
+       struct dma_iommu_mapping *mapping;
+
+       mapping = __arm_iommu_alloc_mapping(base, size);
+       if (IS_ERR(mapping))
+               return mapping;
+
+       mapping->domain = iommu_paging_domain_alloc(dev);
+       if (IS_ERR(mapping->domain)) {
+               int err = PTR_ERR(mapping->domain);
+
+               __arm_iommu_free_mapping(mapping);
+               return ERR_PTR(err);
+       }
+
+       kref_init(&mapping->kref);
+       return mapping;
+}
+EXPORT_SYMBOL_GPL(arm_iommu_create_mapping);
+
+static void release_iommu_mapping(struct kref *kref)
+{
+       struct dma_iommu_mapping *mapping =
+               container_of(kref, struct dma_iommu_mapping, kref);
+
+       iommu_domain_free(mapping->domain);
+       __arm_iommu_free_mapping(mapping);
+}
+
 static int extend_iommu_mapping(struct dma_iommu_mapping *mapping)
 {
        int next_bitmap;

-- 
2.55.0

Reply via email to