diff options
author | Guzman Lugo, Fernando <x0095840@ti.com> | 2010-12-14 19:54:03 -0500 |
---|---|---|
committer | Hari Kanigeri <h-kanigeri2@ti.com> | 2010-12-15 12:29:10 -0500 |
commit | c7f4ab26e3bcdaeb3e19ec658e3ad9092f1a6ceb (patch) | |
tree | b80f93995d8e9daa1f53a18c105e8d532102cd21 /arch/arm/plat-omap | |
parent | 9205a109fbeee180254bb5a4020eb71d50735944 (diff) |
OMAP: iommu: create new api to set valid da range
Some IOMMUs cannot use the whole 0x0 - 0xFFFFFFFF range.
With this new API the valid range can be set.
Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com>
Acked-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/include/plat/iommu.h | 5 | ||||
-rw-r--r-- | arch/arm/plat-omap/iommu.c | 24 | ||||
-rw-r--r-- | arch/arm/plat-omap/iovmm.c | 15 |
3 files changed, 37 insertions, 7 deletions
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 33c7d41cb6a5..69230d685538 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h | |||
@@ -50,6 +50,8 @@ struct iommu { | |||
50 | int (*isr)(struct iommu *obj); | 50 | int (*isr)(struct iommu *obj); |
51 | 51 | ||
52 | void *ctx; /* iommu context: registres saved area */ | 52 | void *ctx; /* iommu context: registres saved area */ |
53 | u32 da_start; | ||
54 | u32 da_end; | ||
53 | }; | 55 | }; |
54 | 56 | ||
55 | struct cr_regs { | 57 | struct cr_regs { |
@@ -103,6 +105,8 @@ struct iommu_platform_data { | |||
103 | const char *name; | 105 | const char *name; |
104 | const char *clk_name; | 106 | const char *clk_name; |
105 | const int nr_tlb_entries; | 107 | const int nr_tlb_entries; |
108 | u32 da_start; | ||
109 | u32 da_end; | ||
106 | }; | 110 | }; |
107 | 111 | ||
108 | #if defined(CONFIG_ARCH_OMAP1) | 112 | #if defined(CONFIG_ARCH_OMAP1) |
@@ -152,6 +156,7 @@ extern void flush_iotlb_all(struct iommu *obj); | |||
152 | extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); | 156 | extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); |
153 | extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); | 157 | extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); |
154 | 158 | ||
159 | extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); | ||
155 | extern struct iommu *iommu_get(const char *name); | 160 | extern struct iommu *iommu_get(const char *name); |
156 | extern void iommu_put(struct iommu *obj); | 161 | extern void iommu_put(struct iommu *obj); |
157 | 162 | ||
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 6cd151b31bc5..b1107c08da56 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c | |||
@@ -830,6 +830,28 @@ static int device_match_by_alias(struct device *dev, void *data) | |||
830 | } | 830 | } |
831 | 831 | ||
832 | /** | 832 | /** |
833 | * iommu_set_da_range - Set a valid device address range | ||
834 | * @obj: target iommu | ||
835 | * @start Start of valid range | ||
836 | * @end End of valid range | ||
837 | **/ | ||
838 | int iommu_set_da_range(struct iommu *obj, u32 start, u32 end) | ||
839 | { | ||
840 | |||
841 | if (!obj) | ||
842 | return -EFAULT; | ||
843 | |||
844 | if (end < start || !PAGE_ALIGN(start | end)) | ||
845 | return -EINVAL; | ||
846 | |||
847 | obj->da_start = start; | ||
848 | obj->da_end = end; | ||
849 | |||
850 | return 0; | ||
851 | } | ||
852 | EXPORT_SYMBOL_GPL(iommu_set_da_range); | ||
853 | |||
854 | /** | ||
833 | * iommu_get - Get iommu handler | 855 | * iommu_get - Get iommu handler |
834 | * @name: target iommu name | 856 | * @name: target iommu name |
835 | **/ | 857 | **/ |
@@ -922,6 +944,8 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev) | |||
922 | obj->name = pdata->name; | 944 | obj->name = pdata->name; |
923 | obj->dev = &pdev->dev; | 945 | obj->dev = &pdev->dev; |
924 | obj->ctx = (void *)obj + sizeof(*obj); | 946 | obj->ctx = (void *)obj + sizeof(*obj); |
947 | obj->da_start = pdata->da_start; | ||
948 | obj->da_end = pdata->da_end; | ||
925 | 949 | ||
926 | mutex_init(&obj->iommu_lock); | 950 | mutex_init(&obj->iommu_lock); |
927 | mutex_init(&obj->mmap_lock); | 951 | mutex_init(&obj->mmap_lock); |
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index fa6e64332a9e..6dc1296c8c77 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c | |||
@@ -280,13 +280,14 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, | |||
280 | alignement = PAGE_SIZE; | 280 | alignement = PAGE_SIZE; |
281 | 281 | ||
282 | if (flags & IOVMF_DA_ANON) { | 282 | if (flags & IOVMF_DA_ANON) { |
283 | /* | 283 | start = obj->da_start; |
284 | * Reserve the first page for NULL | 284 | |
285 | */ | ||
286 | start = PAGE_SIZE; | ||
287 | if (flags & IOVMF_LINEAR) | 285 | if (flags & IOVMF_LINEAR) |
288 | alignement = iopgsz_max(bytes); | 286 | alignement = iopgsz_max(bytes); |
289 | start = roundup(start, alignement); | 287 | start = roundup(start, alignement); |
288 | } else if (start < obj->da_start || start > obj->da_end || | ||
289 | obj->da_end - start < bytes) { | ||
290 | return ERR_PTR(-EINVAL); | ||
290 | } | 291 | } |
291 | 292 | ||
292 | tmp = NULL; | 293 | tmp = NULL; |
@@ -299,16 +300,16 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, | |||
299 | if (prev_end > start) | 300 | if (prev_end > start) |
300 | break; | 301 | break; |
301 | 302 | ||
302 | if (start + bytes <= tmp->da_start) | 303 | if (tmp->da_start > start && (tmp->da_start - start) >= bytes) |
303 | goto found; | 304 | goto found; |
304 | 305 | ||
305 | if (flags & IOVMF_DA_ANON) | 306 | if (tmp->da_end >= start && flags & IOVMF_DA_ANON) |
306 | start = roundup(tmp->da_end + 1, alignement); | 307 | start = roundup(tmp->da_end + 1, alignement); |
307 | 308 | ||
308 | prev_end = tmp->da_end; | 309 | prev_end = tmp->da_end; |
309 | } | 310 | } |
310 | 311 | ||
311 | if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) | 312 | if ((start >= prev_end) && (obj->da_end - start >= bytes)) |
312 | goto found; | 313 | goto found; |
313 | 314 | ||
314 | dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", | 315 | dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", |