summaryrefslogtreecommitdiff
path: root/drivers/video/omap2/omapfb/omapfb-main.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-13 13:19:05 +0200
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-13 13:19:05 +0200
commit3ed37d9aba486dece93e05d68f691b80ee100900 (patch)
tree3e391eb45694c948c608a9c5ce99bc2cc0b52164 /drivers/video/omap2/omapfb/omapfb-main.c
parentc7e1eae537652330cec3fbf5f8f50000b2f24269 (diff)
downloadlwn-3ed37d9aba486dece93e05d68f691b80ee100900.tar.gz
lwn-3ed37d9aba486dece93e05d68f691b80ee100900.zip
Revert "OMAPFB: simplify locking"
This reverts commit b41deecbda70067b26a3a7704fdf967a7940935b. The simpler locking causes huge latencies when two processes use the omapfb, even if they use different framebuffers. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-main.c')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 948dfb9f3e9b..ca585ef37f25 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -672,6 +672,8 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
DBG("check_fb_var %d\n", ofbi->id);
+ WARN_ON(!atomic_read(&ofbi->region->lock_count));
+
r = fb_mode_to_dss_mode(var, &mode);
if (r) {
DBG("cannot convert var to omap dss mode\n");
@@ -853,6 +855,8 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
int rotation = var->rotate;
int i;
+ WARN_ON(!atomic_read(&ofbi->region->lock_count));
+
for (i = 0; i < ofbi->num_overlays; i++) {
if (ovl != ofbi->overlays[i])
continue;
@@ -944,6 +948,8 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
fill_fb(fbi);
#endif
+ WARN_ON(!atomic_read(&ofbi->region->lock_count));
+
for (i = 0; i < ofbi->num_overlays; i++) {
ovl = ofbi->overlays[i];
@@ -1002,16 +1008,15 @@ err:
static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
- struct omapfb2_device *fbdev = ofbi->fbdev;
int r;
DBG("check_var(%d)\n", FB2OFB(fbi)->id);
- omapfb_lock(fbdev);
+ omapfb_get_mem_region(ofbi->region);
r = check_fb_var(fbi, var);
- omapfb_unlock(fbdev);
+ omapfb_put_mem_region(ofbi->region);
return r;
}
@@ -1020,12 +1025,11 @@ static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
static int omapfb_set_par(struct fb_info *fbi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
- struct omapfb2_device *fbdev = ofbi->fbdev;
int r;
DBG("set_par(%d)\n", FB2OFB(fbi)->id);
- omapfb_lock(fbdev);
+ omapfb_get_mem_region(ofbi->region);
set_fb_fix(fbi);
@@ -1036,7 +1040,7 @@ static int omapfb_set_par(struct fb_info *fbi)
r = omapfb_apply_changes(fbi, 0);
out:
- omapfb_unlock(fbdev);
+ omapfb_put_mem_region(ofbi->region);
return r;
}
@@ -1045,7 +1049,6 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
- struct omapfb2_device *fbdev = ofbi->fbdev;
struct fb_var_screeninfo new_var;
int r;
@@ -1061,11 +1064,11 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
fbi->var = new_var;
- omapfb_lock(fbdev);
+ omapfb_get_mem_region(ofbi->region);
r = omapfb_apply_changes(fbi, 0);
- omapfb_unlock(fbdev);
+ omapfb_put_mem_region(ofbi->region);
return r;
}
@@ -1074,14 +1077,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 = {
@@ -1105,7 +1112,7 @@ 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;
@@ -1133,9 +1140,13 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
/* 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;
}
@@ -1902,6 +1913,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
ofbi->region = &fbdev->regions[i];
ofbi->region->id = i;
+ init_rwsem(&ofbi->region->lock);
/* assign these early, so that fb alloc can use them */
ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
@@ -1933,8 +1945,12 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
/* setup fb_infos */
for (i = 0; i < fbdev->num_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;
@@ -1966,8 +1982,12 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
for (i = 0; i < fbdev->num_fbs; i++) {
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;