[PATCH 2/4] ARM: OMAP: IOMMU driver: VMA management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



device Virtual address space management (*partialy implemented)

Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@xxxxxxxxx>
---
 arch/arm/plat-omap/iommu_mmap.c |  127 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 127 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-omap/iommu_mmap.c

diff --git a/arch/arm/plat-omap/iommu_mmap.c b/arch/arm/plat-omap/iommu_mmap.c
new file mode 100644
index 0000000..7070d88
--- /dev/null
+++ b/arch/arm/plat-omap/iommu_mmap.c
@@ -0,0 +1,127 @@
+/*
+ * OMAP peripheral device common IOMMU driver
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@xxxxxxxxx>,
+ *		Paul Mundt and Toshihiro Kobayashi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <asm/pgalloc.h>
+
+#include <mach/clock.h>
+#include <mach/iommu.h>
+/*
+ *
+ *	Device Virtual Address Management
+ *
+ */
+/* REVISIT */
+unsigned long ioget_unmapped_area(struct iommu *obj, unsigned long len)
+{
+	struct mm_struct *mm = obj->twl_mm;
+	struct vm_area_struct *vma;
+	unsigned long start_addr, addr;
+
+	if (len > mm->cached_hole_size) {
+		start_addr = addr = mm->free_area_cache;
+	} else {
+		start_addr = addr = 0;
+		mm->cached_hole_size = 0;
+	}
+
+	while (1) {
+		vma = find_vma(mm, addr);
+		if (!vma || addr + len <= vma->vm_start) {
+			mm->free_area_cache = addr + len;
+			return addr;
+		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+			mm->cached_hole_size = vma->vm_start - addr;
+		addr = vma->vm_end;
+	}
+}
+EXPORT_SYMBOL(ioget_unmapped_area);
+/* REVISIT */
+dma_addr_t iomap_region(struct iommu *obj, struct iotlb_entry *e)
+{
+	struct mm_struct *mm = obj->twl_mm;
+	unsigned long len = pgsz2bytes(e->pgsz);
+	struct vm_area_struct *vma;
+
+	vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
+	if (!vma)
+		return -ENOMEM;
+	vma->vm_mm = mm;
+	vma->vm_start = e->va;
+	vma->vm_end = e->va + len;
+	vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_LOCKED;
+	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+	down_write(&mm->mmap_sem);
+	if (insert_vm_struct(mm, vma)) {
+		up_write(&mm->mmap_sem);
+		kmem_cache_free(vm_area_cachep, vma);
+		return -EINVAL;
+	}
+	up_write(&mm->mmap_sem);
+	return iotwl_pte_set(obj, e);
+}
+EXPORT_SYMBOL(iomap_region);
+/* REVISIT */
+void iounmap_region(struct iommu *obj, unsigned long iova, size_t len)
+{
+	struct mm_struct *mm = obj->twl_mm;
+	unsigned long start = iova;
+
+	down_write(&mm->mmap_sem);
+	while (len >= SZ_4K) {
+		int bytes;
+		struct vm_area_struct *vma, *prev;
+
+		vma = find_vma_prev(mm, start, &prev);
+		if (!vma) {
+			dev_err(obj->dev, "No vma @ %08lx\n", start);
+			continue;
+		}
+		bytes = vma->vm_end - vma->vm_start;
+
+		switch (bytes) {
+		case SZ_1M:
+		case SZ_64K:
+		case SZ_4K:
+		case SZ_16M:
+			break;
+		default:
+			dev_err(obj->dev, "Unsupported size, %xl\n", len);
+			continue;
+		}
+
+		rb_erase(&vma->vm_rb, &mm->mm_rb);
+		mm->map_count--;
+		if (prev)
+			prev->vm_next = vma->vm_next;
+		else
+			mm->mmap = vma->vm_next;
+		mm->mmap_cache = NULL;
+		kmem_cache_free(vm_area_cachep, vma);
+
+		iotwl_pte_clear(obj, iova);
+
+		len -= bytes;
+		start += bytes;
+	}
+	WARN_ON(len);
+	up_write(&mm->mmap_sem);
+}
+EXPORT_SYMBOL(iounmap_region);
+
-- 
1.5.5.1.357.g1af8b

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux