diff options
Diffstat (limited to 'drivers/video/fbmem.c')
-rw-r--r-- | drivers/video/fbmem.c | 39 |
1 files changed, 14 insertions, 25 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 7c254084b6a0..86291dcd964a 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1373,15 +1373,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1373 | { | 1373 | { |
1374 | struct fb_info *info = file_fb_info(file); | 1374 | struct fb_info *info = file_fb_info(file); |
1375 | struct fb_ops *fb; | 1375 | struct fb_ops *fb; |
1376 | unsigned long off; | 1376 | unsigned long mmio_pgoff; |
1377 | unsigned long start; | 1377 | unsigned long start; |
1378 | u32 len; | 1378 | u32 len; |
1379 | 1379 | ||
1380 | if (!info) | 1380 | if (!info) |
1381 | return -ENODEV; | 1381 | return -ENODEV; |
1382 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) | ||
1383 | return -EINVAL; | ||
1384 | off = vma->vm_pgoff << PAGE_SHIFT; | ||
1385 | fb = info->fbops; | 1382 | fb = info->fbops; |
1386 | if (!fb) | 1383 | if (!fb) |
1387 | return -ENODEV; | 1384 | return -ENODEV; |
@@ -1393,32 +1390,24 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1393 | return res; | 1390 | return res; |
1394 | } | 1391 | } |
1395 | 1392 | ||
1396 | /* frame buffer memory */ | 1393 | /* |
1394 | * Ugh. This can be either the frame buffer mapping, or | ||
1395 | * if pgoff points past it, the mmio mapping. | ||
1396 | */ | ||
1397 | start = info->fix.smem_start; | 1397 | start = info->fix.smem_start; |
1398 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); | 1398 | len = info->fix.smem_len; |
1399 | if (off >= len) { | 1399 | mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; |
1400 | /* memory mapped io */ | 1400 | if (vma->vm_pgoff >= mmio_pgoff) { |
1401 | off -= len; | 1401 | vma->vm_pgoff -= mmio_pgoff; |
1402 | if (info->var.accel_flags) { | ||
1403 | mutex_unlock(&info->mm_lock); | ||
1404 | return -EINVAL; | ||
1405 | } | ||
1406 | start = info->fix.mmio_start; | 1402 | start = info->fix.mmio_start; |
1407 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); | 1403 | len = info->fix.mmio_len; |
1408 | } | 1404 | } |
1409 | mutex_unlock(&info->mm_lock); | 1405 | mutex_unlock(&info->mm_lock); |
1410 | start &= PAGE_MASK; | 1406 | |
1411 | if ((vma->vm_end - vma->vm_start + off) > len) | ||
1412 | return -EINVAL; | ||
1413 | off += start; | ||
1414 | vma->vm_pgoff = off >> PAGE_SHIFT; | ||
1415 | /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/ | ||
1416 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 1407 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
1417 | fb_pgprotect(file, vma, off); | 1408 | fb_pgprotect(file, vma, start); |
1418 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 1409 | |
1419 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) | 1410 | return vm_iomap_memory(vma, start, len); |
1420 | return -EAGAIN; | ||
1421 | return 0; | ||
1422 | } | 1411 | } |
1423 | 1412 | ||
1424 | static int | 1413 | static int |