| From: Linus Torvalds <torvalds@linux-foundation.org> |
| Date: Fri, 19 Apr 2013 09:57:35 -0700 |
| Subject: vm: convert fb_mmap to vm_iomap_memory() helper |
| |
| commit fc9bbca8f650e5f738af8806317c0a041a48ae4a upstream. |
| |
| This is my example conversion of a few existing mmap users. The |
| fb_mmap() case is a good example because it is a bit more complicated |
| than some: fb_mmap() mmaps one of two different memory areas depending |
| on the page offset of the mmap (but happily there is never any mixing of |
| the two, so the helper function still works). |
| |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| [bwh: Backported to 3.2: fold in the relevant part of commit 314e51b9851b |
| 'mm: kill vma flag VM_RESERVED and mm->reserved_vm counter'] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/drivers/video/fbmem.c |
| +++ b/drivers/video/fbmem.c |
| @@ -1350,15 +1350,12 @@ fb_mmap(struct file *file, struct vm_are |
| { |
| struct fb_info *info = file_fb_info(file); |
| struct fb_ops *fb; |
| - unsigned long off; |
| + unsigned long mmio_pgoff; |
| unsigned long start; |
| u32 len; |
| |
| if (!info) |
| return -ENODEV; |
| - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) |
| - return -EINVAL; |
| - off = vma->vm_pgoff << PAGE_SHIFT; |
| fb = info->fbops; |
| if (!fb) |
| return -ENODEV; |
| @@ -1370,33 +1367,24 @@ fb_mmap(struct file *file, struct vm_are |
| return res; |
| } |
| |
| - /* frame buffer memory */ |
| + /* |
| + * Ugh. This can be either the frame buffer mapping, or |
| + * if pgoff points past it, the mmio mapping. |
| + */ |
| start = info->fix.smem_start; |
| - len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); |
| - if (off >= len) { |
| - /* memory mapped io */ |
| - off -= len; |
| - if (info->var.accel_flags) { |
| - mutex_unlock(&info->mm_lock); |
| - return -EINVAL; |
| - } |
| + len = info->fix.smem_len; |
| + mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; |
| + if (vma->vm_pgoff >= mmio_pgoff) { |
| + vma->vm_pgoff -= mmio_pgoff; |
| start = info->fix.mmio_start; |
| - len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); |
| + len = info->fix.mmio_len; |
| } |
| mutex_unlock(&info->mm_lock); |
| - start &= PAGE_MASK; |
| - if ((vma->vm_end - vma->vm_start + off) > len) |
| - return -EINVAL; |
| - off += start; |
| - vma->vm_pgoff = off >> PAGE_SHIFT; |
| - /* This is an IO map - tell maydump to skip this VMA */ |
| - vma->vm_flags |= VM_IO | VM_RESERVED; |
| + |
| vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
| - fb_pgprotect(file, vma, off); |
| - if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, |
| - vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
| - return -EAGAIN; |
| - return 0; |
| + fb_pgprotect(file, vma, start); |
| + |
| + return vm_iomap_memory(vma, start, len); |
| } |
| |
| static int |