backlight: Fix external uses of backlight internal semaphore

backlight_device->sem has a very specific use as documented in the
header file. The external users of this are using it for a different
reason, to serialise access to the update_status() method.

backlight users were supposed to implement their own internal
serialisation of update_status() if needed but everyone is doing
things differently and incorrectly. Therefore add a global mutex to
take care of serialisation for everyone, once and for all.

Locking for get_brightness remains optional since most users don't
need it.

Also update the lcd class in a similar way.

Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 1fa211c..5d8f73b 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1807,10 +1807,8 @@
 	mutex_lock(&info->bl_mutex);
 
 	if (info->bl_dev) {
-		down(&info->bl_dev->sem);
 		info->bl_dev->props->power = power;
 		__aty128_bl_update_status(info->bl_dev);
-		up(&info->bl_dev->sem);
 	}
 
 	mutex_unlock(&info->bl_mutex);
@@ -1847,11 +1845,9 @@
 		219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 	mutex_unlock(&info->bl_mutex);
 
-	down(&bd->sem);
 	bd->props->brightness = aty128_bl_data.max_brightness;
 	bd->props->power = FB_BLANK_UNBLANK;
-	bd->props->update_status(bd);
-	up(&bd->sem);
+	backlight_update_status(bd);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 5ea5a00..23deb35 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2188,10 +2188,8 @@
 	mutex_lock(&info->bl_mutex);
 
 	if (info->bl_dev) {
-		down(&info->bl_dev->sem);
 		info->bl_dev->props->power = power;
 		__aty_bl_update_status(info->bl_dev);
-		up(&info->bl_dev->sem);
 	}
 
 	mutex_unlock(&info->bl_mutex);
@@ -2224,11 +2222,9 @@
 		0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
 	mutex_unlock(&info->bl_mutex);
 
-	down(&bd->sem);
 	bd->props->brightness = aty_bl_data.max_brightness;
 	bd->props->power = FB_BLANK_UNBLANK;
-	bd->props->update_status(bd);
-	up(&bd->sem);
+	backlight_update_status(bd);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 8b66df6..9cfceca 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -194,11 +194,9 @@
 		217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
 	mutex_unlock(&rinfo->info->bl_mutex);
 
-	down(&bd->sem);
 	bd->props->brightness = radeon_bl_data.max_brightness;
 	bd->props->power = FB_BLANK_UNBLANK;
-	bd->props->update_status(bd);
-	up(&bd->sem);
+	backlight_update_status(bd);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 7a85be4..347081d 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -37,8 +37,7 @@
 		if (!bd->props->check_fb ||
 		    bd->props->check_fb(evdata->info)) {
 			bd->props->fb_blank = *(int *)evdata->data;
-			if (bd->props && bd->props->update_status)
-				bd->props->update_status(bd);
+			backlight_update_status(bd);
 		}
 	up(&bd->sem);
 	return 0;
@@ -97,8 +96,7 @@
 	if (bd->props) {
 		pr_debug("backlight: set power to %d\n", power);
 		bd->props->power = power;
-		if (bd->props->update_status)
-			bd->props->update_status(bd);
+		backlight_update_status(bd);
 		rc = count;
 	}
 	up(&bd->sem);
@@ -140,8 +138,7 @@
 			pr_debug("backlight: set brightness to %d\n",
 				 brightness);
 			bd->props->brightness = brightness;
-			if (bd->props->update_status)
-				bd->props->update_status(bd);
+			backlight_update_status(bd);
 			rc = count;
 		}
 	}
@@ -230,6 +227,7 @@
 	if (!new_bd)
 		return ERR_PTR(-ENOMEM);
 
+	mutex_init(&new_bd->update_lock);
 	init_MUTEX(&new_bd->sem);
 	new_bd->props = bp;
 	memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev));
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 9590248..1e1e61a 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -198,6 +198,7 @@
 		return ERR_PTR(-ENOMEM);
 
 	init_MUTEX(&new_ld->sem);
+	mutex_init(&new_ld->update_lock);
 	new_ld->props = lp;
 	memset(&new_ld->class_dev, 0, sizeof(new_ld->class_dev));
 	new_ld->class_dev.class = &lcd_class;
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 73cb426..9a656bc 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -153,13 +153,11 @@
 		 * useful at blank = 1 too (saves battery, extends backlight
 		 * life)
 	 	 */
-		down(&pmac_backlight->sem);
 		if (blank)
 			pmac_backlight->props->power = FB_BLANK_POWERDOWN;
 		else
 			pmac_backlight->props->power = FB_BLANK_UNBLANK;
-		pmac_backlight->props->update_status(pmac_backlight);
-		up(&pmac_backlight->sem);
+		backlight_update_status(pmac_backlight);
 	}
 
 	mutex_unlock(&pmac_backlight_mutex);
@@ -415,10 +413,8 @@
 	/* turn on the backlight */
 	mutex_lock(&pmac_backlight_mutex);
 	if (pmac_backlight) {
-		down(&pmac_backlight->sem);
 		pmac_backlight->props->power = FB_BLANK_UNBLANK;
-		pmac_backlight->props->update_status(pmac_backlight);
-		up(&pmac_backlight->sem);
+		backlight_update_status(pmac_backlight);
 	}
 	mutex_unlock(&pmac_backlight_mutex);
 #endif /* CONFIG_PMAC_BACKLIGHT */
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 4254c09..f5e42d0 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -114,10 +114,8 @@
 	mutex_lock(&info->bl_mutex);
 
 	if (info->bl_dev) {
-		down(&info->bl_dev->sem);
 		info->bl_dev->props->power = power;
 		__nvidia_bl_update_status(info->bl_dev);
-		up(&info->bl_dev->sem);
 	}
 
 	mutex_unlock(&info->bl_mutex);
@@ -154,11 +152,9 @@
 		0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 	mutex_unlock(&info->bl_mutex);
 
-	down(&bd->sem);
 	bd->props->brightness = nvidia_bl_data.max_brightness;
 	bd->props->power = FB_BLANK_UNBLANK;
-	bd->props->update_status(bd);
-	up(&bd->sem);
+	backlight_update_status(bd);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index fd82571..b70d18f 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -357,10 +357,8 @@
 	mutex_lock(&info->bl_mutex);
 
 	if (info->bl_dev) {
-		down(&info->bl_dev->sem);
 		info->bl_dev->props->power = power;
 		__riva_bl_update_status(info->bl_dev);
-		up(&info->bl_dev->sem);
 	}
 
 	mutex_unlock(&info->bl_mutex);
@@ -397,11 +395,9 @@
 		FB_BACKLIGHT_MAX);
 	mutex_unlock(&info->bl_mutex);
 
-	down(&bd->sem);
 	bd->props->brightness = riva_bl_data.max_brightness;
 	bd->props->power = FB_BLANK_UNBLANK;
-	bd->props->update_status(bd);
-	up(&bd->sem);
+	backlight_update_status(bd);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	mutex_lock(&pmac_backlight_mutex);