aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-13 06:19:05 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-13 06:19:05 -0500
commit3ed37d9aba486dece93e05d68f691b80ee100900 (patch)
tree3e391eb45694c948c608a9c5ce99bc2cc0b52164 /drivers/video/omap2
parentc7e1eae537652330cec3fbf5f8f50000b2f24269 (diff)
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')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c68
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c40
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c87
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h16
4 files changed, 132 insertions, 79 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index dccb158b0d0b..d30b45d72649 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -85,6 +85,16 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
85 goto out; 85 goto out;
86 } 86 }
87 87
88 /* Take the locks in a specific order to keep lockdep happy */
89 if (old_rg->id < new_rg->id) {
90 omapfb_get_mem_region(old_rg);
91 omapfb_get_mem_region(new_rg);
92 } else if (new_rg->id < old_rg->id) {
93 omapfb_get_mem_region(new_rg);
94 omapfb_get_mem_region(old_rg);
95 } else
96 omapfb_get_mem_region(old_rg);
97
88 if (pi->enabled && !new_rg->size) { 98 if (pi->enabled && !new_rg->size) {
89 /* 99 /*
90 * This plane's memory was freed, can't enable it 100 * This plane's memory was freed, can't enable it
@@ -136,6 +146,16 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
136 goto undo; 146 goto undo;
137 } 147 }
138 148
149 /* Release the locks in a specific order to keep lockdep happy */
150 if (old_rg->id > new_rg->id) {
151 omapfb_put_mem_region(old_rg);
152 omapfb_put_mem_region(new_rg);
153 } else if (new_rg->id > old_rg->id) {
154 omapfb_put_mem_region(new_rg);
155 omapfb_put_mem_region(old_rg);
156 } else
157 omapfb_put_mem_region(old_rg);
158
139 return 0; 159 return 0;
140 160
141 undo: 161 undo:
@@ -146,6 +166,15 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
146 166
147 ovl->set_overlay_info(ovl, &old_info); 167 ovl->set_overlay_info(ovl, &old_info);
148 put_mem: 168 put_mem:
169 /* Release the locks in a specific order to keep lockdep happy */
170 if (old_rg->id > new_rg->id) {
171 omapfb_put_mem_region(old_rg);
172 omapfb_put_mem_region(new_rg);
173 } else if (new_rg->id > old_rg->id) {
174 omapfb_put_mem_region(new_rg);
175 omapfb_put_mem_region(old_rg);
176 } else
177 omapfb_put_mem_region(old_rg);
149 out: 178 out:
150 dev_err(fbdev->dev, "setup_plane failed\n"); 179 dev_err(fbdev->dev, "setup_plane failed\n");
151 180
@@ -195,10 +224,11 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
195 if (display && display->driver->sync) 224 if (display && display->driver->sync)
196 display->driver->sync(display); 225 display->driver->sync(display);
197 226
198 mutex_lock(&fbi->mm_lock);
199
200 rg = ofbi->region; 227 rg = ofbi->region;
201 228
229 down_write_nested(&rg->lock, rg->id);
230 atomic_inc(&rg->lock_count);
231
202 if (rg->size == size && rg->type == mi->type) 232 if (rg->size == size && rg->type == mi->type)
203 goto out; 233 goto out;
204 234
@@ -231,7 +261,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
231 } 261 }
232 262
233 out: 263 out:
234 mutex_unlock(&fbi->mm_lock); 264 atomic_dec(&rg->lock_count);
265 up_write(&rg->lock);
266
235 return r; 267 return r;
236} 268}
237 269
@@ -240,12 +272,14 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
240 struct omapfb_info *ofbi = FB2OFB(fbi); 272 struct omapfb_info *ofbi = FB2OFB(fbi);
241 struct omapfb2_mem_region *rg; 273 struct omapfb2_mem_region *rg;
242 274
243 rg = ofbi->region; 275 rg = omapfb_get_mem_region(ofbi->region);
244 memset(mi, 0, sizeof(*mi)); 276 memset(mi, 0, sizeof(*mi));
245 277
246 mi->size = rg->size; 278 mi->size = rg->size;
247 mi->type = rg->type; 279 mi->type = rg->type;
248 280
281 omapfb_put_mem_region(rg);
282
249 return 0; 283 return 0;
250} 284}
251 285
@@ -284,10 +318,14 @@ int omapfb_set_update_mode(struct fb_info *fbi,
284 if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE) 318 if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE)
285 return -EINVAL; 319 return -EINVAL;
286 320
321 omapfb_lock(fbdev);
322
287 d = get_display_data(fbdev, display); 323 d = get_display_data(fbdev, display);
288 324
289 if (d->update_mode == mode) 325 if (d->update_mode == mode) {
326 omapfb_unlock(fbdev);
290 return 0; 327 return 0;
328 }
291 329
292 r = 0; 330 r = 0;
293 331
@@ -303,6 +341,8 @@ int omapfb_set_update_mode(struct fb_info *fbi,
303 r = -EINVAL; 341 r = -EINVAL;
304 } 342 }
305 343
344 omapfb_unlock(fbdev);
345
306 return r; 346 return r;
307} 347}
308 348
@@ -317,10 +357,14 @@ int omapfb_get_update_mode(struct fb_info *fbi,
317 if (!display) 357 if (!display)
318 return -EINVAL; 358 return -EINVAL;
319 359
360 omapfb_lock(fbdev);
361
320 d = get_display_data(fbdev, display); 362 d = get_display_data(fbdev, display);
321 363
322 *mode = d->update_mode; 364 *mode = d->update_mode;
323 365
366 omapfb_unlock(fbdev);
367
324 return 0; 368 return 0;
325} 369}
326 370
@@ -380,10 +424,13 @@ static int omapfb_set_color_key(struct fb_info *fbi,
380 struct omapfb_color_key *ck) 424 struct omapfb_color_key *ck)
381{ 425{
382 struct omapfb_info *ofbi = FB2OFB(fbi); 426 struct omapfb_info *ofbi = FB2OFB(fbi);
427 struct omapfb2_device *fbdev = ofbi->fbdev;
383 int r; 428 int r;
384 int i; 429 int i;
385 struct omap_overlay_manager *mgr = NULL; 430 struct omap_overlay_manager *mgr = NULL;
386 431
432 omapfb_lock(fbdev);
433
387 for (i = 0; i < ofbi->num_overlays; i++) { 434 for (i = 0; i < ofbi->num_overlays; i++) {
388 if (ofbi->overlays[i]->manager) { 435 if (ofbi->overlays[i]->manager) {
389 mgr = ofbi->overlays[i]->manager; 436 mgr = ofbi->overlays[i]->manager;
@@ -398,6 +445,8 @@ static int omapfb_set_color_key(struct fb_info *fbi,
398 445
399 r = _omapfb_set_color_key(mgr, ck); 446 r = _omapfb_set_color_key(mgr, ck);
400err: 447err:
448 omapfb_unlock(fbdev);
449
401 return r; 450 return r;
402} 451}
403 452
@@ -405,10 +454,13 @@ static int omapfb_get_color_key(struct fb_info *fbi,
405 struct omapfb_color_key *ck) 454 struct omapfb_color_key *ck)
406{ 455{
407 struct omapfb_info *ofbi = FB2OFB(fbi); 456 struct omapfb_info *ofbi = FB2OFB(fbi);
457 struct omapfb2_device *fbdev = ofbi->fbdev;
408 struct omap_overlay_manager *mgr = NULL; 458 struct omap_overlay_manager *mgr = NULL;
409 int r = 0; 459 int r = 0;
410 int i; 460 int i;
411 461
462 omapfb_lock(fbdev);
463
412 for (i = 0; i < ofbi->num_overlays; i++) { 464 for (i = 0; i < ofbi->num_overlays; i++) {
413 if (ofbi->overlays[i]->manager) { 465 if (ofbi->overlays[i]->manager) {
414 mgr = ofbi->overlays[i]->manager; 466 mgr = ofbi->overlays[i]->manager;
@@ -423,6 +475,8 @@ static int omapfb_get_color_key(struct fb_info *fbi,
423 475
424 *ck = omapfb_color_keys[mgr->id]; 476 *ck = omapfb_color_keys[mgr->id];
425err: 477err:
478 omapfb_unlock(fbdev);
479
426 return r; 480 return r;
427} 481}
428 482
@@ -549,8 +603,6 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
549 603
550 int r = 0; 604 int r = 0;
551 605
552 omapfb_lock(fbdev);
553
554 switch (cmd) { 606 switch (cmd) {
555 case OMAPFB_SYNC_GFX: 607 case OMAPFB_SYNC_GFX:
556 DBG("ioctl SYNC_GFX\n"); 608 DBG("ioctl SYNC_GFX\n");
@@ -856,8 +908,6 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
856 r = -EINVAL; 908 r = -EINVAL;
857 } 909 }
858 910
859 omapfb_unlock(fbdev);
860
861 if (r < 0) 911 if (r < 0)
862 DBG("ioctl failed: %d\n", r); 912 DBG("ioctl failed: %d\n", r);
863 913
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)
672 672
673 DBG("check_fb_var %d\n", ofbi->id); 673 DBG("check_fb_var %d\n", ofbi->id);
674 674
675 WARN_ON(!atomic_read(&ofbi->region->lock_count));
676
675 r = fb_mode_to_dss_mode(var, &mode); 677 r = fb_mode_to_dss_mode(var, &mode);
676 if (r) { 678 if (r) {
677 DBG("cannot convert var to omap dss mode\n"); 679 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,
853 int rotation = var->rotate; 855 int rotation = var->rotate;
854 int i; 856 int i;
855 857
858 WARN_ON(!atomic_read(&ofbi->region->lock_count));
859
856 for (i = 0; i < ofbi->num_overlays; i++) { 860 for (i = 0; i < ofbi->num_overlays; i++) {
857 if (ovl != ofbi->overlays[i]) 861 if (ovl != ofbi->overlays[i])
858 continue; 862 continue;
@@ -944,6 +948,8 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
944 fill_fb(fbi); 948 fill_fb(fbi);
945#endif 949#endif
946 950
951 WARN_ON(!atomic_read(&ofbi->region->lock_count));
952
947 for (i = 0; i < ofbi->num_overlays; i++) { 953 for (i = 0; i < ofbi->num_overlays; i++) {
948 ovl = ofbi->overlays[i]; 954 ovl = ofbi->overlays[i];
949 955
@@ -1002,16 +1008,15 @@ err:
1002static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 1008static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
1003{ 1009{
1004 struct omapfb_info *ofbi = FB2OFB(fbi); 1010 struct omapfb_info *ofbi = FB2OFB(fbi);
1005 struct omapfb2_device *fbdev = ofbi->fbdev;
1006 int r; 1011 int r;
1007 1012
1008 DBG("check_var(%d)\n", FB2OFB(fbi)->id); 1013 DBG("check_var(%d)\n", FB2OFB(fbi)->id);
1009 1014
1010 omapfb_lock(fbdev); 1015 omapfb_get_mem_region(ofbi->region);
1011 1016
1012 r = check_fb_var(fbi, var); 1017 r = check_fb_var(fbi, var);
1013 1018
1014 omapfb_unlock(fbdev); 1019 omapfb_put_mem_region(ofbi->region);
1015 1020
1016 return r; 1021 return r;
1017} 1022}
@@ -1020,12 +1025,11 @@ static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
1020static int omapfb_set_par(struct fb_info *fbi) 1025static int omapfb_set_par(struct fb_info *fbi)
1021{ 1026{
1022 struct omapfb_info *ofbi = FB2OFB(fbi); 1027 struct omapfb_info *ofbi = FB2OFB(fbi);
1023 struct omapfb2_device *fbdev = ofbi->fbdev;
1024 int r; 1028 int r;
1025 1029
1026 DBG("set_par(%d)\n", FB2OFB(fbi)->id); 1030 DBG("set_par(%d)\n", FB2OFB(fbi)->id);
1027 1031
1028 omapfb_lock(fbdev); 1032 omapfb_get_mem_region(ofbi->region);
1029 1033
1030 set_fb_fix(fbi); 1034 set_fb_fix(fbi);
1031 1035
@@ -1036,7 +1040,7 @@ static int omapfb_set_par(struct fb_info *fbi)
1036 r = omapfb_apply_changes(fbi, 0); 1040 r = omapfb_apply_changes(fbi, 0);
1037 1041
1038 out: 1042 out:
1039 omapfb_unlock(fbdev); 1043 omapfb_put_mem_region(ofbi->region);
1040 1044
1041 return r; 1045 return r;
1042} 1046}
@@ -1045,7 +1049,6 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
1045 struct fb_info *fbi) 1049 struct fb_info *fbi)
1046{ 1050{
1047 struct omapfb_info *ofbi = FB2OFB(fbi); 1051 struct omapfb_info *ofbi = FB2OFB(fbi);
1048 struct omapfb2_device *fbdev = ofbi->fbdev;
1049 struct fb_var_screeninfo new_var; 1052 struct fb_var_screeninfo new_var;
1050 int r; 1053 int r;
1051 1054
@@ -1061,11 +1064,11 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
1061 1064
1062 fbi->var = new_var; 1065 fbi->var = new_var;
1063 1066
1064 omapfb_lock(fbdev); 1067 omapfb_get_mem_region(ofbi->region);
1065 1068
1066 r = omapfb_apply_changes(fbi, 0); 1069 r = omapfb_apply_changes(fbi, 0);
1067 1070
1068 omapfb_unlock(fbdev); 1071 omapfb_put_mem_region(ofbi->region);
1069 1072
1070 return r; 1073 return r;
1071} 1074}
@@ -1074,14 +1077,18 @@ static void mmap_user_open(struct vm_area_struct *vma)
1074{ 1077{
1075 struct omapfb2_mem_region *rg = vma->vm_private_data; 1078 struct omapfb2_mem_region *rg = vma->vm_private_data;
1076 1079
1080 omapfb_get_mem_region(rg);
1077 atomic_inc(&rg->map_count); 1081 atomic_inc(&rg->map_count);
1082 omapfb_put_mem_region(rg);
1078} 1083}
1079 1084
1080static void mmap_user_close(struct vm_area_struct *vma) 1085static void mmap_user_close(struct vm_area_struct *vma)
1081{ 1086{
1082 struct omapfb2_mem_region *rg = vma->vm_private_data; 1087 struct omapfb2_mem_region *rg = vma->vm_private_data;
1083 1088
1089 omapfb_get_mem_region(rg);
1084 atomic_dec(&rg->map_count); 1090 atomic_dec(&rg->map_count);
1091 omapfb_put_mem_region(rg);
1085} 1092}
1086 1093
1087static struct vm_operations_struct mmap_user_ops = { 1094static struct vm_operations_struct mmap_user_ops = {
@@ -1105,7 +1112,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1105 return -EINVAL; 1112 return -EINVAL;
1106 off = vma->vm_pgoff << PAGE_SHIFT; 1113 off = vma->vm_pgoff << PAGE_SHIFT;
1107 1114
1108 rg = ofbi->region; 1115 rg = omapfb_get_mem_region(ofbi->region);
1109 1116
1110 start = omapfb_get_region_paddr(ofbi); 1117 start = omapfb_get_region_paddr(ofbi);
1111 len = fix->smem_len; 1118 len = fix->smem_len;
@@ -1133,9 +1140,13 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1133 /* vm_ops.open won't be called for mmap itself. */ 1140 /* vm_ops.open won't be called for mmap itself. */
1134 atomic_inc(&rg->map_count); 1141 atomic_inc(&rg->map_count);
1135 1142
1143 omapfb_put_mem_region(rg);
1144
1136 return 0; 1145 return 0;
1137 1146
1138 error: 1147 error:
1148 omapfb_put_mem_region(ofbi->region);
1149
1139 return r; 1150 return r;
1140} 1151}
1141 1152
@@ -1902,6 +1913,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1902 1913
1903 ofbi->region = &fbdev->regions[i]; 1914 ofbi->region = &fbdev->regions[i];
1904 ofbi->region->id = i; 1915 ofbi->region->id = i;
1916 init_rwsem(&ofbi->region->lock);
1905 1917
1906 /* assign these early, so that fb alloc can use them */ 1918 /* assign these early, so that fb alloc can use them */
1907 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : 1919 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
@@ -1933,8 +1945,12 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1933 /* setup fb_infos */ 1945 /* setup fb_infos */
1934 for (i = 0; i < fbdev->num_fbs; i++) { 1946 for (i = 0; i < fbdev->num_fbs; i++) {
1935 struct fb_info *fbi = fbdev->fbs[i]; 1947 struct fb_info *fbi = fbdev->fbs[i];
1948 struct omapfb_info *ofbi = FB2OFB(fbi);
1936 1949
1950 omapfb_get_mem_region(ofbi->region);
1937 r = omapfb_fb_init(fbdev, fbi); 1951 r = omapfb_fb_init(fbdev, fbi);
1952 omapfb_put_mem_region(ofbi->region);
1953
1938 if (r) { 1954 if (r) {
1939 dev_err(fbdev->dev, "failed to setup fb_info\n"); 1955 dev_err(fbdev->dev, "failed to setup fb_info\n");
1940 return r; 1956 return r;
@@ -1966,8 +1982,12 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1966 1982
1967 for (i = 0; i < fbdev->num_fbs; i++) { 1983 for (i = 0; i < fbdev->num_fbs; i++) {
1968 struct fb_info *fbi = fbdev->fbs[i]; 1984 struct fb_info *fbi = fbdev->fbs[i];
1985 struct omapfb_info *ofbi = FB2OFB(fbi);
1969 1986
1987 omapfb_get_mem_region(ofbi->region);
1970 r = omapfb_apply_changes(fbi, 1); 1988 r = omapfb_apply_changes(fbi, 1);
1989 omapfb_put_mem_region(ofbi->region);
1990
1971 if (r) { 1991 if (r) {
1972 dev_err(fbdev->dev, "failed to change mode\n"); 1992 dev_err(fbdev->dev, "failed to change mode\n");
1973 return r; 1993 return r;
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index be5eb074b7d3..18fa9e1d0033 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -49,7 +49,6 @@ static ssize_t store_rotate_type(struct device *dev,
49{ 49{
50 struct fb_info *fbi = dev_get_drvdata(dev); 50 struct fb_info *fbi = dev_get_drvdata(dev);
51 struct omapfb_info *ofbi = FB2OFB(fbi); 51 struct omapfb_info *ofbi = FB2OFB(fbi);
52 struct omapfb2_device *fbdev = ofbi->fbdev;
53 struct omapfb2_mem_region *rg; 52 struct omapfb2_mem_region *rg;
54 int rot_type; 53 int rot_type;
55 int r; 54 int r;
@@ -63,13 +62,12 @@ static ssize_t store_rotate_type(struct device *dev,
63 62
64 if (!lock_fb_info(fbi)) 63 if (!lock_fb_info(fbi))
65 return -ENODEV; 64 return -ENODEV;
66 omapfb_lock(fbdev);
67 65
68 r = 0; 66 r = 0;
69 if (rot_type == ofbi->rotation_type) 67 if (rot_type == ofbi->rotation_type)
70 goto out; 68 goto out;
71 69
72 rg = ofbi->region; 70 rg = omapfb_get_mem_region(ofbi->region);
73 71
74 if (rg->size) { 72 if (rg->size) {
75 r = -EBUSY; 73 r = -EBUSY;
@@ -83,8 +81,8 @@ static ssize_t store_rotate_type(struct device *dev,
83 * need to do any further parameter checking at this point. 81 * need to do any further parameter checking at this point.
84 */ 82 */
85put_region: 83put_region:
84 omapfb_put_mem_region(rg);
86out: 85out:
87 omapfb_unlock(fbdev);
88 unlock_fb_info(fbi); 86 unlock_fb_info(fbi);
89 87
90 return r ? r : count; 88 return r ? r : count;
@@ -106,7 +104,6 @@ static ssize_t store_mirror(struct device *dev,
106{ 104{
107 struct fb_info *fbi = dev_get_drvdata(dev); 105 struct fb_info *fbi = dev_get_drvdata(dev);
108 struct omapfb_info *ofbi = FB2OFB(fbi); 106 struct omapfb_info *ofbi = FB2OFB(fbi);
109 struct omapfb2_device *fbdev = ofbi->fbdev;
110 bool mirror; 107 bool mirror;
111 int r; 108 int r;
112 struct fb_var_screeninfo new_var; 109 struct fb_var_screeninfo new_var;
@@ -117,10 +114,11 @@ static ssize_t store_mirror(struct device *dev,
117 114
118 if (!lock_fb_info(fbi)) 115 if (!lock_fb_info(fbi))
119 return -ENODEV; 116 return -ENODEV;
120 omapfb_lock(fbdev);
121 117
122 ofbi->mirror = mirror; 118 ofbi->mirror = mirror;
123 119
120 omapfb_get_mem_region(ofbi->region);
121
124 memcpy(&new_var, &fbi->var, sizeof(new_var)); 122 memcpy(&new_var, &fbi->var, sizeof(new_var));
125 r = check_fb_var(fbi, &new_var); 123 r = check_fb_var(fbi, &new_var);
126 if (r) 124 if (r)
@@ -135,7 +133,8 @@ static ssize_t store_mirror(struct device *dev,
135 133
136 r = count; 134 r = count;
137out: 135out:
138 omapfb_unlock(fbdev); 136 omapfb_put_mem_region(ofbi->region);
137
139 unlock_fb_info(fbi); 138 unlock_fb_info(fbi);
140 139
141 return r; 140 return r;
@@ -274,11 +273,15 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
274 273
275 DBG("detaching %d\n", ofbi->overlays[i]->id); 274 DBG("detaching %d\n", ofbi->overlays[i]->id);
276 275
276 omapfb_get_mem_region(ofbi->region);
277
277 omapfb_overlay_enable(ovl, 0); 278 omapfb_overlay_enable(ovl, 0);
278 279
279 if (ovl->manager) 280 if (ovl->manager)
280 ovl->manager->apply(ovl->manager); 281 ovl->manager->apply(ovl->manager);
281 282
283 omapfb_put_mem_region(ofbi->region);
284
282 for (t = i + 1; t < ofbi->num_overlays; t++) { 285 for (t = i + 1; t < ofbi->num_overlays; t++) {
283 ofbi->rotation[t-1] = ofbi->rotation[t]; 286 ofbi->rotation[t-1] = ofbi->rotation[t];
284 ofbi->overlays[t-1] = ofbi->overlays[t]; 287 ofbi->overlays[t-1] = ofbi->overlays[t];
@@ -311,8 +314,12 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
311 } 314 }
312 315
313 if (added) { 316 if (added) {
317 omapfb_get_mem_region(ofbi->region);
318
314 r = omapfb_apply_changes(fbi, 0); 319 r = omapfb_apply_changes(fbi, 0);
315 320
321 omapfb_put_mem_region(ofbi->region);
322
316 if (r) 323 if (r)
317 goto out; 324 goto out;
318 } 325 }
@@ -330,13 +337,11 @@ static ssize_t show_overlays_rotate(struct device *dev,
330{ 337{
331 struct fb_info *fbi = dev_get_drvdata(dev); 338 struct fb_info *fbi = dev_get_drvdata(dev);
332 struct omapfb_info *ofbi = FB2OFB(fbi); 339 struct omapfb_info *ofbi = FB2OFB(fbi);
333 struct omapfb2_device *fbdev = ofbi->fbdev;
334 ssize_t l = 0; 340 ssize_t l = 0;
335 int t; 341 int t;
336 342
337 if (!lock_fb_info(fbi)) 343 if (!lock_fb_info(fbi))
338 return -ENODEV; 344 return -ENODEV;
339 omapfb_lock(fbdev);
340 345
341 for (t = 0; t < ofbi->num_overlays; t++) { 346 for (t = 0; t < ofbi->num_overlays; t++) {
342 l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", 347 l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
@@ -345,7 +350,6 @@ static ssize_t show_overlays_rotate(struct device *dev,
345 350
346 l += snprintf(buf + l, PAGE_SIZE - l, "\n"); 351 l += snprintf(buf + l, PAGE_SIZE - l, "\n");
347 352
348 omapfb_unlock(fbdev);
349 unlock_fb_info(fbi); 353 unlock_fb_info(fbi);
350 354
351 return l; 355 return l;
@@ -356,7 +360,6 @@ static ssize_t store_overlays_rotate(struct device *dev,
356{ 360{
357 struct fb_info *fbi = dev_get_drvdata(dev); 361 struct fb_info *fbi = dev_get_drvdata(dev);
358 struct omapfb_info *ofbi = FB2OFB(fbi); 362 struct omapfb_info *ofbi = FB2OFB(fbi);
359 struct omapfb2_device *fbdev = ofbi->fbdev;
360 int num_ovls = 0, r, i; 363 int num_ovls = 0, r, i;
361 int len; 364 int len;
362 bool changed = false; 365 bool changed = false;
@@ -368,7 +371,6 @@ static ssize_t store_overlays_rotate(struct device *dev,
368 371
369 if (!lock_fb_info(fbi)) 372 if (!lock_fb_info(fbi))
370 return -ENODEV; 373 return -ENODEV;
371 omapfb_lock(fbdev);
372 374
373 if (len > 0) { 375 if (len > 0) {
374 char *p = (char *)buf; 376 char *p = (char *)buf;
@@ -405,7 +407,12 @@ static ssize_t store_overlays_rotate(struct device *dev,
405 for (i = 0; i < num_ovls; ++i) 407 for (i = 0; i < num_ovls; ++i)
406 ofbi->rotation[i] = rotation[i]; 408 ofbi->rotation[i] = rotation[i];
407 409
410 omapfb_get_mem_region(ofbi->region);
411
408 r = omapfb_apply_changes(fbi, 0); 412 r = omapfb_apply_changes(fbi, 0);
413
414 omapfb_put_mem_region(ofbi->region);
415
409 if (r) 416 if (r)
410 goto out; 417 goto out;
411 418
@@ -414,7 +421,6 @@ static ssize_t store_overlays_rotate(struct device *dev,
414 421
415 r = count; 422 r = count;
416out: 423out:
417 omapfb_unlock(fbdev);
418 unlock_fb_info(fbi); 424 unlock_fb_info(fbi);
419 425
420 return r; 426 return r;
@@ -425,19 +431,8 @@ static ssize_t show_size(struct device *dev,
425{ 431{
426 struct fb_info *fbi = dev_get_drvdata(dev); 432 struct fb_info *fbi = dev_get_drvdata(dev);
427 struct omapfb_info *ofbi = FB2OFB(fbi); 433 struct omapfb_info *ofbi = FB2OFB(fbi);
428 struct omapfb2_device *fbdev = ofbi->fbdev;
429 int r;
430 434
431 if (!lock_fb_info(fbi)) 435 return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
432 return -ENODEV;
433 omapfb_lock(fbdev);
434
435 r = snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
436
437 omapfb_unlock(fbdev);
438 unlock_fb_info(fbi);
439
440 return r;
441} 436}
442 437
443static ssize_t store_size(struct device *dev, struct device_attribute *attr, 438static ssize_t store_size(struct device *dev, struct device_attribute *attr,
@@ -460,15 +455,15 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
460 455
461 if (!lock_fb_info(fbi)) 456 if (!lock_fb_info(fbi))
462 return -ENODEV; 457 return -ENODEV;
463 omapfb_lock(fbdev);
464 458
465 if (display && display->driver->sync) 459 if (display && display->driver->sync)
466 display->driver->sync(display); 460 display->driver->sync(display);
467 461
468 mutex_lock(&fbi->mm_lock);
469
470 rg = ofbi->region; 462 rg = ofbi->region;
471 463
464 down_write_nested(&rg->lock, rg->id);
465 atomic_inc(&rg->lock_count);
466
472 if (atomic_read(&rg->map_count)) { 467 if (atomic_read(&rg->map_count)) {
473 r = -EBUSY; 468 r = -EBUSY;
474 goto out; 469 goto out;
@@ -501,8 +496,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
501 496
502 r = count; 497 r = count;
503out: 498out:
504 mutex_unlock(&fbi->mm_lock); 499 atomic_dec(&rg->lock_count);
505 omapfb_unlock(fbdev); 500 up_write(&rg->lock);
501
506 unlock_fb_info(fbi); 502 unlock_fb_info(fbi);
507 503
508 return r; 504 return r;
@@ -513,19 +509,8 @@ static ssize_t show_phys(struct device *dev,
513{ 509{
514 struct fb_info *fbi = dev_get_drvdata(dev); 510 struct fb_info *fbi = dev_get_drvdata(dev);
515 struct omapfb_info *ofbi = FB2OFB(fbi); 511 struct omapfb_info *ofbi = FB2OFB(fbi);
516 struct omapfb2_device *fbdev = ofbi->fbdev;
517 int r;
518 512
519 if (!lock_fb_info(fbi)) 513 return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
520 return -ENODEV;
521 omapfb_lock(fbdev);
522
523 r = snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
524
525 omapfb_unlock(fbdev);
526 unlock_fb_info(fbi);
527
528 return r;
529} 514}
530 515
531static ssize_t show_virt(struct device *dev, 516static ssize_t show_virt(struct device *dev,
@@ -541,20 +526,11 @@ static ssize_t show_upd_mode(struct device *dev,
541 struct device_attribute *attr, char *buf) 526 struct device_attribute *attr, char *buf)
542{ 527{
543 struct fb_info *fbi = dev_get_drvdata(dev); 528 struct fb_info *fbi = dev_get_drvdata(dev);
544 struct omapfb_info *ofbi = FB2OFB(fbi);
545 struct omapfb2_device *fbdev = ofbi->fbdev;
546 enum omapfb_update_mode mode; 529 enum omapfb_update_mode mode;
547 int r; 530 int r;
548 531
549 if (!lock_fb_info(fbi))
550 return -ENODEV;
551 omapfb_lock(fbdev);
552
553 r = omapfb_get_update_mode(fbi, &mode); 532 r = omapfb_get_update_mode(fbi, &mode);
554 533
555 omapfb_unlock(fbdev);
556 unlock_fb_info(fbi);
557
558 if (r) 534 if (r)
559 return r; 535 return r;
560 536
@@ -565,8 +541,6 @@ static ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr,
565 const char *buf, size_t count) 541 const char *buf, size_t count)
566{ 542{
567 struct fb_info *fbi = dev_get_drvdata(dev); 543 struct fb_info *fbi = dev_get_drvdata(dev);
568 struct omapfb_info *ofbi = FB2OFB(fbi);
569 struct omapfb2_device *fbdev = ofbi->fbdev;
570 unsigned mode; 544 unsigned mode;
571 int r; 545 int r;
572 546
@@ -574,17 +548,10 @@ static ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr,
574 if (r) 548 if (r)
575 return r; 549 return r;
576 550
577 if (!lock_fb_info(fbi))
578 return -ENODEV;
579 omapfb_lock(fbdev);
580
581 r = omapfb_set_update_mode(fbi, mode); 551 r = omapfb_set_update_mode(fbi, mode);
582 if (r) 552 if (r)
583 return r; 553 return r;
584 554
585 omapfb_unlock(fbdev);
586 unlock_fb_info(fbi);
587
588 return count; 555 return count;
589} 556}
590 557
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 2b5264475ed4..623cd872a367 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -62,6 +62,8 @@ struct omapfb2_mem_region {
62 bool alloc; /* allocated by the driver */ 62 bool alloc; /* allocated by the driver */
63 bool map; /* kernel mapped by the driver */ 63 bool map; /* kernel mapped by the driver */
64 atomic_t map_count; 64 atomic_t map_count;
65 struct rw_semaphore lock;
66 atomic_t lock_count;
65}; 67};
66 68
67/* appended to fb_info */ 69/* appended to fb_info */
@@ -189,4 +191,18 @@ static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
189 return ovl->disable(ovl); 191 return ovl->disable(ovl);
190} 192}
191 193
194static inline struct omapfb2_mem_region *
195omapfb_get_mem_region(struct omapfb2_mem_region *rg)
196{
197 down_read_nested(&rg->lock, rg->id);
198 atomic_inc(&rg->lock_count);
199 return rg;
200}
201
202static inline void omapfb_put_mem_region(struct omapfb2_mem_region *rg)
203{
204 atomic_dec(&rg->lock_count);
205 up_read(&rg->lock);
206}
207
192#endif 208#endif