|
@@ -1708,3 +1708,75 @@ static void arm_iommu_sync_single_for_device(struct device *dev,
|
|
|
dma_addr_t handle, size_t size, enum dma_data_direction dir)
|
|
|
{
|
|
|
struct dma_iommu_mapping *mapping = dev->archdata.mapping;
|
|
|
+ dma_addr_t iova = handle & PAGE_MASK;
|
|
|
+ struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
|
|
|
+ unsigned int offset = handle & ~PAGE_MASK;
|
|
|
+
|
|
|
+ if (!iova)
|
|
|
+ return;
|
|
|
+
|
|
|
+ __dma_page_cpu_to_dev(page, offset, size, dir);
|
|
|
+}
|
|
|
+
|
|
|
+struct dma_map_ops iommu_ops = {
|
|
|
+ .alloc = arm_iommu_alloc_attrs,
|
|
|
+ .free = arm_iommu_free_attrs,
|
|
|
+ .mmap = arm_iommu_mmap_attrs,
|
|
|
+ .get_sgtable = arm_iommu_get_sgtable,
|
|
|
+
|
|
|
+ .map_page = arm_iommu_map_page,
|
|
|
+ .unmap_page = arm_iommu_unmap_page,
|
|
|
+ .sync_single_for_cpu = arm_iommu_sync_single_for_cpu,
|
|
|
+ .sync_single_for_device = arm_iommu_sync_single_for_device,
|
|
|
+
|
|
|
+ .map_sg = arm_iommu_map_sg,
|
|
|
+ .unmap_sg = arm_iommu_unmap_sg,
|
|
|
+ .sync_sg_for_cpu = arm_iommu_sync_sg_for_cpu,
|
|
|
+ .sync_sg_for_device = arm_iommu_sync_sg_for_device,
|
|
|
+};
|
|
|
+
|
|
|
+struct dma_map_ops iommu_coherent_ops = {
|
|
|
+ .alloc = arm_iommu_alloc_attrs,
|
|
|
+ .free = arm_iommu_free_attrs,
|
|
|
+ .mmap = arm_iommu_mmap_attrs,
|
|
|
+ .get_sgtable = arm_iommu_get_sgtable,
|
|
|
+
|
|
|
+ .map_page = arm_coherent_iommu_map_page,
|
|
|
+ .unmap_page = arm_coherent_iommu_unmap_page,
|
|
|
+
|
|
|
+ .map_sg = arm_coherent_iommu_map_sg,
|
|
|
+ .unmap_sg = arm_coherent_iommu_unmap_sg,
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * arm_iommu_create_mapping
|
|
|
+ * @bus: pointer to the bus holding the client device (for IOMMU calls)
|
|
|
+ * @base: start address of the valid IO address space
|
|
|
+ * @size: size of the valid IO address space
|
|
|
+ * @order: accuracy of the IO addresses allocations
|
|
|
+ *
|
|
|
+ * 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 bus_type *bus, dma_addr_t base, size_t size,
|
|
|
+ int order)
|
|
|
+{
|
|
|
+ unsigned int count = size >> (PAGE_SHIFT + order);
|
|
|
+ unsigned int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
|
|
|
+ struct dma_iommu_mapping *mapping;
|
|
|
+ int err = -ENOMEM;
|
|
|
+
|
|
|
+ if (!count)
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+
|
|
|
+ mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL);
|
|
|
+ if (!mapping)
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ mapping->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
|
|
|
+ if (!mapping->bitmap)
|