diff options
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-main.c')
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-main.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 4a0588022b33..eb4338bbaa2b 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1019,36 +1019,48 @@ err: * DO NOT MODIFY PAR */ static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) { + struct omapfb_info *ofbi = FB2OFB(fbi); int r; DBG("check_var(%d)\n", FB2OFB(fbi)->id); + omapfb_get_mem_region(ofbi->region); + r = check_fb_var(fbi, var); + omapfb_put_mem_region(ofbi->region); + return r; } /* set the video mode according to info->var */ static int omapfb_set_par(struct fb_info *fbi) { + struct omapfb_info *ofbi = FB2OFB(fbi); int r; DBG("set_par(%d)\n", FB2OFB(fbi)->id); + omapfb_get_mem_region(ofbi->region); + set_fb_fix(fbi); r = setup_vrfb_rotation(fbi); if (r) - return r; + goto out; r = omapfb_apply_changes(fbi, 0); + out: + omapfb_put_mem_region(ofbi->region); + return r; } static int omapfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) { + struct omapfb_info *ofbi = FB2OFB(fbi); struct fb_var_screeninfo new_var; int r; @@ -1064,8 +1076,12 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var, fbi->var = new_var; + omapfb_get_mem_region(ofbi->region); + r = omapfb_apply_changes(fbi, 0); + omapfb_put_mem_region(ofbi->region); + return r; } @@ -1073,14 +1089,18 @@ static void mmap_user_open(struct vm_area_struct *vma) { struct omapfb2_mem_region *rg = vma->vm_private_data; + omapfb_get_mem_region(rg); atomic_inc(&rg->map_count); + omapfb_put_mem_region(rg); } static void mmap_user_close(struct vm_area_struct *vma) { struct omapfb2_mem_region *rg = vma->vm_private_data; + omapfb_get_mem_region(rg); atomic_dec(&rg->map_count); + omapfb_put_mem_region(rg); } static struct vm_operations_struct mmap_user_ops = { @@ -1096,6 +1116,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) unsigned long off; unsigned long start; u32 len; + int r = -EINVAL; if (vma->vm_end - vma->vm_start == 0) return 0; @@ -1103,14 +1124,14 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) return -EINVAL; off = vma->vm_pgoff << PAGE_SHIFT; - rg = ofbi->region; + rg = omapfb_get_mem_region(ofbi->region); start = omapfb_get_region_paddr(ofbi); len = fix->smem_len; if (off >= len) - return -EINVAL; + goto error; if ((vma->vm_end - vma->vm_start + off) > len) - return -EINVAL; + goto error; off += start; @@ -1122,11 +1143,23 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) vma->vm_ops = &mmap_user_ops; vma->vm_private_data = rg; if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + r = -EAGAIN; + goto error; + } + /* vm_ops.open won't be called for mmap itself. */ atomic_inc(&rg->map_count); + + omapfb_put_mem_region(rg); + return 0; + + error: + omapfb_put_mem_region(ofbi->region); + + return r; } /* Store a single color palette entry into a pseudo palette or the hardware @@ -1897,6 +1930,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) ofbi->region = &fbdev->regions[i]; ofbi->region->id = i; + mutex_init(&ofbi->region->mtx); /* assign these early, so that fb alloc can use them */ ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : @@ -1927,7 +1961,13 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) /* setup fb_infos */ for (i = 0; i < fbdev->num_fbs; i++) { - r = omapfb_fb_init(fbdev, fbdev->fbs[i]); + struct fb_info *fbi = fbdev->fbs[i]; + struct omapfb_info *ofbi = FB2OFB(fbi); + + omapfb_get_mem_region(ofbi->region); + r = omapfb_fb_init(fbdev, fbi); + omapfb_put_mem_region(ofbi->region); + if (r) { dev_err(fbdev->dev, "failed to setup fb_info\n"); return r; @@ -1948,7 +1988,13 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) DBG("framebuffers registered\n"); for (i = 0; i < fbdev->num_fbs; i++) { - r = omapfb_apply_changes(fbdev->fbs[i], 1); + struct fb_info *fbi = fbdev->fbs[i]; + struct omapfb_info *ofbi = FB2OFB(fbi); + + omapfb_get_mem_region(ofbi->region); + r = omapfb_apply_changes(fbi, 1); + omapfb_put_mem_region(ofbi->region); + if (r) { dev_err(fbdev->dev, "failed to change mode\n"); return r; |