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-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index dccb158..d30b45d 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -85,6 +85,16 @@
 		goto out;
 	}
 
+	/* Take the locks in a specific order to keep lockdep happy */
+	if (old_rg->id < new_rg->id) {
+		omapfb_get_mem_region(old_rg);
+		omapfb_get_mem_region(new_rg);
+	} else if (new_rg->id < old_rg->id) {
+		omapfb_get_mem_region(new_rg);
+		omapfb_get_mem_region(old_rg);
+	} else
+		omapfb_get_mem_region(old_rg);
+
 	if (pi->enabled && !new_rg->size) {
 		/*
 		 * This plane's memory was freed, can't enable it
@@ -136,6 +146,16 @@
 			goto undo;
 	}
 
+	/* Release the locks in a specific order to keep lockdep happy */
+	if (old_rg->id > new_rg->id) {
+		omapfb_put_mem_region(old_rg);
+		omapfb_put_mem_region(new_rg);
+	} else if (new_rg->id > old_rg->id) {
+		omapfb_put_mem_region(new_rg);
+		omapfb_put_mem_region(old_rg);
+	} else
+		omapfb_put_mem_region(old_rg);
+
 	return 0;
 
  undo:
@@ -146,6 +166,15 @@
 
 	ovl->set_overlay_info(ovl, &old_info);
  put_mem:
+	/* Release the locks in a specific order to keep lockdep happy */
+	if (old_rg->id > new_rg->id) {
+		omapfb_put_mem_region(old_rg);
+		omapfb_put_mem_region(new_rg);
+	} else if (new_rg->id > old_rg->id) {
+		omapfb_put_mem_region(new_rg);
+		omapfb_put_mem_region(old_rg);
+	} else
+		omapfb_put_mem_region(old_rg);
  out:
 	dev_err(fbdev->dev, "setup_plane failed\n");
 
@@ -195,10 +224,11 @@
 	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 (rg->size == size && rg->type == mi->type)
 		goto out;
 
@@ -231,7 +261,9 @@
 	}
 
  out:
-	mutex_unlock(&fbi->mm_lock);
+	atomic_dec(&rg->lock_count);
+	up_write(&rg->lock);
+
 	return r;
 }
 
@@ -240,12 +272,14 @@
 	struct omapfb_info *ofbi = FB2OFB(fbi);
 	struct omapfb2_mem_region *rg;
 
-	rg = ofbi->region;
+	rg = omapfb_get_mem_region(ofbi->region);
 	memset(mi, 0, sizeof(*mi));
 
 	mi->size = rg->size;
 	mi->type = rg->type;
 
+	omapfb_put_mem_region(rg);
+
 	return 0;
 }
 
@@ -284,10 +318,14 @@
 	if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE)
 		return -EINVAL;
 
+	omapfb_lock(fbdev);
+
 	d = get_display_data(fbdev, display);
 
-	if (d->update_mode == mode)
+	if (d->update_mode == mode) {
+		omapfb_unlock(fbdev);
 		return 0;
+	}
 
 	r = 0;
 
@@ -303,6 +341,8 @@
 			r = -EINVAL;
 	}
 
+	omapfb_unlock(fbdev);
+
 	return r;
 }
 
@@ -317,10 +357,14 @@
 	if (!display)
 		return -EINVAL;
 
+	omapfb_lock(fbdev);
+
 	d = get_display_data(fbdev, display);
 
 	*mode = d->update_mode;
 
+	omapfb_unlock(fbdev);
+
 	return 0;
 }
 
@@ -380,10 +424,13 @@
 		struct omapfb_color_key *ck)
 {
 	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
 	int r;
 	int i;
 	struct omap_overlay_manager *mgr = NULL;
 
+	omapfb_lock(fbdev);
+
 	for (i = 0; i < ofbi->num_overlays; i++) {
 		if (ofbi->overlays[i]->manager) {
 			mgr = ofbi->overlays[i]->manager;
@@ -398,6 +445,8 @@
 
 	r = _omapfb_set_color_key(mgr, ck);
 err:
+	omapfb_unlock(fbdev);
+
 	return r;
 }
 
@@ -405,10 +454,13 @@
 		struct omapfb_color_key *ck)
 {
 	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
 	struct omap_overlay_manager *mgr = NULL;
 	int r = 0;
 	int i;
 
+	omapfb_lock(fbdev);
+
 	for (i = 0; i < ofbi->num_overlays; i++) {
 		if (ofbi->overlays[i]->manager) {
 			mgr = ofbi->overlays[i]->manager;
@@ -423,6 +475,8 @@
 
 	*ck = omapfb_color_keys[mgr->id];
 err:
+	omapfb_unlock(fbdev);
+
 	return r;
 }
 
@@ -549,8 +603,6 @@
 
 	int r = 0;
 
-	omapfb_lock(fbdev);
-
 	switch (cmd) {
 	case OMAPFB_SYNC_GFX:
 		DBG("ioctl SYNC_GFX\n");
@@ -856,8 +908,6 @@
 		r = -EINVAL;
 	}
 
-	omapfb_unlock(fbdev);
-
 	if (r < 0)
 		DBG("ioctl failed: %d\n", r);