Index: linux-2.6.16/drivers/video/backlight/backlight.c
===================================================================
--- linux-2.6.16.orig/drivers/video/backlight/backlight.c	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/drivers/video/backlight/backlight.c	2006-03-26 17:46:00.000000000 +0100
@@ -16,14 +16,12 @@
 
 static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
 {
-	int rc;
+	int rc = -ENXIO;
 	struct backlight_device *bd = to_backlight_device(cdev);
 
 	down(&bd->sem);
-	if (likely(bd->props && bd->props->get_power))
-		rc = sprintf(buf, "%d\n", bd->props->get_power(bd));
-	else
-		rc = -ENXIO;
+	if (likely(bd->props))
+		rc = sprintf(buf, "%d\n", bd->props->power);
 	up(&bd->sem);
 
 	return rc;
@@ -31,7 +29,7 @@
 
 static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
 {
-	int rc, power;
+	int rc = -ENXIO, power;
 	char *endp;
 	struct backlight_device *bd = to_backlight_device(cdev);
 
@@ -40,12 +38,13 @@
 		return -EINVAL;
 
 	down(&bd->sem);
-	if (likely(bd->props && bd->props->set_power)) {
+	if (likely(bd->props)) {
 		pr_debug("backlight: set power to %d\n", power);
-		bd->props->set_power(bd, power);
+		bd->props->power = power;
+		if (likely(bd->props->update_status))
+			bd->props->update_status(bd);
 		rc = count;
-	} else
-		rc = -ENXIO;
+	}
 	up(&bd->sem);
 
 	return rc;
@@ -53,14 +52,12 @@
 
 static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
 {
-	int rc;
+	int rc = -ENXIO;
 	struct backlight_device *bd = to_backlight_device(cdev);
 
 	down(&bd->sem);
-	if (likely(bd->props && bd->props->get_brightness))
-		rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd));
-	else
-		rc = -ENXIO;
+	if (likely(bd->props))
+		rc = sprintf(buf, "%d\n", bd->props->brightness);
 	up(&bd->sem);
 
 	return rc;
@@ -68,7 +65,7 @@
 
 static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
 {
-	int rc, brightness;
+	int rc = -ENXIO, brightness;
 	char *endp;
 	struct backlight_device *bd = to_backlight_device(cdev);
 
@@ -77,12 +74,17 @@
 		return -EINVAL;
 
 	down(&bd->sem);
-	if (likely(bd->props && bd->props->set_brightness)) {
-		pr_debug("backlight: set brightness to %d\n", brightness);
-		bd->props->set_brightness(bd, brightness);
-		rc = count;
-	} else
-		rc = -ENXIO;
+	if (likely(bd->props)) {
+		if (brightness > bd->props->max_brightness)
+			rc = -EINVAL;
+		else {
+			pr_debug("backlight: set brightness to %d\n", brightness);
+			bd->props->brightness = brightness;
+			if (likely(bd->props->update_status))
+				bd->props->update_status(bd);
+			rc = count;
+		}
+	}
 	up(&bd->sem);
 
 	return rc;
@@ -90,14 +92,25 @@
 
 static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
 {
-	int rc;
+	int rc = -ENXIO;
 	struct backlight_device *bd = to_backlight_device(cdev);
 
 	down(&bd->sem);
 	if (likely(bd->props))
 		rc = sprintf(buf, "%d\n", bd->props->max_brightness);
-	else
-		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_show_actual_brightness(struct class_device *cdev, char *buf)
+{
+	int rc = -ENXIO;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->get_brightness))
+		rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd));
 	up(&bd->sem);
 
 	return rc;
@@ -124,6 +137,7 @@
 static struct class_device_attribute bl_class_device_attributes[] = {
 	DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
 	DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness),
+	DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness, NULL),
 	DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
 };
 
@@ -144,8 +158,11 @@
 	bd = container_of(self, struct backlight_device, fb_notif);
 	down(&bd->sem);
 	if (bd->props)
-		if (!bd->props->check_fb || bd->props->check_fb(evdata->info))
-			bd->props->set_power(bd, *(int *)evdata->data);
+		if (!bd->props->check_fb || bd->props->check_fb(evdata->info)) {
+			bd->props->fb_blank = *(int *)evdata->data;
+			if (likely(bd->props && bd->props->update_status))
+				bd->props->update_status(bd);
+		}
 	up(&bd->sem);
 	return 0;
 }
@@ -231,6 +248,12 @@
 					 &bl_class_device_attributes[i]);
 
 	down(&bd->sem);
+	if (likely(bd->props && bd->props->update_status)) {
+		bd->props->brightness = 0;
+		bd->props->power = 0;
+		bd->props->update_status(bd);
+	}
+
 	bd->props = NULL;
 	up(&bd->sem);
 
Index: linux-2.6.16/drivers/video/backlight/corgi_bl.c
===================================================================
--- linux-2.6.16.orig/drivers/video/backlight/corgi_bl.c	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/drivers/video/backlight/corgi_bl.c	2006-03-26 23:09:15.000000000 +0100
@@ -25,24 +25,30 @@
 #define CORGI_DEFAULT_INTENSITY		0x1f
 #define CORGI_LIMIT_MASK		0x0b
 
-static int corgibl_powermode = FB_BLANK_UNBLANK;
-static int current_intensity = 0;
-static int corgibl_limit = 0;
+static int corgibl_intensity;
 static void (*corgibl_mach_set_intensity)(int intensity);
 static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
 static struct backlight_properties corgibl_data;
+static struct backlight_device *corgi_backlight_device;
+
+static unsigned long corgibl_flags;
+#define CORGIBL_SUSPENDED     0x01
+#define CORGIBL_BATTLOW       0x02
 
-static void corgibl_send_intensity(int intensity)
+static int corgibl_send_intensity(struct backlight_device *bd)
 {
 	unsigned long flags;
 	void (*corgi_kick_batt)(void);
+	int intensity = bd->props->brightness;
 
-	if (corgibl_powermode != FB_BLANK_UNBLANK) {
+	if (bd->props->power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props->fb_blank != FB_BLANK_UNBLANK)
 		intensity = 0;
-	} else {
-		if (corgibl_limit)
-			intensity &= CORGI_LIMIT_MASK;
-	}
+	if (corgibl_flags & CORGIBL_SUSPENDED)
+		intensity = 0;
+	if (corgibl_flags & CORGIBL_BATTLOW)
+		intensity &= CORGI_LIMIT_MASK;
 
 	spin_lock_irqsave(&bl_lock, flags);
 
@@ -50,45 +56,29 @@
 
 	spin_unlock_irqrestore(&bl_lock, flags);
 
+	corgibl_intensity = intensity;
+
  	corgi_kick_batt = symbol_get(sharpsl_battery_kick);
  	if (corgi_kick_batt) {
  		corgi_kick_batt();
  		symbol_put(sharpsl_battery_kick);
  	}
-}
 
-static void corgibl_blank(int blank)
-{
-	switch(blank) {
-
-	case FB_BLANK_NORMAL:
-	case FB_BLANK_VSYNC_SUSPEND:
-	case FB_BLANK_HSYNC_SUSPEND:
-	case FB_BLANK_POWERDOWN:
-		if (corgibl_powermode == FB_BLANK_UNBLANK) {
-			corgibl_send_intensity(0);
-			corgibl_powermode = blank;
-		}
-		break;
-	case FB_BLANK_UNBLANK:
-		if (corgibl_powermode != FB_BLANK_UNBLANK) {
-			corgibl_powermode = blank;
-			corgibl_send_intensity(current_intensity);
-		}
-		break;
-	}
+	return 0;
 }
 
 #ifdef CONFIG_PM
 static int corgibl_suspend(struct platform_device *dev, pm_message_t state)
 {
-	corgibl_blank(FB_BLANK_POWERDOWN);
+	corgibl_flags |= CORGIBL_SUSPENDED;
+	corgibl_send_intensity(corgi_backlight_device);
 	return 0;
 }
 
 static int corgibl_resume(struct platform_device *dev)
 {
-	corgibl_blank(FB_BLANK_UNBLANK);
+	corgibl_flags &= ~CORGIBL_SUSPENDED;
+	corgibl_send_intensity(corgi_backlight_device);
 	return 0;
 }
 #else
@@ -96,54 +86,38 @@
 #define corgibl_resume	NULL
 #endif
 
-
-static int corgibl_set_power(struct backlight_device *bd, int state)
-{
-	corgibl_blank(state);
-	return 0;
-}
-
-static int corgibl_get_power(struct backlight_device *bd)
+static int corgibl_get_intensity(struct backlight_device *bd)
 {
-	return corgibl_powermode;
+	return corgibl_intensity;
 }
 
-static int corgibl_set_intensity(struct backlight_device *bd, int intensity)
+static int corgibl_set_intensity(struct backlight_device *bd)
 {
-	if (intensity > corgibl_data.max_brightness)
-		intensity = corgibl_data.max_brightness;
-	corgibl_send_intensity(intensity);
-	current_intensity=intensity;
+	corgibl_send_intensity(corgi_backlight_device);
 	return 0;
 }
 
-static int corgibl_get_intensity(struct backlight_device *bd)
-{
-	return current_intensity;
-}
-
 /*
  * Called when the battery is low to limit the backlight intensity.
  * If limit==0 clear any limit, otherwise limit the intensity
  */
 void corgibl_limit_intensity(int limit)
 {
-	corgibl_limit = (limit ? 1 : 0);
-	corgibl_send_intensity(current_intensity);
+	if (limit)
+		corgibl_flags |= CORGIBL_BATTLOW;
+	else
+		corgibl_flags &= ~CORGIBL_BATTLOW;
+	corgibl_send_intensity(corgi_backlight_device);
 }
 EXPORT_SYMBOL(corgibl_limit_intensity);
 
 
 static struct backlight_properties corgibl_data = {
-	.owner		= THIS_MODULE,
-	.get_power      = corgibl_get_power,
-	.set_power      = corgibl_set_power,
+	.owner          = THIS_MODULE,
 	.get_brightness = corgibl_get_intensity,
-	.set_brightness = corgibl_set_intensity,
+	.update_status  = corgibl_set_intensity,
 };
 
-static struct backlight_device *corgi_backlight_device;
-
 static int __init corgibl_probe(struct platform_device *pdev)
 {
 	struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
@@ -156,8 +130,9 @@
 	if (IS_ERR (corgi_backlight_device))
 		return PTR_ERR (corgi_backlight_device);
 
-	corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY);
-	corgibl_limit_intensity(0);
+	corgibl_data.power = FB_BLANK_UNBLANK;
+	corgibl_data.brightness = CORGI_DEFAULT_INTENSITY;
+	corgibl_send_intensity(corgi_backlight_device);
 
 	printk("Corgi Backlight Driver Initialized.\n");
 	return 0;
@@ -167,8 +142,6 @@
 {
 	backlight_device_unregister(corgi_backlight_device);
 
-	corgibl_set_intensity(NULL, 0);
-
 	printk("Corgi Backlight Driver Unloaded\n");
 	return 0;
 }
Index: linux-2.6.16/include/linux/backlight.h
===================================================================
--- linux-2.6.16.orig/include/linux/backlight.h	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/include/linux/backlight.h	2006-03-26 18:38:31.000000000 +0100
@@ -19,20 +19,25 @@
 struct backlight_properties {
 	/* Owner module */
 	struct module *owner;
-	/* Get the backlight power status (0: full on, 1..3: power saving
-	   modes; 4: full off), see FB_BLANK_XXX */
-	int (*get_power)(struct backlight_device *);
-	/* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
-	int (*set_power)(struct backlight_device *, int power);
-	/* Maximal value for brightness (read-only) */
-	int max_brightness;
-	/* Get current backlight brightness */
+
+	/* Notify the backlight driver some property has changed */
+	int (*update_status)(struct backlight_device *);
+	/* Return the current backlight brightness (accounting for power,
+	   fb_blank etc.) */
 	int (*get_brightness)(struct backlight_device *);
-	/* Set backlight brightness (0..max_brightness) */
-	int (*set_brightness)(struct backlight_device *, int brightness);
 	/* Check if given framebuffer device is the one bound to this backlight;
 	   return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
 	int (*check_fb)(struct fb_info *);
+
+	/* Current User requested brightness (0 - max_brightness) */
+	int brightness;
+	/* Maximal value for brightness (read-only) */
+	int max_brightness;
+	/* Current FB Power mode (0: full on, 1..3: power saving
+	   modes; 4: full off), see FB_BLANK_XXX */
+	int power;
+	/* FB Blanking is active? */
+	int fb_blank;
 };
 
 struct backlight_device {
Index: linux-2.6.16/drivers/video/backlight/hp680_bl.c
===================================================================
--- linux-2.6.16.orig/drivers/video/backlight/hp680_bl.c	2006-03-20 05:53:29.000000000 +0000
+++ linux-2.6.16/drivers/video/backlight/hp680_bl.c	2006-03-26 18:58:38.000000000 +0100
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
@@ -25,66 +25,58 @@
 #define HP680_MAX_INTENSITY 255
 #define HP680_DEFAULT_INTENSITY 10
 
-static int hp680bl_powermode = FB_BLANK_UNBLANK;
+static int hp680bl_suspended;
 static int current_intensity = 0;
 static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
+static struct backlight_device *hp680_backlight_device;
 
-static void hp680bl_send_intensity(int intensity)
+static void hp680bl_send_intensity(struct backlight_device *bd)
 {
 	unsigned long flags;
+	u16 v;
+	int intensity = bd->props->brightness;
 
-	if (hp680bl_powermode != FB_BLANK_UNBLANK)
+	if (bd->props->power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props->fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (hp680bl_suspended)
 		intensity = 0;
 
 	spin_lock_irqsave(&bl_lock, flags);
-	sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+	if (intensity && current_intensity == 0) {
+		sh_dac_enable(DAC_LCD_BRIGHTNESS);
+		v = inw(HD64461_GPBDR);
+		v &= ~HD64461_GPBDR_LCDOFF;
+		outw(v, HD64461_GPBDR);
+		sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+	} else if (intensity == 0 && current_intensity != 0) {
+		sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+		sh_dac_disable(DAC_LCD_BRIGHTNESS);
+		v = inw(HD64461_GPBDR);
+		v |= HD64461_GPBDR_LCDOFF;
+		outw(v, HD64461_GPBDR);
+	} else if (intensity) {
+		sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+	}
 	spin_unlock_irqrestore(&bl_lock, flags);
-}
-
-static void hp680bl_blank(int blank)
-{
-	u16 v;
 
-	switch(blank) {
-
-	case FB_BLANK_NORMAL:
-	case FB_BLANK_VSYNC_SUSPEND:
-	case FB_BLANK_HSYNC_SUSPEND:
-	case FB_BLANK_POWERDOWN:
-		if (hp680bl_powermode == FB_BLANK_UNBLANK) {
-			hp680bl_send_intensity(0);
-			hp680bl_powermode = blank;
-			sh_dac_disable(DAC_LCD_BRIGHTNESS);
-			v = inw(HD64461_GPBDR);
-			v |= HD64461_GPBDR_LCDOFF;
-			outw(v, HD64461_GPBDR);
-		}
-		break;
-	case FB_BLANK_UNBLANK:
-		if (hp680bl_powermode != FB_BLANK_UNBLANK) {
-			sh_dac_enable(DAC_LCD_BRIGHTNESS);
-			v = inw(HD64461_GPBDR);
-			v &= ~HD64461_GPBDR_LCDOFF;
-			outw(v, HD64461_GPBDR);
-			hp680bl_powermode = blank;
-			hp680bl_send_intensity(current_intensity);
-		}
-		break;
-	}
+	current_intensity = intensity;
 }
 
+
 #ifdef CONFIG_PM
-static int hp680bl_suspend(struct device *dev, pm_message_t state, u32 level)
+static int hp680bl_suspend(struct platform_device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN)
-		hp680bl_blank(FB_BLANK_POWERDOWN);
+	hp680bl_suspended = 1;
+	hp680bl_send_intensity(hp680_backlight_device);
 	return 0;
 }
 
-static int hp680bl_resume(struct device *dev, u32 level)
+static int hp680bl_resume(struct platform_device *dev)
 {
-	if (level == RESUME_POWER_ON)
-		hp680bl_blank(FB_BLANK_UNBLANK);
+	hp680bl_suspended = 0;
+	hp680bl_send_intensity(hp680_backlight_device);
 	return 0;
 }
 #else
@@ -92,24 +84,9 @@
 #define hp680bl_resume	NULL
 #endif
 
-
-static int hp680bl_set_power(struct backlight_device *bd, int state)
-{
-	hp680bl_blank(state);
-	return 0;
-}
-
-static int hp680bl_get_power(struct backlight_device *bd)
-{
-	return hp680bl_powermode;
-}
-
-static int hp680bl_set_intensity(struct backlight_device *bd, int intensity)
+static int hp680bl_set_intensity(struct backlight_device *bd)
 {
-	if (intensity > HP680_MAX_INTENSITY)
-		intensity = HP680_MAX_INTENSITY;
-	hp680bl_send_intensity(intensity);
-	current_intensity = intensity;
+	hp680bl_send_intensity(bd);
 	return 0;
 }
 
@@ -120,65 +97,67 @@
 
 static struct backlight_properties hp680bl_data = {
 	.owner		= THIS_MODULE,
-	.get_power      = hp680bl_get_power,
-	.set_power      = hp680bl_set_power,
 	.max_brightness = HP680_MAX_INTENSITY,
 	.get_brightness = hp680bl_get_intensity,
-	.set_brightness = hp680bl_set_intensity,
+	.update_status  = hp680bl_set_intensity,
 };
 
-static struct backlight_device *hp680_backlight_device;
-
-static int __init hp680bl_probe(struct device *dev)
+static int __init hp680bl_probe(struct platform_device *dev)
 {
 	hp680_backlight_device = backlight_device_register ("hp680-bl",
 		NULL, &hp680bl_data);
 	if (IS_ERR (hp680_backlight_device))
 		return PTR_ERR (hp680_backlight_device);
 
-	hp680bl_set_intensity(NULL, HP680_DEFAULT_INTENSITY);
+	hp680_backlight_device->props->brightness = HP680_DEFAULT_INTENSITY;
+	hp680bl_send_intensity(hp680_backlight_device);
 
 	return 0;
 }
 
-static int hp680bl_remove(struct device *dev)
+static int hp680bl_remove(struct platform_device *dev)
 {
 	backlight_device_unregister(hp680_backlight_device);
 
 	return 0;
 }
 
-static struct device_driver hp680bl_driver = {
-	.name		= "hp680-bl",
-	.bus		= &platform_bus_type,
+static struct platform_driver hp680bl_driver = {
 	.probe		= hp680bl_probe,
 	.remove		= hp680bl_remove,
 	.suspend	= hp680bl_suspend,
 	.resume		= hp680bl_resume,
+	.driver		= {
+		.name	= "hp680-bl",
+	},
 };
 
-static struct platform_device hp680bl_device = {
-	.name	= "hp680-bl",
-	.id	= -1,
-};
+static struct platform_device *hp680bl_device;
 
 static int __init hp680bl_init(void)
 {
 	int ret;
 
-	ret=driver_register(&hp680bl_driver);
+	ret = platform_driver_register(&hp680bl_driver);
 	if (!ret) {
-		ret = platform_device_register(&hp680bl_device);
-		if (ret)
-			driver_unregister(&hp680bl_driver);
+		hp680bl_device = platform_device_alloc("hp680-bl", -1);
+		if (!hp680bl_device)
+			return -ENOMEM;
+
+		ret = platform_device_add(hp680bl_device);
+
+		if (ret) {
+			platform_device_put(hp680bl_device);
+			platform_driver_unregister(&hp680bl_driver);
+		}
 	}
 	return ret;
 }
 
 static void __exit hp680bl_exit(void)
 {
-	platform_device_unregister(&hp680bl_device);
- 	driver_unregister(&hp680bl_driver);
+	platform_device_unregister(hp680bl_device);
+ 	platform_driver_unregister(&hp680bl_driver);
 }
 
 module_init(hp680bl_init);
