summaryrefslogtreecommitdiff
path: root/drivers/video/omap2/omapfb/omapfb-sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-sysfs.c')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c70
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 5179219128b..6f9c72cd6bb 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,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_mem_region *rg;
enum omap_dss_rotation_type rot_type;
int r;
@@ -64,9 +65,11 @@ static ssize_t store_rotate_type(struct device *dev,
if (rot_type == ofbi->rotation_type)
goto out;
- if (ofbi->region.size) {
+ rg = omapfb_get_mem_region(ofbi->region);
+
+ if (rg->size) {
r = -EBUSY;
- goto out;
+ goto put_region;
}
ofbi->rotation_type = rot_type;
@@ -75,6 +78,8 @@ static ssize_t store_rotate_type(struct device *dev,
* Since the VRAM for this FB is not allocated at the moment we don't
* need to do any further parameter checking at this point.
*/
+put_region:
+ omapfb_put_mem_region(rg);
out:
unlock_fb_info(fbi);
@@ -97,7 +102,7 @@ static ssize_t store_mirror(struct device *dev,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
- bool mirror;
+ unsigned long mirror;
int r;
struct fb_var_screeninfo new_var;
@@ -111,6 +116,8 @@ static ssize_t store_mirror(struct device *dev,
ofbi->mirror = mirror;
+ omapfb_get_mem_region(ofbi->region);
+
memcpy(&new_var, &fbi->var, sizeof(new_var));
r = check_fb_var(fbi, &new_var);
if (r)
@@ -125,6 +132,8 @@ static ssize_t store_mirror(struct device *dev,
r = count;
out:
+ omapfb_put_mem_region(ofbi->region);
+
unlock_fb_info(fbi);
return r;
@@ -263,11 +272,15 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
DBG("detaching %d\n", ofbi->overlays[i]->id);
+ omapfb_get_mem_region(ofbi->region);
+
omapfb_overlay_enable(ovl, 0);
if (ovl->manager)
ovl->manager->apply(ovl->manager);
+ omapfb_put_mem_region(ofbi->region);
+
for (t = i + 1; t < ofbi->num_overlays; t++) {
ofbi->rotation[t-1] = ofbi->rotation[t];
ofbi->overlays[t-1] = ofbi->overlays[t];
@@ -300,7 +313,12 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
}
if (added) {
+ omapfb_get_mem_region(ofbi->region);
+
r = omapfb_apply_changes(fbi, 0);
+
+ omapfb_put_mem_region(ofbi->region);
+
if (r)
goto out;
}
@@ -388,7 +406,12 @@ static ssize_t store_overlays_rotate(struct device *dev,
for (i = 0; i < num_ovls; ++i)
ofbi->rotation[i] = rotation[i];
+ omapfb_get_mem_region(ofbi->region);
+
r = omapfb_apply_changes(fbi, 0);
+
+ omapfb_put_mem_region(ofbi->region);
+
if (r)
goto out;
@@ -408,7 +431,7 @@ static ssize_t show_size(struct device *dev,
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
- return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size);
+ return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
}
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,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+ struct omapfb2_mem_region *rg;
unsigned long size;
int r;
int i;
@@ -425,15 +450,33 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
if (!lock_fb_info(fbi))
return -ENODEV;
- for (i = 0; i < ofbi->num_overlays; i++) {
- if (ofbi->overlays[i]->info.enabled) {
- r = -EBUSY;
- goto out;
+ rg = ofbi->region;
+
+ down_write_nested(&rg->lock, rg->id);
+ atomic_inc(&rg->lock_count);
+
+ if (atomic_read(&rg->map_count)) {
+ r = -EBUSY;
+ goto out;
+ }
+
+ for (i = 0; i < fbdev->num_fbs; i++) {
+ struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
+ int j;
+
+ if (ofbi2->region != rg)
+ continue;
+
+ for (j = 0; j < ofbi2->num_overlays; j++) {
+ if (ofbi2->overlays[j]->info.enabled) {
+ r = -EBUSY;
+ goto out;
+ }
}
}
- if (size != ofbi->region.size) {
- r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type);
+ if (size != ofbi->region->size) {
+ r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type);
if (r) {
dev_err(dev, "realloc fbmem failed\n");
goto out;
@@ -442,6 +485,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
r = count;
out:
+ atomic_dec(&rg->lock_count);
+ up_write(&rg->lock);
+
unlock_fb_info(fbi);
return r;
@@ -453,7 +499,7 @@ static ssize_t show_phys(struct device *dev,
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
- return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr);
+ return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
}
static ssize_t show_virt(struct device *dev,
@@ -462,7 +508,7 @@ static ssize_t show_virt(struct device *dev,
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
- return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr);
+ return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr);
}
static struct device_attribute omapfb_attrs[] = {