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