aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2011-12-16 14:11:03 +0800
committerAndy Green <andy.green@linaro.org>2011-12-26 22:33:20 +0800
commit234fdcb5186ac785ff6706c48ca96dacf0862f89 (patch)
tree946ca3b5bd457ed84dc64e13aae0e4c433028f35
parentd6f6754e3418d856fe3226d6efc9e42a6d90d758 (diff)
TILER: Add support for mapping kernel allocated buffers into TILER
get_user_pages is not effective for kernel allocated buffers. We fall back to tiler_virt2phys() for those. Signed-off-by: Lajos Molnar <molnar@ti.com> Signed-off-by: Mark Tyler <mark.tyler@ti.com> Signed-off-by: Andy Gross <andy.gross@ti.com>
-rw-r--r--drivers/media/video/tiler/tiler-main.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c
index 5d72db1ca89..69e79c30319 100644
--- a/drivers/media/video/tiler/tiler-main.c
+++ b/drivers/media/video/tiler/tiler-main.c
@@ -971,7 +971,7 @@ static s32 map_block(enum tiler_fmt fmt, u32 width, u32 height,
u32 key, u32 gid, struct process_info *pi,
struct mem_info **info, u32 usr_addr)
{
- u32 i = 0, tmp = -1, *mem = NULL;
+ u32 i = 0, tmp = -1, *mem = NULL, use_gp = 1;
u8 write = 0;
s32 res = -ENOMEM;
struct mem_info *mi = NULL;
@@ -1065,19 +1065,29 @@ static s32 map_block(enum tiler_fmt fmt, u32 width, u32 height,
tmp = mi->usr;
for (i = 0; i < mi->num_pg; i++) {
- if (get_user_pages(curr_task, mm, tmp, 1, write, 1, &page,
- NULL) && page) {
+ /*
+ * At first use get_user_pages which works best for
+ * userspace buffers. If it fails (e.g. for kernel
+ * allocated buffers), fall back to using the page
+ * table directly.
+ */
+ if (use_gp && get_user_pages(curr_task, mm, tmp, 1, write, 1,
+ &page, NULL) && page) {
if (page_count(page) < 1) {
printk(KERN_ERR "Bad page count from"
"get_user_pages()\n");
}
mi->pg_ptr[i] = (u32)page;
mem[i] = page_to_phys(page);
- tmp += PAGE_SIZE;
} else {
- printk(KERN_ERR "get_user_pages() failed\n");
- goto fault;
+ use_gp = mi->pg_ptr[i] = 0;
+ mem[i] = tiler_virt2phys(tmp);
+ if (!mem[i]) {
+ printk(KERN_ERR "get_user_pages() failed and virtual address is not in page table\n");
+ goto fault;
+ }
}
+ tmp += PAGE_SIZE;
}
up_read(&mm->mmap_sem);