diff options
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-sysfs.c')
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-sysfs.c | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c index 5179219128bd..6f9c72cd6bb0 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_mem_region *rg; | ||
52 | enum omap_dss_rotation_type rot_type; | 53 | enum omap_dss_rotation_type rot_type; |
53 | int r; | 54 | int r; |
54 | 55 | ||
@@ -64,9 +65,11 @@ static ssize_t store_rotate_type(struct device *dev, | |||
64 | if (rot_type == ofbi->rotation_type) | 65 | if (rot_type == ofbi->rotation_type) |
65 | goto out; | 66 | goto out; |
66 | 67 | ||
67 | if (ofbi->region.size) { | 68 | rg = omapfb_get_mem_region(ofbi->region); |
69 | |||
70 | if (rg->size) { | ||
68 | r = -EBUSY; | 71 | r = -EBUSY; |
69 | goto out; | 72 | goto put_region; |
70 | } | 73 | } |
71 | 74 | ||
72 | ofbi->rotation_type = rot_type; | 75 | ofbi->rotation_type = rot_type; |
@@ -75,6 +78,8 @@ static ssize_t store_rotate_type(struct device *dev, | |||
75 | * Since the VRAM for this FB is not allocated at the moment we don't | 78 | * Since the VRAM for this FB is not allocated at the moment we don't |
76 | * need to do any further parameter checking at this point. | 79 | * need to do any further parameter checking at this point. |
77 | */ | 80 | */ |
81 | put_region: | ||
82 | omapfb_put_mem_region(rg); | ||
78 | out: | 83 | out: |
79 | unlock_fb_info(fbi); | 84 | unlock_fb_info(fbi); |
80 | 85 | ||
@@ -97,7 +102,7 @@ static ssize_t store_mirror(struct device *dev, | |||
97 | { | 102 | { |
98 | struct fb_info *fbi = dev_get_drvdata(dev); | 103 | struct fb_info *fbi = dev_get_drvdata(dev); |
99 | struct omapfb_info *ofbi = FB2OFB(fbi); | 104 | struct omapfb_info *ofbi = FB2OFB(fbi); |
100 | bool mirror; | 105 | unsigned long mirror; |
101 | int r; | 106 | int r; |
102 | struct fb_var_screeninfo new_var; | 107 | struct fb_var_screeninfo new_var; |
103 | 108 | ||
@@ -111,6 +116,8 @@ static ssize_t store_mirror(struct device *dev, | |||
111 | 116 | ||
112 | ofbi->mirror = mirror; | 117 | ofbi->mirror = mirror; |
113 | 118 | ||
119 | omapfb_get_mem_region(ofbi->region); | ||
120 | |||
114 | memcpy(&new_var, &fbi->var, sizeof(new_var)); | 121 | memcpy(&new_var, &fbi->var, sizeof(new_var)); |
115 | r = check_fb_var(fbi, &new_var); | 122 | r = check_fb_var(fbi, &new_var); |
116 | if (r) | 123 | if (r) |
@@ -125,6 +132,8 @@ static ssize_t store_mirror(struct device *dev, | |||
125 | 132 | ||
126 | r = count; | 133 | r = count; |
127 | out: | 134 | out: |
135 | omapfb_put_mem_region(ofbi->region); | ||
136 | |||
128 | unlock_fb_info(fbi); | 137 | unlock_fb_info(fbi); |
129 | 138 | ||
130 | return r; | 139 | return r; |
@@ -263,11 +272,15 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, | |||
263 | 272 | ||
264 | DBG("detaching %d\n", ofbi->overlays[i]->id); | 273 | DBG("detaching %d\n", ofbi->overlays[i]->id); |
265 | 274 | ||
275 | omapfb_get_mem_region(ofbi->region); | ||
276 | |||
266 | omapfb_overlay_enable(ovl, 0); | 277 | omapfb_overlay_enable(ovl, 0); |
267 | 278 | ||
268 | if (ovl->manager) | 279 | if (ovl->manager) |
269 | ovl->manager->apply(ovl->manager); | 280 | ovl->manager->apply(ovl->manager); |
270 | 281 | ||
282 | omapfb_put_mem_region(ofbi->region); | ||
283 | |||
271 | for (t = i + 1; t < ofbi->num_overlays; t++) { | 284 | for (t = i + 1; t < ofbi->num_overlays; t++) { |
272 | ofbi->rotation[t-1] = ofbi->rotation[t]; | 285 | ofbi->rotation[t-1] = ofbi->rotation[t]; |
273 | ofbi->overlays[t-1] = ofbi->overlays[t]; | 286 | ofbi->overlays[t-1] = ofbi->overlays[t]; |
@@ -300,7 +313,12 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, | |||
300 | } | 313 | } |
301 | 314 | ||
302 | if (added) { | 315 | if (added) { |
316 | omapfb_get_mem_region(ofbi->region); | ||
317 | |||
303 | r = omapfb_apply_changes(fbi, 0); | 318 | r = omapfb_apply_changes(fbi, 0); |
319 | |||
320 | omapfb_put_mem_region(ofbi->region); | ||
321 | |||
304 | if (r) | 322 | if (r) |
305 | goto out; | 323 | goto out; |
306 | } | 324 | } |
@@ -388,7 +406,12 @@ static ssize_t store_overlays_rotate(struct device *dev, | |||
388 | for (i = 0; i < num_ovls; ++i) | 406 | for (i = 0; i < num_ovls; ++i) |
389 | ofbi->rotation[i] = rotation[i]; | 407 | ofbi->rotation[i] = rotation[i]; |
390 | 408 | ||
409 | omapfb_get_mem_region(ofbi->region); | ||
410 | |||
391 | r = omapfb_apply_changes(fbi, 0); | 411 | r = omapfb_apply_changes(fbi, 0); |
412 | |||
413 | omapfb_put_mem_region(ofbi->region); | ||
414 | |||
392 | if (r) | 415 | if (r) |
393 | goto out; | 416 | goto out; |
394 | 417 | ||
@@ -408,7 +431,7 @@ static ssize_t show_size(struct device *dev, | |||
408 | struct fb_info *fbi = dev_get_drvdata(dev); | 431 | struct fb_info *fbi = dev_get_drvdata(dev); |
409 | struct omapfb_info *ofbi = FB2OFB(fbi); | 432 | struct omapfb_info *ofbi = FB2OFB(fbi); |
410 | 433 | ||
411 | return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size); | 434 | return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size); |
412 | } | 435 | } |
413 | 436 | ||
414 | static ssize_t store_size(struct device *dev, struct device_attribute *attr, | 437 | static ssize_t store_size(struct device *dev, struct device_attribute *attr, |
@@ -416,6 +439,8 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, | |||
416 | { | 439 | { |
417 | struct fb_info *fbi = dev_get_drvdata(dev); | 440 | struct fb_info *fbi = dev_get_drvdata(dev); |
418 | struct omapfb_info *ofbi = FB2OFB(fbi); | 441 | struct omapfb_info *ofbi = FB2OFB(fbi); |
442 | struct omapfb2_device *fbdev = ofbi->fbdev; | ||
443 | struct omapfb2_mem_region *rg; | ||
419 | unsigned long size; | 444 | unsigned long size; |
420 | int r; | 445 | int r; |
421 | int i; | 446 | int i; |
@@ -425,15 +450,33 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, | |||
425 | if (!lock_fb_info(fbi)) | 450 | if (!lock_fb_info(fbi)) |
426 | return -ENODEV; | 451 | return -ENODEV; |
427 | 452 | ||
428 | for (i = 0; i < ofbi->num_overlays; i++) { | 453 | rg = ofbi->region; |
429 | if (ofbi->overlays[i]->info.enabled) { | 454 | |
430 | r = -EBUSY; | 455 | down_write_nested(&rg->lock, rg->id); |
431 | goto out; | 456 | atomic_inc(&rg->lock_count); |
457 | |||
458 | if (atomic_read(&rg->map_count)) { | ||
459 | r = -EBUSY; | ||
460 | goto out; | ||
461 | } | ||
462 | |||
463 | for (i = 0; i < fbdev->num_fbs; i++) { | ||
464 | struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]); | ||
465 | int j; | ||
466 | |||
467 | if (ofbi2->region != rg) | ||
468 | continue; | ||
469 | |||
470 | for (j = 0; j < ofbi2->num_overlays; j++) { | ||
471 | if (ofbi2->overlays[j]->info.enabled) { | ||
472 | r = -EBUSY; | ||
473 | goto out; | ||
474 | } | ||
432 | } | 475 | } |
433 | } | 476 | } |
434 | 477 | ||
435 | if (size != ofbi->region.size) { | 478 | if (size != ofbi->region->size) { |
436 | r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type); | 479 | r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type); |
437 | if (r) { | 480 | if (r) { |
438 | dev_err(dev, "realloc fbmem failed\n"); | 481 | dev_err(dev, "realloc fbmem failed\n"); |
439 | goto out; | 482 | goto out; |
@@ -442,6 +485,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, | |||
442 | 485 | ||
443 | r = count; | 486 | r = count; |
444 | out: | 487 | out: |
488 | atomic_dec(&rg->lock_count); | ||
489 | up_write(&rg->lock); | ||
490 | |||
445 | unlock_fb_info(fbi); | 491 | unlock_fb_info(fbi); |
446 | 492 | ||
447 | return r; | 493 | return r; |
@@ -453,7 +499,7 @@ static ssize_t show_phys(struct device *dev, | |||
453 | struct fb_info *fbi = dev_get_drvdata(dev); | 499 | struct fb_info *fbi = dev_get_drvdata(dev); |
454 | struct omapfb_info *ofbi = FB2OFB(fbi); | 500 | struct omapfb_info *ofbi = FB2OFB(fbi); |
455 | 501 | ||
456 | return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr); | 502 | return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr); |
457 | } | 503 | } |
458 | 504 | ||
459 | static ssize_t show_virt(struct device *dev, | 505 | static ssize_t show_virt(struct device *dev, |
@@ -462,7 +508,7 @@ static ssize_t show_virt(struct device *dev, | |||
462 | struct fb_info *fbi = dev_get_drvdata(dev); | 508 | struct fb_info *fbi = dev_get_drvdata(dev); |
463 | struct omapfb_info *ofbi = FB2OFB(fbi); | 509 | struct omapfb_info *ofbi = FB2OFB(fbi); |
464 | 510 | ||
465 | return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr); | 511 | return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr); |
466 | } | 512 | } |
467 | 513 | ||
468 | static struct device_attribute omapfb_attrs[] = { | 514 | static struct device_attribute omapfb_attrs[] = { |