diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 3bb4c0a..1754b51 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -1,5 +1,5 @@
 /*
- *  Backlight Driver for Nvidia 8600 in Macbook Pro
+ *  Backlight Driver for Nvidia 8600/9400M/9600 in Macbook/Macbook Pro
  *
  *  Copyright (c) Red Hat <mjg@redhat.com>
  *  Based on code from Pommed:
@@ -7,6 +7,10 @@
  *  Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
  *  Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
  *
+ *  Copyright (c) 2009 Brian Tarricone <brian@tarricone.org>
+ *  Based on code from nvclock:
+ *  Copyright (C) 2007 Roderick Colenbrander
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
@@ -24,6 +28,7 @@
 #include <linux/err.h>
 #include <linux/dmi.h>
 #include <linux/io.h>
+#include <linux/pci.h>
 
 static struct backlight_device *mbp_backlight_device;
 
@@ -32,6 +37,10 @@ struct dmi_match_data {
 	/* I/O resource to allocate. */
 	unsigned long iostart;
 	unsigned long iolen;
+	/* ... or MMIO region to allocate. */
+	unsigned long memstart;
+	unsigned long memlen;
+	void *membase;
 	/* Backlight operations structure. */
 	struct backlight_ops backlight_ops;
 };
@@ -41,6 +50,8 @@ static int debug;
 module_param_named(debug, debug, int, 0644);
 MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
 
+static /* const */ struct dmi_match_data *driver_data;
+
 /*
  * Implementation for MacBooks with Intel chipset.
  */
@@ -124,10 +135,69 @@ static const struct dmi_match_data nvidia_chipset_data = {
 };
 
 /*
- * DMI matching.
+ * Implementation for MacBooks with Nvidia chipset.  This implementation
+ * hits the PDISPLAY_SOR0_REGS_BRIGHTNESS register which works while X
+ * is running, unlike the other method (this is at least true for
+ * MacBookPro5,5).
+ *
+ * I think this method should work for many Nvidia NV50 chipsets (not just
+ * on MacBookPro5,5, and probably even on non-Apple hardware), but I really
+ * have no idea, so we'll just enable for the Pro5,5 only for now.
+ *
+ * Implementation taken from nvclock's src/backend/nv50.c, which is:
+ * Copyright(C) 2007 Roderick Colenbrander
+ * and released under the terms of the GNU General Public License v2 or later.
  */
-static /* const */ struct dmi_match_data *driver_data;
 
+#define NV_PDISPLAY_OFFSET 0x610000
+#define NV_PDISPLAY_SOR0_REGS_BRIGHTNESS 0xc084
+#define NV_PDISPLAY_SOR0_REGS_BRIGHTNESS_CONTROL_ENABLED 0x80000000
+
+/* leave the driver's max_brightness value at 15 to avoid reworking how
+ * the driver works entirely.  we can just scale to the 'real' max of 1024
+ */
+#define NV_PDISPLAY_BACKLIGHT_MAX  1024
+
+static int nvidia_chipset_send_intensity_mmio(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (debug)
+		printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+		       intensity);
+
+	writel((intensity * NV_PDISPLAY_BACKLIGHT_MAX / 15) | NV_PDISPLAY_SOR0_REGS_BRIGHTNESS_CONTROL_ENABLED,
+		   driver_data->membase + NV_PDISPLAY_OFFSET + NV_PDISPLAY_SOR0_REGS_BRIGHTNESS);
+
+	return 0;
+}
+
+static int nvidia_chipset_get_intensity_mmio(struct backlight_device *bd)
+{
+	int intensity;
+	unsigned int val = readl(driver_data->membase + NV_PDISPLAY_OFFSET + NV_PDISPLAY_SOR0_REGS_BRIGHTNESS);
+
+	if (debug)
+		printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %u\n",
+		       val);
+
+	/* convert to level between 0 and 15 */
+	intensity = (((double)val / NV_PDISPLAY_BACKLIGHT_MAX * 15) + 0.5);
+	return intensity;
+}
+
+static const struct dmi_match_data nvidia_chipset_data_mmio = {
+	.iolen = 0,
+	.backlight_ops		= {
+		.options	= BL_CORE_SUSPENDRESUME,
+		.get_brightness = nvidia_chipset_get_intensity_mmio,
+		.update_status	= nvidia_chipset_send_intensity_mmio
+	}
+};
+
+/*
+ * DMI matching.
+ */
 static int mbp_dmi_match(const struct dmi_system_id *id)
 {
 	driver_data = id->driver_data;
@@ -136,6 +206,32 @@ static int mbp_dmi_match(const struct dmi_system_id *id)
 	return 1;
 }
 
+static int mbp_dmi_match_mmio(const struct dmi_system_id *id)
+{
+	struct pci_dev *pdev = NULL;
+
+	driver_data = id->driver_data;
+
+	printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident);
+
+	while((pdev = pci_get_device(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, pdev))) {
+		if((pdev->class >> 16) != PCI_BASE_CLASS_DISPLAY)  /* XXX: should we use PCI_CLASS_DISPLAY_VGA? */
+			continue;
+
+		driver_data->memstart = pdev->resource[0].start;
+		driver_data->memlen = pdev->resource[0].end - pdev->resource[0].start + 1;
+		if (debug)
+			printk(KERN_DEBUG "Found video device, memstart=0x%lx, memlen=0x%lx\n",
+			       driver_data->memstart, driver_data->memlen);
+		return 1;
+	}
+
+	driver_data = NULL;
+	printk(KERN_ERR "mbp_nvidia_bl: Couldn't find PCI device\n");
+
+	return 0;
+}
+
 static const struct dmi_system_id __initdata mbp_device_table[] = {
 	{
 		.callback	= mbp_dmi_match,
@@ -191,22 +287,41 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
 		},
 		.driver_data	= (void *)&nvidia_chipset_data,
 	},
+	{
+		.callback	= mbp_dmi_match_mmio,
+		.ident		= "MacBookPro 5,5",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"),
+		},
+		.driver_data	= (void *)&nvidia_chipset_data_mmio,
+	},
 	{ }
 };
 
 static int __init mbp_init(void)
 {
-	if (!dmi_check_system(mbp_device_table))
+	if (!dmi_check_system(mbp_device_table) || !driver_data)
 		return -ENODEV;
 
-	if (!request_region(driver_data->iostart, driver_data->iolen, 
-						"Macbook Pro backlight"))
-		return -ENXIO;
+	if (driver_data->iolen != 0) {
+		if (!request_region(driver_data->iostart, driver_data->iolen,
+							"Macbook Pro backlight"))
+			return -ENXIO;
+	} else if (driver_data->memlen != 0) {
+		driver_data->membase = ioremap(driver_data->memstart,
+		                               driver_data->memlen);
+		if (!driver_data->membase)
+			return -ENXIO;
+	}
 
 	mbp_backlight_device = backlight_device_register("mbp_backlight",
 					NULL, NULL, &driver_data->backlight_ops);
 	if (IS_ERR(mbp_backlight_device)) {
-		release_region(driver_data->iostart, driver_data->iolen);
+		if (driver_data->iolen != 0)
+			release_region(driver_data->iostart, driver_data->iolen);
+		else if (driver_data->memlen != 0)
+			iounmap(driver_data->membase);
 		return PTR_ERR(mbp_backlight_device);
 	}
 
@@ -222,7 +337,10 @@ static void __exit mbp_exit(void)
 {
 	backlight_device_unregister(mbp_backlight_device);
 
-	release_region(driver_data->iostart, driver_data->iolen);
+	if (driver_data->iolen != 0)
+		release_region(driver_data->iostart, driver_data->iolen);
+	else if (driver_data->membase)
+		iounmap(driver_data->membase);
 }
 
 module_init(mbp_init);
