From 2b96783fd25eb2153cab2fb6ff92b2bacc809bed Mon Sep 17 00:00:00 2001 From: Nitin Kumbhar Date: Thu, 30 Jun 2011 17:53:52 +0530 Subject: video: tegra: add mmap support for framebuffer fb_mmap maps current window so that content of screen is accessible through mmap sys call to user space components. BUG 832288 Change-Id: I10ccb0b70c951f6d43dbd8a7a1e59e86c0ee75e9 Reviewed-on: http://git-master/r/39204 Reviewed-by: Manish Tuteja Tested-by: Manish Tuteja --- drivers/video/tegra/fb.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'drivers/video/tegra/fb.c') diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c index a28ba561477c..9f5bd9a71e68 100644 --- a/drivers/video/tegra/fb.c +++ b/drivers/video/tegra/fb.c @@ -79,10 +79,7 @@ static int tegra_fb_open(struct fb_info *info, int user) { struct tegra_fb_info *tegra_fb = info->par; - if (atomic_xchg(&tegra_fb->in_use, 1)) - return -EBUSY; - - tegra_fb->user_nvmap = NULL; + atomic_inc(&tegra_fb->in_use); return 0; } @@ -92,6 +89,9 @@ static int tegra_fb_release(struct fb_info *info, int user) struct tegra_fb_info *tegra_fb = info->par; struct fb_var_screeninfo *var = &info->var; + if (atomic_dec_return(&tegra_fb->in_use)) + return 0; + flush_workqueue(tegra_fb->flip_wq); if (tegra_fb->win->cur_handle) { @@ -116,8 +116,6 @@ static int tegra_fb_release(struct fb_info *info, int user) tegra_fb->user_nvmap = NULL; } - WARN_ON(!atomic_xchg(&tegra_fb->in_use, 0)); - return 0; } @@ -586,6 +584,26 @@ surf_err: return err; } +static int tegra_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct tegra_fb_info *tegra_fb = info->par; + struct tegra_dc_win *win = tegra_fb->win; + unsigned long size = vma->vm_end - vma->vm_start; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + + if (offset + size > win->size) + return -EINVAL; + + offset += win->phys_addr + win->offset; + + if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, + size, PAGE_READONLY)) + return -EAGAIN; + + vma->vm_flags |= VM_RESERVED; + return 0; +} + /* TODO: implement private window ioctls to set overlay x,y */ static int tegra_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) @@ -674,6 +692,7 @@ static struct fb_ops tegra_fb_ops = { .fb_fillrect = tegra_fb_fillrect, .fb_copyarea = tegra_fb_copyarea, .fb_imageblit = tegra_fb_imageblit, + .fb_mmap = tegra_fb_mmap, .fb_ioctl = tegra_fb_ioctl, }; -- cgit v1.2.3