diff options
author | Lajos Molnar <molnar@ti.com> | 2011-12-16 14:11:03 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2011-12-26 22:33:20 +0800 |
commit | 234fdcb5186ac785ff6706c48ca96dacf0862f89 (patch) | |
tree | 946ca3b5bd457ed84dc64e13aae0e4c433028f35 | |
parent | d6f6754e3418d856fe3226d6efc9e42a6d90d758 (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.c | 22 |
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); |