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>
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index be5eb07..18fa9e1 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -49,7 +49,6 @@
 {
 	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;
 	int rot_type;
 	int r;
@@ -63,13 +62,12 @@
 
 	if (!lock_fb_info(fbi))
 		return -ENODEV;
-	omapfb_lock(fbdev);
 
 	r = 0;
 	if (rot_type == ofbi->rotation_type)
 		goto out;
 
-	rg = ofbi->region;
+	rg = omapfb_get_mem_region(ofbi->region);
 
 	if (rg->size) {
 		r = -EBUSY;
@@ -83,8 +81,8 @@
 	 * need to do any further parameter checking at this point.
 	 */
 put_region:
+	omapfb_put_mem_region(rg);
 out:
-	omapfb_unlock(fbdev);
 	unlock_fb_info(fbi);
 
 	return r ? r : count;
@@ -106,7 +104,6 @@
 {
 	struct fb_info *fbi = dev_get_drvdata(dev);
 	struct omapfb_info *ofbi = FB2OFB(fbi);
-	struct omapfb2_device *fbdev = ofbi->fbdev;
 	bool mirror;
 	int r;
 	struct fb_var_screeninfo new_var;
@@ -117,10 +114,11 @@
 
 	if (!lock_fb_info(fbi))
 		return -ENODEV;
-	omapfb_lock(fbdev);
 
 	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)
@@ -135,7 +133,8 @@
 
 	r = count;
 out:
-	omapfb_unlock(fbdev);
+	omapfb_put_mem_region(ofbi->region);
+
 	unlock_fb_info(fbi);
 
 	return r;
@@ -274,11 +273,15 @@
 
 		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];
@@ -311,8 +314,12 @@
 	}
 
 	if (added) {
+		omapfb_get_mem_region(ofbi->region);
+
 		r = omapfb_apply_changes(fbi, 0);
 
+		omapfb_put_mem_region(ofbi->region);
+
 		if (r)
 			goto out;
 	}
@@ -330,13 +337,11 @@
 {
 	struct fb_info *fbi = dev_get_drvdata(dev);
 	struct omapfb_info *ofbi = FB2OFB(fbi);
-	struct omapfb2_device *fbdev = ofbi->fbdev;
 	ssize_t l = 0;
 	int t;
 
 	if (!lock_fb_info(fbi))
 		return -ENODEV;
-	omapfb_lock(fbdev);
 
 	for (t = 0; t < ofbi->num_overlays; t++) {
 		l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
@@ -345,7 +350,6 @@
 
 	l += snprintf(buf + l, PAGE_SIZE - l, "\n");
 
-	omapfb_unlock(fbdev);
 	unlock_fb_info(fbi);
 
 	return l;
@@ -356,7 +360,6 @@
 {
 	struct fb_info *fbi = dev_get_drvdata(dev);
 	struct omapfb_info *ofbi = FB2OFB(fbi);
-	struct omapfb2_device *fbdev = ofbi->fbdev;
 	int num_ovls = 0, r, i;
 	int len;
 	bool changed = false;
@@ -368,7 +371,6 @@
 
 	if (!lock_fb_info(fbi))
 		return -ENODEV;
-	omapfb_lock(fbdev);
 
 	if (len > 0) {
 		char *p = (char *)buf;
@@ -405,7 +407,12 @@
 		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;
 
@@ -414,7 +421,6 @@
 
 	r = count;
 out:
-	omapfb_unlock(fbdev);
 	unlock_fb_info(fbi);
 
 	return r;
@@ -425,19 +431,8 @@
 {
 	struct fb_info *fbi = dev_get_drvdata(dev);
 	struct omapfb_info *ofbi = FB2OFB(fbi);
-	struct omapfb2_device *fbdev = ofbi->fbdev;
-	int r;
 
-	if (!lock_fb_info(fbi))
-		return -ENODEV;
-	omapfb_lock(fbdev);
-
-	r = snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
-
-	omapfb_unlock(fbdev);
-	unlock_fb_info(fbi);
-
-	return r;
+	return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
 }
 
 static ssize_t store_size(struct device *dev, struct device_attribute *attr,
@@ -460,15 +455,15 @@
 
 	if (!lock_fb_info(fbi))
 		return -ENODEV;
-	omapfb_lock(fbdev);
 
 	if (display && display->driver->sync)
 		display->driver->sync(display);
 
-	mutex_lock(&fbi->mm_lock);
-
 	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;
@@ -501,8 +496,9 @@
 
 	r = count;
 out:
-	mutex_unlock(&fbi->mm_lock);
-	omapfb_unlock(fbdev);
+	atomic_dec(&rg->lock_count);
+	up_write(&rg->lock);
+
 	unlock_fb_info(fbi);
 
 	return r;
@@ -513,19 +509,8 @@
 {
 	struct fb_info *fbi = dev_get_drvdata(dev);
 	struct omapfb_info *ofbi = FB2OFB(fbi);
-	struct omapfb2_device *fbdev = ofbi->fbdev;
-	int r;
 
-	if (!lock_fb_info(fbi))
-		return -ENODEV;
-	omapfb_lock(fbdev);
-
-	r = snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
-
-	omapfb_unlock(fbdev);
-	unlock_fb_info(fbi);
-
-	return r;
+	return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
 }
 
 static ssize_t show_virt(struct device *dev,
@@ -541,20 +526,11 @@
 		struct device_attribute *attr, char *buf)
 {
 	struct fb_info *fbi = dev_get_drvdata(dev);
-	struct omapfb_info *ofbi = FB2OFB(fbi);
-	struct omapfb2_device *fbdev = ofbi->fbdev;
 	enum omapfb_update_mode mode;
 	int r;
 
-	if (!lock_fb_info(fbi))
-		return -ENODEV;
-	omapfb_lock(fbdev);
-
 	r = omapfb_get_update_mode(fbi, &mode);
 
-	omapfb_unlock(fbdev);
-	unlock_fb_info(fbi);
-
 	if (r)
 		return r;
 
@@ -565,8 +541,6 @@
 		const char *buf, size_t count)
 {
 	struct fb_info *fbi = dev_get_drvdata(dev);
-	struct omapfb_info *ofbi = FB2OFB(fbi);
-	struct omapfb2_device *fbdev = ofbi->fbdev;
 	unsigned mode;
 	int r;
 
@@ -574,17 +548,10 @@
 	if (r)
 		return r;
 
-	if (!lock_fb_info(fbi))
-		return -ENODEV;
-	omapfb_lock(fbdev);
-
 	r = omapfb_set_update_mode(fbi, mode);
 	if (r)
 		return r;
 
-	omapfb_unlock(fbdev);
-	unlock_fb_info(fbi);
-
 	return count;
 }