summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 10:20:36 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 10:20:36 -0700
commit765426e8ee4c0ab2bc9d44951f4865b8494cdbd0 (patch)
tree2b46ab8953eff175c8d3474a9754c1ab1394e4de /drivers
parent36ec891895020f3bc9953c8b11d079c6d77d76bd (diff)
parent898b054f3eec5921320ae8614b5bdd7b07ea5b43 (diff)
downloadlinux-765426e8ee4c0ab2bc9d44951f4865b8494cdbd0.tar.gz
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (123 commits)
  dock: make dock driver not a module
  ACPI: fix ia64 build warning
  ACPI: hack around sysfs warning with link order
  ACPI suspend: fix build warning when CONFIG_ACPI_SLEEP=n
  intel_menlo: fix build warning
  panasonic-laptop: fix build
  ACPICA: Update version to 20080926
  ACPICA: Add support for zero-length buffer-to-string conversions
  ACPICA: New: Validation for predefined ACPI methods/objects
  ACPICA: Fix for implicit return compatibility
  ACPICA: Fixed a couple memory leaks associated with "implicit return"
  ACPICA: Optimize buffer allocation procedure
  ACPICA: Fix possible memory leak, error exit path
  ACPICA: Fix fault after mem allocation failure in AML parser
  ACPICA: Remove unused ACPI register bit definition
  ACPICA: Update version to 20080829
  ACPICA: Fix possible memory leak in acpi_ns_get_external_pathname
  ACPICA: Cleanup for internal Reference Object
  ACPICA: Update comments - no functional changes
  ACPICA: Update for Reference ACPI_OPERAND_OBJECT
  ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/Kconfig15
-rw-r--r--drivers/acpi/Makefile3
-rw-r--r--drivers/acpi/ac.c4
-rw-r--r--drivers/acpi/acpi_memhotplug.c11
-rw-r--r--drivers/acpi/asus_acpi.c227
-rw-r--r--drivers/acpi/battery.c2
-rw-r--r--drivers/acpi/bay.c411
-rw-r--r--drivers/acpi/bus.c78
-rw-r--r--drivers/acpi/button.c6
-rw-r--r--drivers/acpi/cm_sbs.c8
-rw-r--r--drivers/acpi/container.c4
-rw-r--r--drivers/acpi/debug.c2
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c3
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c83
-rw-r--r--drivers/acpi/dispatcher/dsobject.c62
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c2
-rw-r--r--drivers/acpi/dispatcher/dswexec.c12
-rw-r--r--drivers/acpi/dock.c388
-rw-r--r--drivers/acpi/ec.c400
-rw-r--r--drivers/acpi/executer/exconfig.c123
-rw-r--r--drivers/acpi/executer/exconvrt.c32
-rw-r--r--drivers/acpi/executer/exdump.c87
-rw-r--r--drivers/acpi/executer/exmisc.c14
-rw-r--r--drivers/acpi/executer/exoparg1.c26
-rw-r--r--drivers/acpi/executer/exoparg2.c4
-rw-r--r--drivers/acpi/executer/exresnte.c16
-rw-r--r--drivers/acpi/executer/exresolv.c60
-rw-r--r--drivers/acpi/executer/exresop.c50
-rw-r--r--drivers/acpi/executer/exstore.c61
-rw-r--r--drivers/acpi/executer/exstoren.c3
-rw-r--r--drivers/acpi/fan.c6
-rw-r--r--drivers/acpi/hardware/hwsleep.c44
-rw-r--r--drivers/acpi/namespace/Makefile2
-rw-r--r--drivers/acpi/namespace/nsdump.c5
-rw-r--r--drivers/acpi/namespace/nseval.c73
-rw-r--r--drivers/acpi/namespace/nsnames.c7
-rw-r--r--drivers/acpi/namespace/nspredef.c900
-rw-r--r--drivers/acpi/namespace/nssearch.c2
-rw-r--r--drivers/acpi/namespace/nsxfeval.c78
-rw-r--r--drivers/acpi/namespace/nsxfname.c5
-rw-r--r--drivers/acpi/numa.c2
-rw-r--r--drivers/acpi/osl.c55
-rw-r--r--drivers/acpi/parser/psloop.c2
-rw-r--r--drivers/acpi/parser/psparse.c32
-rw-r--r--drivers/acpi/pci_link.c6
-rw-r--r--drivers/acpi/pci_root.c4
-rw-r--r--drivers/acpi/pci_slot.c10
-rw-r--r--drivers/acpi/power.c74
-rw-r--r--drivers/acpi/processor_core.c6
-rw-r--r--drivers/acpi/processor_idle.c1
-rw-r--r--drivers/acpi/processor_perflib.c30
-rw-r--r--drivers/acpi/processor_throttling.c12
-rw-r--r--drivers/acpi/reboot.c25
-rw-r--r--drivers/acpi/resources/rscalc.c5
-rw-r--r--drivers/acpi/resources/rscreate.c10
-rw-r--r--drivers/acpi/sbs.c2
-rw-r--r--drivers/acpi/sbshc.c6
-rw-r--r--drivers/acpi/scan.c90
-rw-r--r--drivers/acpi/sleep/main.c66
-rw-r--r--drivers/acpi/system.c4
-rw-r--r--drivers/acpi/tables/tbfadt.c32
-rw-r--r--drivers/acpi/tables/tbinstal.c61
-rw-r--r--drivers/acpi/thermal.c57
-rw-r--r--drivers/acpi/toshiba_acpi.c2
-rw-r--r--drivers/acpi/utilities/utalloc.c53
-rw-r--r--drivers/acpi/utilities/utcopy.c29
-rw-r--r--drivers/acpi/utilities/utdelete.c12
-rw-r--r--drivers/acpi/utilities/utglobal.c52
-rw-r--r--drivers/acpi/utilities/utmisc.c9
-rw-r--r--drivers/acpi/utilities/utobject.c15
-rw-r--r--drivers/acpi/utilities/utxface.c7
-rw-r--r--drivers/acpi/utils.c4
-rw-r--r--drivers/acpi/video.c60
-rw-r--r--drivers/acpi/wmi.c49
-rw-r--r--drivers/ata/libata-acpi.c135
-rw-r--r--drivers/cpuidle/cpuidle.c9
-rw-r--r--drivers/dma/ioat_dma.c3
-rw-r--r--drivers/idle/Kconfig16
-rw-r--r--drivers/idle/Makefile2
-rw-r--r--drivers/idle/i7300_idle.c674
-rw-r--r--drivers/misc/Kconfig12
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/acer-wmi.c225
-rw-r--r--drivers/misc/asus-laptop.c17
-rw-r--r--drivers/misc/eeepc-laptop.c232
-rw-r--r--drivers/misc/fujitsu-laptop.c135
-rw-r--r--drivers/misc/intel_menlow.c31
-rw-r--r--drivers/misc/panasonic-laptop.c767
-rw-r--r--drivers/misc/sony-laptop.c2
-rw-r--r--drivers/misc/thinkpad_acpi.c65
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c20
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c2
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c4
-rw-r--r--drivers/pnp/Kconfig20
-rw-r--r--drivers/pnp/Makefile4
-rw-r--r--drivers/pnp/base.h10
-rw-r--r--drivers/pnp/core.c29
-rw-r--r--drivers/pnp/driver.c4
-rw-r--r--drivers/pnp/isapnp/Makefile4
-rw-r--r--drivers/pnp/isapnp/core.c12
-rw-r--r--drivers/pnp/manager.c34
-rw-r--r--drivers/pnp/pnpacpi/Makefile4
-rw-r--r--drivers/pnp/pnpacpi/core.c16
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c43
-rw-r--r--drivers/pnp/pnpbios/Makefile4
-rw-r--r--drivers/pnp/pnpbios/core.c4
-rw-r--r--drivers/pnp/pnpbios/rsparser.c18
-rw-r--r--drivers/pnp/quirks.c5
-rw-r--r--drivers/pnp/resource.c12
-rw-r--r--drivers/pnp/support.c14
111 files changed, 4929 insertions, 1864 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index cadc64fe8f68..2503f7b99b2f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_EISA)		+= eisa/
 obj-y				+= lguest/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle/
+obj-y				+= idle/
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_MEMSTICK)		+= memstick/
 obj-$(CONFIG_NEW_LEDS)		+= leds/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index da49b006bcc5..f4f632917509 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -42,7 +42,7 @@ if ACPI
 
 config ACPI_SLEEP
 	bool
-	depends on PM_SLEEP
+	depends on SUSPEND || HIBERNATION
 	default y
 
 config ACPI_PROCFS
@@ -157,18 +157,11 @@ config ACPI_FAN
 	  applications to perform basic fan control (on, off, status).
 
 config ACPI_DOCK
-	tristate "Dock"
+	bool "Dock"
 	depends on EXPERIMENTAL
 	help
-	  This driver adds support for ACPI controlled docking stations
-
-config ACPI_BAY
-	tristate "Removable Drive Bay (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	depends on ACPI_DOCK
-	help
-	  This driver adds support for ACPI controlled removable drive
-	  bays such as the IBM ultrabay or the Dell Module Bay.
+	  This driver adds support for ACPI controlled docking stations and removable
+	  drive bays such as the IBM ultrabay or the Dell Module Bay.
 
 config ACPI_PROCESSOR
 	tristate "Processor"
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 52a4cd4b81d0..d91c027ece8f 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -45,14 +45,13 @@ obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
 obj-$(CONFIG_ACPI_DOCK)		+= dock.o
-obj-$(CONFIG_ACPI_BAY)		+= bay.o
 obj-$(CONFIG_ACPI_VIDEO)	+= video.o
 obj-y				+= pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_PCI_SLOT)	+= pci_slot.o
-obj-$(CONFIG_ACPI_POWER)	+= power.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
 obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
+obj-$(CONFIG_ACPI_POWER)	+= power.o
 obj-$(CONFIG_ACPI_SYSTEM)	+= system.o event.o
 obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
 obj-$(CONFIG_ACPI_NUMA)		+= numa.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 831883b7d6c9..d72a1b6c8a94 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -85,7 +85,7 @@ struct acpi_ac {
 	struct power_supply charger;
 #endif
 	struct acpi_device * device;
-	unsigned long state;
+	unsigned long long state;
 };
 
 #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
@@ -269,7 +269,7 @@ static int acpi_ac_add(struct acpi_device *device)
 	ac->device = device;
 	strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_AC_CLASS);
-	acpi_driver_data(device) = ac;
+	device->driver_data = ac;
 
 	result = acpi_ac_get_state(ac);
 	if (result)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 5f1127ad5a95..71d21c51c45f 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -194,8 +194,7 @@ acpi_memory_get_device(acpi_handle handle,
 
 static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
 {
-	unsigned long current_status;
-
+	unsigned long long current_status;
 
 	/* Get device present/absent information from the _STA */
 	if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA",
@@ -264,7 +263,7 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
 	acpi_status status;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
-	unsigned long current_status;
+	unsigned long long current_status;
 
 
 	/* Issue the _EJ0 command */
@@ -403,7 +402,7 @@ static int acpi_memory_device_add(struct acpi_device *device)
 	mem_device->device = device;
 	sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
 	sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
-	acpi_driver_data(device) = mem_device;
+	device->driver_data = mem_device;
 
 	/* Get the range from the _CRS */
 	result = acpi_memory_get_device_resources(mem_device);
@@ -454,8 +453,8 @@ static int acpi_memory_device_start (struct acpi_device *device)
 		/* call add_memory func */
 		result = acpi_memory_enable_device(mem_device);
 		if (result)
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				"Error in acpi_memory_enable_device\n"));
+			printk(KERN_ERR PREFIX
+				"Error in acpi_memory_enable_device\n");
 	}
 	return result;
 }
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index d3d0886d637f..1e74988c7b2d 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -42,7 +42,7 @@
 
 #define ASUS_ACPI_VERSION "0.30"
 
-#define PROC_ASUS       "asus"	//the directory
+#define PROC_ASUS       "asus"	/* The directory */
 #define PROC_MLED       "mled"
 #define PROC_WLED       "wled"
 #define PROC_TLED       "tled"
@@ -66,10 +66,10 @@
 /*
  * Flags for hotk status
  */
-#define MLED_ON     0x01	//mail LED
-#define WLED_ON     0x02	//wireless LED
-#define TLED_ON     0x04	//touchpad LED
-#define BT_ON       0x08	//internal Bluetooth
+#define MLED_ON     0x01	/* Mail LED */
+#define WLED_ON     0x02	/* Wireless LED */
+#define TLED_ON     0x04	/* Touchpad LED */
+#define BT_ON       0x08	/* Internal Bluetooth */
 
 MODULE_AUTHOR("Julien Lerouge, Karol Kozimor");
 MODULE_DESCRIPTION(ACPI_HOTK_NAME);
@@ -82,28 +82,28 @@ MODULE_PARM_DESC(asus_uid, "UID for entries in /proc/acpi/asus");
 module_param(asus_gid, uint, 0);
 MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus");
 
-/* For each model, all features implemented, 
+/* For each model, all features implemented,
  * those marked with R are relative to HOTK, A for absolute */
 struct model_data {
-	char *name;		//name of the laptop________________A
-	char *mt_mled;		//method to handle mled_____________R
-	char *mled_status;	//node to handle mled reading_______A
-	char *mt_wled;		//method to handle wled_____________R
-	char *wled_status;	//node to handle wled reading_______A
-	char *mt_tled;		//method to handle tled_____________R
-	char *tled_status;	//node to handle tled reading_______A
-	char *mt_ledd;		//method to handle LED display______R
-	char *mt_bt_switch;	//method to switch Bluetooth on/off_R
-	char *bt_status;	//no model currently supports this__?
-	char *mt_lcd_switch;	//method to turn LCD on/off_________A
-	char *lcd_status;	//node to read LCD panel state______A
-	char *brightness_up;	//method to set brightness up_______A
-	char *brightness_down;	//guess what ?______________________A
-	char *brightness_set;	//method to set absolute brightness_R
-	char *brightness_get;	//method to get absolute brightness_R
-	char *brightness_status;	//node to get brightness____________A
-	char *display_set;	//method to set video output________R
-	char *display_get;	//method to get video output________R
+	char *name;		/* name of the laptop________________A */
+	char *mt_mled;		/* method to handle mled_____________R */
+	char *mled_status;	/* node to handle mled reading_______A */
+	char *mt_wled;		/* method to handle wled_____________R */
+	char *wled_status;	/* node to handle wled reading_______A */
+	char *mt_tled;		/* method to handle tled_____________R */
+	char *tled_status;	/* node to handle tled reading_______A */
+	char *mt_ledd;		/* method to handle LED display______R */
+	char *mt_bt_switch;	/* method to switch Bluetooth on/off_R */
+	char *bt_status;	/* no model currently supports this__? */
+	char *mt_lcd_switch;	/* method to turn LCD on/off_________A */
+	char *lcd_status;	/* node to read LCD panel state______A */
+	char *brightness_up;	/* method to set brightness up_______A */
+	char *brightness_down;	/* method to set brightness down ____A */
+	char *brightness_set;	/* method to set absolute brightness_R */
+	char *brightness_get;	/* method to get absolute brightness_R */
+	char *brightness_status;/* node to get brightness____________A */
+	char *display_set;	/* method to set video output________R */
+	char *display_get;	/* method to get video output________R */
 };
 
 /*
@@ -111,41 +111,41 @@ struct model_data {
  * about the hotk device
  */
 struct asus_hotk {
-	struct acpi_device *device;	//the device we are in
-	acpi_handle handle;	//the handle of the hotk device
-	char status;		//status of the hotk, for LEDs, ...
-	u32 ledd_status;	//status of the LED display
-	struct model_data *methods;	//methods available on the laptop
-	u8 brightness;		//brightness level
+	struct acpi_device *device;	/* the device we are in */
+	acpi_handle handle;		/* the handle of the hotk device */
+	char status;			/* status of the hotk, for LEDs */
+	u32 ledd_status;		/* status of the LED display */
+	struct model_data *methods;	/* methods available on the laptop */
+	u8 brightness;			/* brightness level */
 	enum {
-		A1x = 0,	//A1340D, A1300F
-		A2x,		//A2500H
-		A4G,		//A4700G
-		D1x,		//D1
-		L2D,		//L2000D
-		L3C,		//L3800C
-		L3D,		//L3400D
-		L3H,		//L3H, L2000E, L5D
-		L4R,		//L4500R
-		L5x,		//L5800C 
-		L8L,		//L8400L
-		M1A,		//M1300A
-		M2E,		//M2400E, L4400L
-		M6N,		//M6800N, W3400N
-		M6R,		//M6700R, A3000G
-		P30,		//Samsung P30
-		S1x,		//S1300A, but also L1400B and M2400A (L84F)
-		S2x,		//S200 (J1 reported), Victor MP-XP7210
-		W1N,		//W1000N
-		W5A,		//W5A
-		W3V,            //W3030V
-		xxN,		//M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
-		A4S,            //Z81sp
-		//(Centrino)
-		F3Sa,
+		A1x = 0,	/* A1340D, A1300F */
+		A2x,		/* A2500H */
+		A4G,		/* A4700G */
+		D1x,		/* D1 */
+		L2D,		/* L2000D */
+		L3C,		/* L3800C */
+		L3D,		/* L3400D */
+		L3H,		/* L3H, L2000E, L5D */
+		L4R,		/* L4500R */
+		L5x,		/* L5800C */
+		L8L,		/* L8400L */
+		M1A,		/* M1300A */
+		M2E,		/* M2400E, L4400L */
+		M6N,		/* M6800N, W3400N */
+		M6R,		/* M6700R, A3000G */
+		P30,		/* Samsung P30 */
+		S1x,		/* S1300A, but also L1400B and M2400A (L84F) */
+		S2x,		/* S200 (J1 reported), Victor MP-XP7210 */
+		W1N,		/* W1000N */
+		W5A,		/* W5A */
+		W3V,            /* W3030V */
+		xxN,		/* M2400N, M3700N, M5200N, M6800N,
+							 S1300N, S5200N*/
+		A4S,            /* Z81sp */
+		F3Sa,		/* (Centrino) */
 		END_MODEL
-	} model;		//Models currently supported
-	u16 event_count[128];	//count for each event TODO make this better
+	} model;		/* Models currently supported */
+	u16 event_count[128];	/* Count for each event TODO make this better */
 };
 
 /* Here we go */
@@ -459,18 +459,18 @@ static struct acpi_driver asus_hotk_driver = {
 		},
 };
 
-/* 
+/*
  * This function evaluates an ACPI method, given an int as parameter, the
  * method is searched within the scope of the handle, can be NULL. The output
  * of the method is written is output, which can also be NULL
  *
- * returns 1 if write is successful, 0 else. 
+ * returns 1 if write is successful, 0 else.
  */
 static int write_acpi_int(acpi_handle handle, const char *method, int val,
 			  struct acpi_buffer *output)
 {
-	struct acpi_object_list params;	//list of input parameters (an int here)
-	union acpi_object in_obj;	//the only param we use
+	struct acpi_object_list params;	/* list of input parameters (int) */
+	union acpi_object in_obj;	/* the only param we use */
 	acpi_status status;
 
 	params.count = 1;
@@ -507,18 +507,18 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
 {
 	int len = 0;
 	int temp;
-	char buf[16];		//enough for all info
+	char buf[16];		/* enough for all info */
 	/*
-	 * We use the easy way, we don't care of off and count, so we don't set eof
-	 * to 1
+	 * We use the easy way, we don't care of off and count,
+	 * so we don't set eof to 1
 	 */
 
 	len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
 	len += sprintf(page + len, "Model reference    : %s\n",
 		       hotk->methods->name);
-	/* 
-	 * The SFUN method probably allows the original driver to get the list 
-	 * of features supported by a given model. For now, 0x0100 or 0x0800 
+	/*
+	 * The SFUN method probably allows the original driver to get the list
+	 * of features supported by a given model. For now, 0x0100 or 0x0800
 	 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
 	 * The significance of others is yet to be found.
 	 */
@@ -528,7 +528,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
 	/*
 	 * Another value for userspace: the ASYM method returns 0x02 for
 	 * battery low and 0x04 for battery critical, its readings tend to be
-	 * more accurate than those provided by _BST. 
+	 * more accurate than those provided by _BST.
 	 * Note: since not all the laptops provide this method, errors are
 	 * silently ignored.
 	 */
@@ -579,7 +579,7 @@ static int read_led(const char *ledname, int ledmask)
 	return (hotk->status & ledmask) ? 1 : 0;
 }
 
-static int parse_arg(const char __user * buf, unsigned long count, int *val)
+static int parse_arg(const char __user *buf, unsigned long count, int *val)
 {
 	char s[32];
 	if (!count)
@@ -596,7 +596,7 @@ static int parse_arg(const char __user * buf, unsigned long count, int *val)
 
 /* FIXME: kill extraneous args so it can be called independently */
 static int
-write_led(const char __user * buffer, unsigned long count,
+write_led(const char __user *buffer, unsigned long count,
 	  char *ledname, int ledmask, int invert)
 {
 	int rv, value;
@@ -631,7 +631,7 @@ proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_mled(struct file *file, const char __user * buffer,
+proc_write_mled(struct file *file, const char __user *buffer,
 		unsigned long count, void *data)
 {
 	return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
@@ -648,7 +648,7 @@ proc_read_ledd(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_ledd(struct file *file, const char __user * buffer,
+proc_write_ledd(struct file *file, const char __user *buffer,
 		unsigned long count, void *data)
 {
 	int rv, value;
@@ -677,7 +677,7 @@ proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_wled(struct file *file, const char __user * buffer,
+proc_write_wled(struct file *file, const char __user *buffer,
 		unsigned long count, void *data)
 {
 	return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
@@ -694,10 +694,10 @@ proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_bluetooth(struct file *file, const char __user * buffer,
+proc_write_bluetooth(struct file *file, const char __user *buffer,
 		     unsigned long count, void *data)
 {
-	/* Note: mt_bt_switch controls both internal Bluetooth adapter's 
+	/* Note: mt_bt_switch controls both internal Bluetooth adapter's
 	   presence and its LED */
 	return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0);
 }
@@ -714,7 +714,7 @@ proc_read_tled(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_tled(struct file *file, const char __user * buffer,
+proc_write_tled(struct file *file, const char __user *buffer,
 		unsigned long count, void *data)
 {
 	return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
@@ -734,7 +734,7 @@ static int get_lcd_state(void)
 
 		input.count = 2;
 		input.pointer = mt_params;
-		/* Note: the following values are partly guessed up, but 
+		/* Note: the following values are partly guessed up, but
 		   otherwise they seem to work */
 		mt_params[0].type = ACPI_TYPE_INTEGER;
 		mt_params[0].integer.value = 0x02;
@@ -753,7 +753,7 @@ static int get_lcd_state(void)
 			/* That's what the AML code does */
 			lcd = out_obj.integer.value >> 8;
 	} else if (hotk->model == F3Sa) {
-		unsigned long tmp;
+		unsigned long long tmp;
 		union acpi_object param;
 		struct acpi_object_list input;
 		acpi_status status;
@@ -796,12 +796,13 @@ static int set_lcd_state(int value)
 			    acpi_evaluate_object(NULL,
 						 hotk->methods->mt_lcd_switch,
 						 NULL, NULL);
-		} else {	/* L3H and the like have to be handled differently */
+		} else {
+			/* L3H and the like must be handled differently */
 			if (!write_acpi_int
 			    (hotk->handle, hotk->methods->mt_lcd_switch, 0x07,
 			     NULL))
 				status = AE_ERROR;
-			/* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, 
+			/* L3H's AML executes EHK (0x07) upon Fn+F7 keypress,
 			   the exact behaviour is simulated here */
 		}
 		if (ACPI_FAILURE(status))
@@ -819,7 +820,7 @@ proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_lcd(struct file *file, const char __user * buffer,
+proc_write_lcd(struct file *file, const char __user *buffer,
 	       unsigned long count, void *data)
 {
 	int rv, value;
@@ -897,7 +898,7 @@ proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
 }
 
 static int
-proc_write_brn(struct file *file, const char __user * buffer,
+proc_write_brn(struct file *file, const char __user *buffer,
 	       unsigned long count, void *data)
 {
 	int rv, value;
@@ -921,7 +922,7 @@ static void set_display(int value)
 }
 
 /*
- * Now, *this* one could be more user-friendly, but so far, no-one has 
+ * Now, *this* one could be more user-friendly, but so far, no-one has
  * complained. The significance of bits is the same as in proc_write_disp()
  */
 static int
@@ -933,18 +934,18 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
 	if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
 		printk(KERN_WARNING
 		       "Asus ACPI: Error reading display status\n");
-	value &= 0x07;		/* needed for some models, shouldn't hurt others */
+	value &= 0x07;	/* needed for some models, shouldn't hurt others */
 	return sprintf(page, "%d\n", value);
 }
 
 /*
- * Experimental support for display switching. As of now: 1 should activate 
- * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination 
- * (bitwise) of these will suffice. I never actually tested 3 displays hooked up 
- * simultaneously, so be warned. See the acpi4asus README for more info.
+ * Experimental support for display switching. As of now: 1 should activate
+ * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination
+ * (bitwise) of these will suffice. I never actually tested 3 displays hooked
+ * up simultaneously, so be warned. See the acpi4asus README for more info.
  */
 static int
-proc_write_disp(struct file *file, const char __user * buffer,
+proc_write_disp(struct file *file, const char __user *buffer,
 		unsigned long count, void *data)
 {
 	int rv, value;
@@ -957,12 +958,12 @@ proc_write_disp(struct file *file, const char __user * buffer,
 
 typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
 			     int *eof, void *data);
-typedef int (proc_writefunc) (struct file * file, const char __user * buffer,
+typedef int (proc_writefunc) (struct file *file, const char __user *buffer,
 			      unsigned long count, void *data);
 
 static int
-asus_proc_add(char *name, proc_writefunc * writefunc,
-		     proc_readfunc * readfunc, mode_t mode,
+asus_proc_add(char *name, proc_writefunc *writefunc,
+		     proc_readfunc *readfunc, mode_t mode,
 		     struct acpi_device *device)
 {
 	struct proc_dir_entry *proc =
@@ -1040,9 +1041,9 @@ static int asus_hotk_add_fs(struct acpi_device *device)
 			      &proc_read_bluetooth, mode, device);
 	}
 
-	/* 
-	 * We need both read node and write method as LCD switch is also accessible
-	 * from keyboard 
+	/*
+	 * We need both read node and write method as LCD switch is also
+	 * accessible from the keyboard
 	 */
 	if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
 		asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode,
@@ -1096,11 +1097,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
 	if (!hotk)
 		return;
 
-	if ((event & ~((u32) BR_UP)) < 16) {
+	if ((event & ~((u32) BR_UP)) < 16)
 		hotk->brightness = (event & ~((u32) BR_UP));
-	} else if ((event & ~((u32) BR_DOWN)) < 16) {
+	else if ((event & ~((u32) BR_DOWN)) < 16)
 		hotk->brightness = (event & ~((u32) BR_DOWN));
-	}
 
 	acpi_bus_generate_proc_event(hotk->device, event,
 				hotk->event_count[event % 128]++);
@@ -1186,8 +1186,8 @@ static int asus_hotk_get_info(void)
 	acpi_status status;
 
 	/*
-	 * Get DSDT headers early enough to allow for differentiating between 
-	 * models, but late enough to allow acpi_bus_register_driver() to fail 
+	 * Get DSDT headers early enough to allow for differentiating between
+	 * models, but late enough to allow acpi_bus_register_driver() to fail
 	 * before doing anything ACPI-specific. Should we encounter a machine,
 	 * which needs special handling (i.e. its hotkey device has a different
 	 * HID), this bit will be moved. A global variable asus_info contains
@@ -1212,8 +1212,8 @@ static int asus_hotk_get_info(void)
 
 	/*
 	 * Try to match the object returned by INIT to the specific model.
-	 * Handle every possible object (or the lack of thereof) the DSDT 
-	 * writers might throw at us. When in trouble, we pass NULL to 
+	 * Handle every possible object (or the lack of thereof) the DSDT
+	 * writers might throw at us. When in trouble, we pass NULL to
 	 * asus_model_match() and try something completely different.
 	 */
 	if (buffer.pointer) {
@@ -1244,6 +1244,8 @@ static int asus_hotk_get_info(void)
 			       "default values\n", string);
 			printk(KERN_NOTICE
 			       "  send /proc/acpi/dsdt to the developers\n");
+			kfree(model);
+			return -ENODEV;
 		}
 		hotk->methods = &model_conf[hotk->model];
 		return AE_OK;
@@ -1254,7 +1256,7 @@ static int asus_hotk_get_info(void)
 	/* Sort of per-model blacklist */
 	if (strncmp(string, "L2B", 3) == 0)
 		hotk->methods->lcd_status = NULL;
-	/* L2B is similar enough to L3C to use its settings, with this only 
+	/* L2B is similar enough to L3C to use its settings, with this only
 	   exception */
 	else if (strncmp(string, "A3G", 3) == 0)
 		hotk->methods->lcd_status = "\\BLFG";
@@ -1321,7 +1323,7 @@ static int asus_hotk_add(struct acpi_device *device)
 	hotk->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_HOTK_CLASS);
-	acpi_driver_data(device) = hotk;
+	device->driver_data = hotk;
 	hotk->device = device;
 
 	result = asus_hotk_check();
@@ -1366,10 +1368,9 @@ static int asus_hotk_add(struct acpi_device *device)
 	/* LED display is off by default */
 	hotk->ledd_status = 0xFFF;
 
-      end:
-	if (result) {
+end:
+	if (result)
 		kfree(hotk);
-	}
 
 	return result;
 }
@@ -1394,8 +1395,8 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
 }
 
 static struct backlight_ops asus_backlight_data = {
-        .get_brightness = read_brightness,
-        .update_status  = set_brightness_status,
+	.get_brightness = read_brightness,
+	.update_status  = set_brightness_status,
 };
 
 static void asus_acpi_exit(void)
@@ -1442,15 +1443,15 @@ static int __init asus_acpi_init(void)
 		return -ENODEV;
 	}
 
-	asus_backlight_device = backlight_device_register("asus",NULL,NULL,
+	asus_backlight_device = backlight_device_register("asus", NULL, NULL,
 							  &asus_backlight_data);
-        if (IS_ERR(asus_backlight_device)) {
+	if (IS_ERR(asus_backlight_device)) {
 		printk(KERN_ERR "Could not register asus backlight device\n");
 		asus_backlight_device = NULL;
 		asus_acpi_exit();
 		return -ENODEV;
 	}
-        asus_backlight_device->props.max_brightness = 15;
+	asus_backlight_device->props.max_brightness = 15;
 
 	return 0;
 }
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 70f7f60929ca..b2133e89ad9a 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -804,7 +804,7 @@ static int acpi_battery_add(struct acpi_device *device)
 	battery->device = device;
 	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
-	acpi_driver_data(device) = battery;
+	device->driver_data = battery;
 	mutex_init(&battery->lock);
 	acpi_battery_update(battery);
 #ifdef CONFIG_ACPI_PROCFS_POWER
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
deleted file mode 100644
index 61b6c5beb2d3..000000000000
--- a/drivers/acpi/bay.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- *  bay.c - ACPI removable drive bay driver
- *
- *  Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/notifier.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
-#include <linux/seq_file.h>
-#include <asm/uaccess.h>
-#include <linux/platform_device.h>
-
-ACPI_MODULE_NAME("bay");
-MODULE_AUTHOR("Kristen Carlson Accardi");
-MODULE_DESCRIPTION("ACPI Removable Drive Bay Driver");
-MODULE_LICENSE("GPL");
-#define ACPI_BAY_CLASS "bay"
-#define ACPI_BAY_COMPONENT	0x10000000
-#define _COMPONENT ACPI_BAY_COMPONENT
-#define bay_dprintk(h,s) {\
-	char prefix[80] = {'\0'};\
-	struct acpi_buffer buffer = {sizeof(prefix), prefix};\
-	acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
-	printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
-static void bay_notify(acpi_handle handle, u32 event, void *data);
-
-static const struct acpi_device_id bay_device_ids[] = {
-	{"LNXIOBAY", 0},
-	{"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, bay_device_ids);
-
-struct bay {
-	acpi_handle handle;
-	char *name;
-	struct list_head list;
-	struct platform_device *pdev;
-};
-
-static LIST_HEAD(drive_bays);
-
-
-/*****************************************************************************
- *                         Drive Bay functions                               *
- *****************************************************************************/
-/**
- * is_ejectable - see if a device is ejectable
- * @handle: acpi handle of the device
- *
- * If an acpi object has a _EJ0 method, then it is ejectable
- */
-static int is_ejectable(acpi_handle handle)
-{
-	acpi_status status;
-	acpi_handle tmp;
-
-	status = acpi_get_handle(handle, "_EJ0", &tmp);
-	if (ACPI_FAILURE(status))
-		return 0;
-	return 1;
-}
-
-/**
- * bay_present - see if the bay device is present
- * @bay: the drive bay
- *
- * execute the _STA method.
- */
-static int bay_present(struct bay *bay)
-{
-	unsigned long sta;
-	acpi_status status;
-
-	if (bay) {
-		status = acpi_evaluate_integer(bay->handle, "_STA", NULL, &sta);
-		if (ACPI_SUCCESS(status) && sta)
-			return 1;
-	}
-	return 0;
-}
-
-/**
- * eject_device - respond to an eject request
- * @handle - the device to eject
- *
- * Call this devices _EJ0 method.
- */
-static void eject_device(acpi_handle handle)
-{
-	struct acpi_object_list arg_list;
-	union acpi_object arg;
-
-	bay_dprintk(handle, "Ejecting device");
-
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = 1;
-
-	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
-					      &arg_list, NULL)))
-		pr_debug("Failed to evaluate _EJ0!\n");
-}
-
-/*
- * show_present - read method for "present" file in sysfs
- */
-static ssize_t show_present(struct device *dev,
-			   struct device_attribute *attr, char *buf)
-{
-	struct bay *bay = dev_get_drvdata(dev);
-	return snprintf(buf, PAGE_SIZE, "%d\n", bay_present(bay));
-
-}
-static DEVICE_ATTR(present, S_IRUGO, show_present, NULL);
-
-/*
- * write_eject - write method for "eject" file in sysfs
- */
-static ssize_t write_eject(struct device *dev, struct device_attribute *attr,
-			   const char *buf, size_t count)
-{
-	struct bay *bay = dev_get_drvdata(dev);
-
-	if (!count)
-		return -EINVAL;
-
-	eject_device(bay->handle);
-	return count;
-}
-static DEVICE_ATTR(eject, S_IWUSR, NULL, write_eject);
-
-/**
- * is_ata - see if a device is an ata device
- * @handle: acpi handle of the device
- *
- * If an acpi object has one of 4 ATA ACPI methods defined,
- * then it is an ATA device
- */
-static int is_ata(acpi_handle handle)
-{
-	acpi_handle tmp;
-
-	if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
-	   (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
-	   (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
-	   (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
-		return 1;
-
-	return 0;
-}
-
-/**
- * parent_is_ata(acpi_handle handle)
- *
- */
-static int parent_is_ata(acpi_handle handle)
-{
-	acpi_handle phandle;
-
-	if (acpi_get_parent(handle, &phandle))
-		return 0;
-
-	return is_ata(phandle);
-}
-
-/**
- * is_ejectable_bay - see if a device is an ejectable drive bay
- * @handle: acpi handle of the device
- *
- * If an acpi object is ejectable and has one of the ACPI ATA
- * methods defined, then we can safely call it an ejectable
- * drive bay
- */
-static int is_ejectable_bay(acpi_handle handle)
-{
-	if ((is_ata(handle) || parent_is_ata(handle)) && is_ejectable(handle))
-		return 1;
-	return 0;
-}
-
-#if 0
-/**
- * eject_removable_drive - try to eject this drive
- * @dev : the device structure of the drive
- *
- * If a device is a removable drive that requires an _EJ0 method
- * to be executed in order to safely remove from the system, do
- * it.  ATM - always returns success
- */
-int eject_removable_drive(struct device *dev)
-{
-	acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
-
-	if (handle) {
-		bay_dprintk(handle, "Got device handle");
-		if (is_ejectable_bay(handle))
-			eject_device(handle);
-	} else {
-		printk("No acpi handle for device\n");
-	}
-
-	/* should I return an error code? */
-	return 0;
-}
-EXPORT_SYMBOL_GPL(eject_removable_drive);
-#endif  /*  0  */
-
-static int acpi_bay_add_fs(struct bay *bay)
-{
-	int ret;
-	struct device *dev = &bay->pdev->dev;
-
-	ret = device_create_file(dev, &dev_attr_present);
-	if (ret)
-		goto add_fs_err;
-	ret = device_create_file(dev, &dev_attr_eject);
-	if (ret) {
-		device_remove_file(dev, &dev_attr_present);
-		goto add_fs_err;
-	}
-	return 0;
-
- add_fs_err:
-	bay_dprintk(bay->handle, "Error adding sysfs files\n");
-	return ret;
-}
-
-static void acpi_bay_remove_fs(struct bay *bay)
-{
-	struct device *dev = &bay->pdev->dev;
-
-	/* cleanup sysfs */
-	device_remove_file(dev, &dev_attr_present);
-	device_remove_file(dev, &dev_attr_eject);
-}
-
-static int bay_is_dock_device(acpi_handle handle)
-{
-	acpi_handle parent;
-
-	acpi_get_parent(handle, &parent);
-
-	/* if the device or it's parent is dependent on the
-	 * dock, then we are a dock device
-	 */
-	return (is_dock_device(handle) || is_dock_device(parent));
-}
-
-static int bay_add(acpi_handle handle, int id)
-{
-	acpi_status status;
-	struct bay *new_bay;
-	struct platform_device *pdev;
-	struct acpi_buffer nbuffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &nbuffer);
-
-	bay_dprintk(handle, "Adding notify handler");
-
-	/*
-	 * Initialize bay device structure
-	 */
-	new_bay = kzalloc(sizeof(*new_bay), GFP_ATOMIC);
-	INIT_LIST_HEAD(&new_bay->list);
-	new_bay->handle = handle;
-	new_bay->name = (char *)nbuffer.pointer;
-
-	/* initialize platform device stuff */
-	pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0);
-	if (IS_ERR(pdev)) {
-		printk(KERN_ERR PREFIX "Error registering bay device\n");
-		goto bay_add_err;
-	}
-	new_bay->pdev = pdev;
-	platform_set_drvdata(pdev, new_bay);
-
-	/*
-	 * we want the bay driver to be able to send uevents
-	 */
-	pdev->dev.uevent_suppress = 0;
-
-	/* register for events on this device */
-	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-			bay_notify, new_bay);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_INFO PREFIX "Error installing bay notify handler\n");
-		platform_device_unregister(new_bay->pdev);
-		goto bay_add_err;
-	}
-
-	if (acpi_bay_add_fs(new_bay)) {
-		acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-					   bay_notify);
-		platform_device_unregister(new_bay->pdev);
-		goto bay_add_err;
-	}
-
-	/* if we are on a dock station, we should register for dock
-	 * notifications.
-	 */
-	if (bay_is_dock_device(handle)) {
-		bay_dprintk(handle, "Is dependent on dock\n");
-		register_hotplug_dock_device(handle, bay_notify, new_bay);
-	}
-	list_add(&new_bay->list, &drive_bays);
-	printk(KERN_INFO PREFIX "Bay [%s] Added\n", new_bay->name);
-	return 0;
-
-bay_add_err:
-	kfree(new_bay->name);
-	kfree(new_bay);
-	return -ENODEV;
-}
-
-/**
- * bay_notify - act upon an acpi bay notification
- * @handle: the bay handle
- * @event: the acpi event
- * @data: our driver data struct
- *
- */
-static void bay_notify(acpi_handle handle, u32 event, void *data)
-{
-	struct bay *bay_dev = (struct bay *)data;
-	struct device *dev = &bay_dev->pdev->dev;
-	char event_string[12];
-	char *envp[] = { event_string, NULL };
-
-	bay_dprintk(handle, "Bay event");
-	sprintf(event_string, "BAY_EVENT=%d", event);
-	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
-}
-
-static acpi_status
-find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	int *count = (int *)context;
-
-	/*
-	 * there could be more than one ejectable bay.
-	 * so, just return AE_OK always so that every object
-	 * will be checked.
-	 */
-	if (is_ejectable_bay(handle)) {
-		bay_dprintk(handle, "found ejectable bay");
-		if (!bay_add(handle, *count))
-			(*count)++;
-	}
-	return AE_OK;
-}
-
-static int __init bay_init(void)
-{
-	int bays = 0;
-
-	INIT_LIST_HEAD(&drive_bays);
-
-	if (acpi_disabled)
-		return -ENODEV;
-
-	/* look for dockable drive bays */
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-		ACPI_UINT32_MAX, find_bay, &bays, NULL);
-
-	if (!bays)
-		return -ENODEV;
-
-	return 0;
-}
-
-static void __exit bay_exit(void)
-{
-	struct bay *bay, *tmp;
-
-	list_for_each_entry_safe(bay, tmp, &drive_bays, list) {
-		if (is_dock_device(bay->handle))
-			unregister_hotplug_dock_device(bay->handle);
-		acpi_bay_remove_fs(bay);
-		acpi_remove_notify_handler(bay->handle, ACPI_SYSTEM_NOTIFY,
-			bay_notify);
-		platform_device_unregister(bay->pdev);
-		kfree(bay->name);
-		kfree(bay);
-	}
-}
-
-postcore_initcall(bay_init);
-module_exit(bay_exit);
-
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index ccae305ee55d..c797c6473f31 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -48,6 +48,23 @@ EXPORT_SYMBOL(acpi_root_dir);
 
 #define STRUCT_TO_INT(s)	(*((int*)&s))
 
+static int set_power_nocheck(const struct dmi_system_id *id)
+{
+	printk(KERN_NOTICE PREFIX "%s detected - "
+		"disable power check in power transistion\n", id->ident);
+	acpi_power_nocheck = 1;
+	return 0;
+}
+static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
+	{
+	set_power_nocheck, "HP Pavilion 05", {
+	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+	DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
+	DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
+	{},
+};
+
+
 /* --------------------------------------------------------------------------
                                 Device Management
    -------------------------------------------------------------------------- */
@@ -77,7 +94,7 @@ EXPORT_SYMBOL(acpi_bus_get_device);
 int acpi_bus_get_status(struct acpi_device *device)
 {
 	acpi_status status = AE_OK;
-	unsigned long sta = 0;
+	unsigned long long sta = 0;
 
 
 	if (!device)
@@ -95,21 +112,21 @@ int acpi_bus_get_status(struct acpi_device *device)
 	}
 
 	/*
-	 * Otherwise we assume the status of our parent (unless we don't
-	 * have one, in which case status is implied).
+	 * According to ACPI spec some device can be present and functional
+	 * even if the parent is not present but functional.
+	 * In such conditions the child device should not inherit the status
+	 * from the parent.
 	 */
-	else if (device->parent)
-		device->status = device->parent->status;
 	else
 		STRUCT_TO_INT(device->status) =
 		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
 		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
 
 	if (device->status.functional && !device->status.present) {
-		printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
-		       "functional but not present; setting present\n",
-		       device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
-		device->status.present = 1;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
+		       "functional but not present;\n",
+			device->pnp.bus_id,
+			(u32) STRUCT_TO_INT(device->status)));
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
@@ -155,7 +172,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
 	int result = 0;
 	acpi_status status = 0;
 	struct acpi_device *device = NULL;
-	unsigned long psc = 0;
+	unsigned long long psc = 0;
 
 
 	result = acpi_bus_get_device(handle, &device);
@@ -223,7 +240,19 @@ int acpi_bus_set_power(acpi_handle handle, int state)
 	/*
 	 * Get device's current power state
 	 */
-	acpi_bus_get_power(device->handle, &device->power.state);
+	if (!acpi_power_nocheck) {
+		/*
+		 * Maybe the incorrect power state is returned on the bogus
+		 * bios, which is different with the real power state.
+		 * For example: the bios returns D0 state and the real power
+		 * state is D3. OS expects to set the device to D0 state. In
+		 * such case if OS uses the power state returned by the BIOS,
+		 * the device can't be transisted to the correct power state.
+		 * So if the acpi_power_nocheck is set, it is unnecessary to
+		 * get the power state by calling acpi_bus_get_power.
+		 */
+		acpi_bus_get_power(device->handle, &device->power.state);
+	}
 	if ((state == device->power.state) && !device->flags.force_power_state) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
 				  state));
@@ -496,6 +525,19 @@ static int acpi_bus_check_scope(struct acpi_device *device)
 	return 0;
 }
 
+static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
+int register_acpi_bus_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);
+
+void unregister_acpi_bus_notifier(struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
+
 /**
  * acpi_bus_notify
  * ---------------
@@ -506,6 +548,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 	int result = 0;
 	struct acpi_device *device = NULL;
 
+	blocking_notifier_call_chain(&acpi_bus_notify_list,
+		type, (void *)handle);
 
 	if (acpi_bus_get_device(handle, &device))
 		return;
@@ -749,6 +793,12 @@ static int __init acpi_bus_init(void)
 		goto error1;
 	}
 
+	/*
+	 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
+	 * is necessary to enable it as early as possible.
+	 */
+	acpi_boot_ec_enable();
+
 	printk(KERN_INFO PREFIX "Interpreter enabled\n");
 
 	/* Initialize sleep structures */
@@ -818,7 +868,11 @@ static int __init acpi_init(void)
 		}
 	} else
 		disable_acpi();
-
+	/*
+	 * If the laptop falls into the DMI check table, the power state check
+	 * will be disabled in the course of device power transistion.
+	 */
+	dmi_check_system(power_nocheck_dmi_table);
 	return result;
 }
 
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 1dfec413588c..9d568d417eaa 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -145,7 +145,7 @@ static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_button *button = seq->private;
 	acpi_status status;
-	unsigned long state;
+	unsigned long long state;
 
 	if (!button || !button->device)
 		return 0;
@@ -253,7 +253,7 @@ static int acpi_button_remove_fs(struct acpi_device *device)
    -------------------------------------------------------------------------- */
 static int acpi_lid_send_state(struct acpi_button *button)
 {
-	unsigned long state;
+	unsigned long long state;
 	acpi_status status;
 
 	status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
@@ -384,7 +384,7 @@ static int acpi_button_add(struct acpi_device *device)
 		return -ENOMEM;
 
 	button->device = device;
-	acpi_driver_data(device) = button;
+	device->driver_data = button;
 
 	button->input = input = input_allocate_device();
 	if (!input) {
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c
index f9db4f444bd0..4441e84b28a9 100644
--- a/drivers/acpi/cm_sbs.c
+++ b/drivers/acpi/cm_sbs.c
@@ -52,8 +52,8 @@ struct proc_dir_entry *acpi_lock_ac_dir(void)
 	if (acpi_ac_dir) {
 		lock_ac_dir_cnt++;
 	} else {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Cannot create %s\n", ACPI_AC_CLASS));
+		printk(KERN_ERR PREFIX
+				  "Cannot create %s\n", ACPI_AC_CLASS);
 	}
 	mutex_unlock(&cm_sbs_mutex);
 	return acpi_ac_dir;
@@ -83,8 +83,8 @@ struct proc_dir_entry *acpi_lock_battery_dir(void)
 	if (acpi_battery_dir) {
 		lock_battery_dir_cnt++;
 	} else {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Cannot create %s\n", ACPI_BATTERY_CLASS));
+		printk(KERN_ERR PREFIX
+				  "Cannot create %s\n", ACPI_BATTERY_CLASS);
 	}
 	mutex_unlock(&cm_sbs_mutex);
 	return acpi_battery_dir;
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 3c25ec7a1871..134818b265a9 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -76,7 +76,7 @@ static int is_device_present(acpi_handle handle)
 {
 	acpi_handle temp;
 	acpi_status status;
-	unsigned long sta;
+	unsigned long long sta;
 
 
 	status = acpi_get_handle(handle, "_STA", &temp);
@@ -108,7 +108,7 @@ static int acpi_container_add(struct acpi_device *device)
 	container->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
-	acpi_driver_data(device) = container;
+	device->driver_data = container;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
 			  acpi_device_name(device), acpi_device_bid(device)));
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 6df564f4ca6e..abf36b4b1d1d 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -47,8 +47,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = {
 };
 
 static const struct acpi_dlevel acpi_debug_levels[] = {
-	ACPI_DEBUG_INIT(ACPI_LV_ERROR),
-	ACPI_DEBUG_INIT(ACPI_LV_WARN),
 	ACPI_DEBUG_INIT(ACPI_LV_INIT),
 	ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
 	ACPI_DEBUG_INIT(ACPI_LV_INFO),
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 4613b9ca5792..279a5a60a0dd 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -103,6 +103,9 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
 						    NULL);
 		acpi_ex_enter_interpreter();
 	}
+
+	acpi_ds_clear_implicit_return(walk_state);
+
 #ifdef ACPI_DISASSEMBLER
 	if (ACPI_FAILURE(status)) {
 
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index 13c43eac35db..d03f81bd1bcb 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acdispat.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acinterp.h>
 
@@ -52,11 +51,11 @@ ACPI_MODULE_NAME("dsmthdat")
 
 /* Local prototypes */
 static void
-acpi_ds_method_data_delete_value(u16 opcode,
+acpi_ds_method_data_delete_value(u8 type,
 				 u32 index, struct acpi_walk_state *walk_state);
 
 static acpi_status
-acpi_ds_method_data_set_value(u16 opcode,
+acpi_ds_method_data_set_value(u8 type,
 			      u32 index,
 			      union acpi_operand_object *object,
 			      struct acpi_walk_state *walk_state);
@@ -216,7 +215,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
 		 * Store the argument in the method/walk descriptor.
 		 * Do not copy the arg in order to implement call by reference
 		 */
-		status = acpi_ds_method_data_set_value(AML_ARG_OP, index,
+		status = acpi_ds_method_data_set_value(ACPI_REFCLASS_ARG, index,
 						       params[index],
 						       walk_state);
 		if (ACPI_FAILURE(status)) {
@@ -234,7 +233,8 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
  *
  * FUNCTION:    acpi_ds_method_data_get_node
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which Local or Arg whose type to get
  *              walk_state          - Current walk state object
  *              Node                - Where the node is returned.
@@ -246,7 +246,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
  ******************************************************************************/
 
 acpi_status
-acpi_ds_method_data_get_node(u16 opcode,
+acpi_ds_method_data_get_node(u8 type,
 			     u32 index,
 			     struct acpi_walk_state *walk_state,
 			     struct acpi_namespace_node **node)
@@ -256,8 +256,8 @@ acpi_ds_method_data_get_node(u16 opcode,
 	/*
 	 * Method Locals and Arguments are supported
 	 */
-	switch (opcode) {
-	case AML_LOCAL_OP:
+	switch (type) {
+	case ACPI_REFCLASS_LOCAL:
 
 		if (index > ACPI_METHOD_MAX_LOCAL) {
 			ACPI_ERROR((AE_INFO,
@@ -271,7 +271,7 @@ acpi_ds_method_data_get_node(u16 opcode,
 		*node = &walk_state->local_variables[index];
 		break;
 
-	case AML_ARG_OP:
+	case ACPI_REFCLASS_ARG:
 
 		if (index > ACPI_METHOD_MAX_ARG) {
 			ACPI_ERROR((AE_INFO,
@@ -286,8 +286,8 @@ acpi_ds_method_data_get_node(u16 opcode,
 		break;
 
 	default:
-		ACPI_ERROR((AE_INFO, "Opcode %d is invalid", opcode));
-		return_ACPI_STATUS(AE_AML_BAD_OPCODE);
+		ACPI_ERROR((AE_INFO, "Type %d is invalid", type));
+		return_ACPI_STATUS(AE_TYPE);
 	}
 
 	return_ACPI_STATUS(AE_OK);
@@ -297,7 +297,8 @@ acpi_ds_method_data_get_node(u16 opcode,
  *
  * FUNCTION:    acpi_ds_method_data_set_value
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which Local or Arg to get
  *              Object              - Object to be inserted into the stack entry
  *              walk_state          - Current walk state object
@@ -310,7 +311,7 @@ acpi_ds_method_data_get_node(u16 opcode,
  ******************************************************************************/
 
 static acpi_status
-acpi_ds_method_data_set_value(u16 opcode,
+acpi_ds_method_data_set_value(u8 type,
 			      u32 index,
 			      union acpi_operand_object *object,
 			      struct acpi_walk_state *walk_state)
@@ -321,13 +322,13 @@ acpi_ds_method_data_set_value(u16 opcode,
 	ACPI_FUNCTION_TRACE(ds_method_data_set_value);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-			  "NewObj %p Opcode %X, Refs=%d [%s]\n", object,
-			  opcode, object->common.reference_count,
+			  "NewObj %p Type %2.2X, Refs=%d [%s]\n", object,
+			  type, object->common.reference_count,
 			  acpi_ut_get_type_name(object->common.type)));
 
 	/* Get the namespace node for the arg/local */
 
-	status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+	status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -350,7 +351,8 @@ acpi_ds_method_data_set_value(u16 opcode,
  *
  * FUNCTION:    acpi_ds_method_data_get_value
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which local_var or argument to get
  *              walk_state          - Current walk state object
  *              dest_desc           - Where Arg or Local value is returned
@@ -363,7 +365,7 @@ acpi_ds_method_data_set_value(u16 opcode,
  ******************************************************************************/
 
 acpi_status
-acpi_ds_method_data_get_value(u16 opcode,
+acpi_ds_method_data_get_value(u8 type,
 			      u32 index,
 			      struct acpi_walk_state *walk_state,
 			      union acpi_operand_object **dest_desc)
@@ -383,7 +385,7 @@ acpi_ds_method_data_get_value(u16 opcode,
 
 	/* Get the namespace node for the arg/local */
 
-	status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+	status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -419,8 +421,8 @@ acpi_ds_method_data_get_value(u16 opcode,
 		/* Otherwise, return the error */
 
 		else
-			switch (opcode) {
-			case AML_ARG_OP:
+			switch (type) {
+			case ACPI_REFCLASS_ARG:
 
 				ACPI_ERROR((AE_INFO,
 					    "Uninitialized Arg[%d] at node %p",
@@ -428,7 +430,7 @@ acpi_ds_method_data_get_value(u16 opcode,
 
 				return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
 
-			case AML_LOCAL_OP:
+			case ACPI_REFCLASS_LOCAL:
 
 				ACPI_ERROR((AE_INFO,
 					    "Uninitialized Local[%d] at node %p",
@@ -437,9 +439,10 @@ acpi_ds_method_data_get_value(u16 opcode,
 				return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL);
 
 			default:
+
 				ACPI_ERROR((AE_INFO,
 					    "Not a Arg/Local opcode: %X",
-					    opcode));
+					    type));
 				return_ACPI_STATUS(AE_AML_INTERNAL);
 			}
 	}
@@ -458,7 +461,8 @@ acpi_ds_method_data_get_value(u16 opcode,
  *
  * FUNCTION:    acpi_ds_method_data_delete_value
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which local_var or argument to delete
  *              walk_state          - Current walk state object
  *
@@ -470,7 +474,7 @@ acpi_ds_method_data_get_value(u16 opcode,
  ******************************************************************************/
 
 static void
-acpi_ds_method_data_delete_value(u16 opcode,
+acpi_ds_method_data_delete_value(u8 type,
 				 u32 index, struct acpi_walk_state *walk_state)
 {
 	acpi_status status;
@@ -481,7 +485,7 @@ acpi_ds_method_data_delete_value(u16 opcode,
 
 	/* Get the namespace node for the arg/local */
 
-	status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+	status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
 	if (ACPI_FAILURE(status)) {
 		return_VOID;
 	}
@@ -514,7 +518,8 @@ acpi_ds_method_data_delete_value(u16 opcode,
  *
  * FUNCTION:    acpi_ds_store_object_to_local
  *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
+ *                                    ACPI_REFCLASS_ARG
  *              Index               - Which Local or Arg to set
  *              obj_desc            - Value to be stored
  *              walk_state          - Current walk state
@@ -528,7 +533,7 @@ acpi_ds_method_data_delete_value(u16 opcode,
  ******************************************************************************/
 
 acpi_status
-acpi_ds_store_object_to_local(u16 opcode,
+acpi_ds_store_object_to_local(u8 type,
 			      u32 index,
 			      union acpi_operand_object *obj_desc,
 			      struct acpi_walk_state *walk_state)
@@ -539,8 +544,8 @@ acpi_ds_store_object_to_local(u16 opcode,
 	union acpi_operand_object *new_obj_desc;
 
 	ACPI_FUNCTION_TRACE(ds_store_object_to_local);
-	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
-			  opcode, index, obj_desc));
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
+			  type, index, obj_desc));
 
 	/* Parameter validation */
 
@@ -550,7 +555,7 @@ acpi_ds_store_object_to_local(u16 opcode,
 
 	/* Get the namespace node for the arg/local */
 
-	status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
+	status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -602,7 +607,7 @@ acpi_ds_store_object_to_local(u16 opcode,
 		 *
 		 * Weird, but true.
 		 */
-		if (opcode == AML_ARG_OP) {
+		if (type == ACPI_REFCLASS_ARG) {
 			/*
 			 * If we have a valid reference object that came from ref_of(),
 			 * do the indirect store
@@ -611,8 +616,8 @@ acpi_ds_store_object_to_local(u16 opcode,
 			     ACPI_DESC_TYPE_OPERAND)
 			    && (current_obj_desc->common.type ==
 				ACPI_TYPE_LOCAL_REFERENCE)
-			    && (current_obj_desc->reference.opcode ==
-				AML_REF_OF_OP)) {
+			    && (current_obj_desc->reference.class ==
+				ACPI_REFCLASS_REFOF)) {
 				ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 						  "Arg (%p) is an ObjRef(Node), storing in node %p\n",
 						  new_obj_desc,
@@ -640,11 +645,9 @@ acpi_ds_store_object_to_local(u16 opcode,
 			}
 		}
 
-		/*
-		 * Delete the existing object
-		 * before storing the new one
-		 */
-		acpi_ds_method_data_delete_value(opcode, index, walk_state);
+		/* Delete the existing object before storing the new one */
+
+		acpi_ds_method_data_delete_value(type, index, walk_state);
 	}
 
 	/*
@@ -653,7 +656,7 @@ acpi_ds_store_object_to_local(u16 opcode,
 	 * (increments the object reference count by one)
 	 */
 	status =
-	    acpi_ds_method_data_set_value(opcode, index, new_obj_desc,
+	    acpi_ds_method_data_set_value(type, index, new_obj_desc,
 					  walk_state);
 
 	/* Remove local reference if we copied the object above */
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 0f2805899210..4f08e599d07e 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -731,54 +731,70 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
 		switch (op_info->type) {
 		case AML_TYPE_LOCAL_VARIABLE:
 
-			/* Split the opcode into a base opcode + offset */
+			/* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
 
-			obj_desc->reference.opcode = AML_LOCAL_OP;
-			obj_desc->reference.offset = opcode - AML_LOCAL_OP;
+			obj_desc->reference.value = opcode - AML_LOCAL_OP;
+			obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-			status = acpi_ds_method_data_get_node(AML_LOCAL_OP,
-							      obj_desc->
-							      reference.offset,
-							      walk_state,
-							      (struct
-							       acpi_namespace_node
-							       **)&obj_desc->
-							      reference.object);
+			status =
+			    acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL,
+							 obj_desc->reference.
+							 value, walk_state,
+							 ACPI_CAST_INDIRECT_PTR
+							 (struct
+							  acpi_namespace_node,
+							  &obj_desc->reference.
+							  object));
 #endif
 			break;
 
 		case AML_TYPE_METHOD_ARGUMENT:
 
-			/* Split the opcode into a base opcode + offset */
+			/* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
 
-			obj_desc->reference.opcode = AML_ARG_OP;
-			obj_desc->reference.offset = opcode - AML_ARG_OP;
+			obj_desc->reference.value = opcode - AML_ARG_OP;
+			obj_desc->reference.class = ACPI_REFCLASS_ARG;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-			status = acpi_ds_method_data_get_node(AML_ARG_OP,
+			status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG,
 							      obj_desc->
-							      reference.offset,
+							      reference.value,
 							      walk_state,
+							      ACPI_CAST_INDIRECT_PTR
 							      (struct
-							       acpi_namespace_node
-							       **)&obj_desc->
-							      reference.object);
+							       acpi_namespace_node,
+							       &obj_desc->
+							       reference.
+							       object));
 #endif
 			break;
 
-		default:	/* Other literals, etc.. */
+		default:	/* Object name or Debug object */
 
-			if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
+			switch (op->common.aml_opcode) {
+			case AML_INT_NAMEPATH_OP:
 
 				/* Node was saved in Op */
 
 				obj_desc->reference.node = op->common.node;
 				obj_desc->reference.object =
 				    op->common.node->object;
-			}
+				obj_desc->reference.class = ACPI_REFCLASS_NAME;
+				break;
+
+			case AML_DEBUG_OP:
 
-			obj_desc->reference.opcode = opcode;
+				obj_desc->reference.class = ACPI_REFCLASS_DEBUG;
+				break;
+
+			default:
+
+				ACPI_ERROR((AE_INFO,
+					    "Unimplemented reference type for AML opcode: %4.4X",
+					    opcode));
+				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
+			}
 			break;
 		}
 		break;
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index 6a81c4400edf..69fae5905bb8 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -1330,7 +1330,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
 			     (walk_state->results->results.obj_desc[0]) ==
 			     ACPI_TYPE_LOCAL_REFERENCE)
 			    && ((walk_state->results->results.obj_desc[0])->
-				reference.opcode != AML_INDEX_OP)) {
+				reference.class != ACPI_REFCLASS_INDEX)) {
 				status =
 				    acpi_ex_resolve_to_value(&walk_state->
 							     results->results.
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index b5072fa9c920..396fe12078cd 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -166,6 +166,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
 		status = AE_CTRL_FALSE;
 	}
 
+	/* Predicate can be used for an implicit return value */
+
+	(void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE);
+
       cleanup:
 
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
@@ -429,10 +433,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
 			     ACPI_TYPE_LOCAL_REFERENCE)
 			    && (walk_state->operands[1]->common.type ==
 				ACPI_TYPE_LOCAL_REFERENCE)
-			    && (walk_state->operands[0]->reference.opcode ==
-				walk_state->operands[1]->reference.opcode)
-			    && (walk_state->operands[0]->reference.offset ==
-				walk_state->operands[1]->reference.offset)) {
+			    && (walk_state->operands[0]->reference.class ==
+				walk_state->operands[1]->reference.class)
+			    && (walk_state->operands[0]->reference.value ==
+				walk_state->operands[1]->reference.value)) {
 				status = AE_OK;
 			} else {
 				ACPI_EXCEPTION((AE_INFO, status,
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 7d2edf143f16..5b30b8d91d71 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -48,7 +48,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
 	" before undocking");
 
 static struct atomic_notifier_head dock_notifier_list;
-static struct platform_device *dock_device;
 static char dock_device_name[] = "dock";
 
 static const struct acpi_device_id dock_device_ids[] = {
@@ -65,23 +64,29 @@ struct dock_station {
 	struct mutex hp_lock;
 	struct list_head dependent_devices;
 	struct list_head hotplug_devices;
+
+	struct list_head sibiling;
+	struct platform_device *dock_device;
 };
+static LIST_HEAD(dock_stations);
+static int dock_station_count;
 
 struct dock_dependent_device {
 	struct list_head list;
 	struct list_head hotplug_list;
 	acpi_handle handle;
-	acpi_notify_handler handler;
+	struct acpi_dock_ops *ops;
 	void *context;
 };
 
 #define DOCK_DOCKING	0x00000001
 #define DOCK_UNDOCKING  0x00000002
+#define DOCK_IS_DOCK	0x00000010
+#define DOCK_IS_ATA	0x00000020
+#define DOCK_IS_BAT	0x00000040
 #define DOCK_EVENT	3
 #define UNDOCK_EVENT	2
 
-static struct dock_station *dock_station;
-
 /*****************************************************************************
  *                         Dock Dependent device functions                   *
  *****************************************************************************/
@@ -199,6 +204,60 @@ static int is_dock(acpi_handle handle)
 	return 1;
 }
 
+static int is_ejectable(acpi_handle handle)
+{
+	acpi_status status;
+	acpi_handle tmp;
+
+	status = acpi_get_handle(handle, "_EJ0", &tmp);
+	if (ACPI_FAILURE(status))
+		return 0;
+	return 1;
+}
+
+static int is_ata(acpi_handle handle)
+{
+	acpi_handle tmp;
+
+	if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
+	   (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
+	   (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
+	   (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
+		return 1;
+
+	return 0;
+}
+
+static int is_battery(acpi_handle handle)
+{
+	struct acpi_device_info *info;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	int ret = 1;
+
+	if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer)))
+		return 0;
+	info = buffer.pointer;
+	if (!(info->valid & ACPI_VALID_HID))
+		ret = 0;
+	else
+		ret = !strcmp("PNP0C0A", info->hardware_id.value);
+
+	kfree(buffer.pointer);
+	return ret;
+}
+
+static int is_ejectable_bay(acpi_handle handle)
+{
+	acpi_handle phandle;
+	if (!is_ejectable(handle))
+		return 0;
+	if (is_battery(handle) || is_ata(handle))
+		return 1;
+	if (!acpi_get_parent(handle, &phandle) && is_ata(phandle))
+		return 1;
+	return 0;
+}
+
 /**
  * is_dock_device - see if a device is on a dock station
  * @handle: acpi handle of the device
@@ -209,11 +268,17 @@ static int is_dock(acpi_handle handle)
  */
 int is_dock_device(acpi_handle handle)
 {
-	if (!dock_station)
+	struct dock_station *dock_station;
+
+	if (!dock_station_count)
 		return 0;
 
-	if (is_dock(handle) || find_dock_dependent_device(dock_station, handle))
+	if (is_dock(handle))
 		return 1;
+	list_for_each_entry(dock_station, &dock_stations, sibiling) {
+		if (find_dock_dependent_device(dock_station, handle))
+			return 1;
+	}
 
 	return 0;
 }
@@ -229,7 +294,7 @@ EXPORT_SYMBOL_GPL(is_dock_device);
  */
 static int dock_present(struct dock_station *ds)
 {
-	unsigned long sta;
+	unsigned long long sta;
 	acpi_status status;
 
 	if (ds) {
@@ -320,8 +385,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
 	 * First call driver specific hotplug functions
 	 */
 	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
-		if (dd->handler)
-			dd->handler(dd->handle, event, dd->context);
+		if (dd->ops && dd->ops->handler)
+			dd->ops->handler(dd->handle, event, dd->context);
 	}
 
 	/*
@@ -341,9 +406,10 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
 
 static void dock_event(struct dock_station *ds, u32 event, int num)
 {
-	struct device *dev = &dock_device->dev;
+	struct device *dev = &ds->dock_device->dev;
 	char event_string[13];
 	char *envp[] = { event_string, NULL };
+	struct dock_dependent_device *dd;
 
 	if (num == UNDOCK_EVENT)
 		sprintf(event_string, "EVENT=undock");
@@ -354,7 +420,14 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
 	 * Indicate that the status of the dock station has
 	 * changed.
 	 */
-	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+	if (num == DOCK_EVENT)
+		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+
+	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
+		if (dd->ops && dd->ops->uevent)
+			dd->ops->uevent(dd->handle, event, dd->context);
+	if (num != DOCK_EVENT)
+		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 }
 
 /**
@@ -414,9 +487,10 @@ static void handle_dock(struct dock_station *ds, int dock)
 	arg.type = ACPI_TYPE_INTEGER;
 	arg.integer.value = dock;
 	status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
-	if (ACPI_FAILURE(status))
-		printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n",
-			 (char *)name_buffer.pointer);
+	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+		ACPI_EXCEPTION((AE_INFO, status, "%s - failed to execute"
+			" _DCK\n", (char *)name_buffer.pointer));
+
 	kfree(buffer.pointer);
 	kfree(name_buffer.pointer);
 }
@@ -452,6 +526,25 @@ static inline void complete_undock(struct dock_station *ds)
 	ds->flags &= ~(DOCK_UNDOCKING);
 }
 
+static void dock_lock(struct dock_station *ds, int lock)
+{
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	acpi_status status;
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = !!lock;
+	status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+		if (lock)
+			printk(KERN_WARNING PREFIX "Locking device failed\n");
+		else
+			printk(KERN_WARNING PREFIX "Unlocking device failed\n");
+	}
+}
+
 /**
  * dock_in_progress - see if we are in the middle of handling a dock event
  * @ds: the dock station
@@ -479,7 +572,7 @@ static int dock_in_progress(struct dock_station *ds)
  */
 int register_dock_notifier(struct notifier_block *nb)
 {
-	if (!dock_station)
+	if (!dock_station_count)
 		return -ENODEV;
 
 	return atomic_notifier_chain_register(&dock_notifier_list, nb);
@@ -493,7 +586,7 @@ EXPORT_SYMBOL_GPL(register_dock_notifier);
  */
 void unregister_dock_notifier(struct notifier_block *nb)
 {
-	if (!dock_station)
+	if (!dock_station_count)
 		return;
 
 	atomic_notifier_chain_unregister(&dock_notifier_list, nb);
@@ -504,7 +597,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
 /**
  * register_hotplug_dock_device - register a hotplug function
  * @handle: the handle of the device
- * @handler: the acpi_notifier_handler to call after docking
+ * @ops: handlers to call after docking
  * @context: device specific data
  *
  * If a driver would like to perform a hotplug operation after a dock
@@ -512,27 +605,36 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
  * the dock driver after _DCK is executed.
  */
 int
-register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
+register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
 			     void *context)
 {
 	struct dock_dependent_device *dd;
+	struct dock_station *dock_station;
+	int ret = -EINVAL;
 
-	if (!dock_station)
+	if (!dock_station_count)
 		return -ENODEV;
 
 	/*
 	 * make sure this handle is for a device dependent on the dock,
 	 * this would include the dock station itself
 	 */
-	dd = find_dock_dependent_device(dock_station, handle);
-	if (dd) {
-		dd->handler = handler;
-		dd->context = context;
-		dock_add_hotplug_device(dock_station, dd);
-		return 0;
+	list_for_each_entry(dock_station, &dock_stations, sibiling) {
+		/*
+		 * An ATA bay can be in a dock and itself can be ejected
+		 * seperately, so there are two 'dock stations' which need the
+		 * ops
+		 */
+		dd = find_dock_dependent_device(dock_station, handle);
+		if (dd) {
+			dd->ops = ops;
+			dd->context = context;
+			dock_add_hotplug_device(dock_station, dd);
+			ret = 0;
+		}
 	}
 
-	return -EINVAL;
+	return ret;
 }
 
 EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
@@ -544,13 +646,16 @@ EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
 void unregister_hotplug_dock_device(acpi_handle handle)
 {
 	struct dock_dependent_device *dd;
+	struct dock_station *dock_station;
 
-	if (!dock_station)
+	if (!dock_station_count)
 		return;
 
-	dd = find_dock_dependent_device(dock_station, handle);
-	if (dd)
-		dock_del_hotplug_device(dock_station, dd);
+	list_for_each_entry(dock_station, &dock_stations, sibiling) {
+		dd = find_dock_dependent_device(dock_station, handle);
+		if (dd)
+			dock_del_hotplug_device(dock_station, dd);
+	}
 }
 
 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
@@ -575,13 +680,9 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
 	 */
 	dock_event(ds, event, UNDOCK_EVENT);
 
-	if (!dock_present(ds)) {
-		complete_undock(ds);
-		return -ENODEV;
-	}
-
 	hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
 	undock(ds);
+	dock_lock(ds, 0);
 	eject_dock(ds);
 	if (dock_present(ds)) {
 		printk(KERN_ERR PREFIX "Unable to undock!\n");
@@ -604,14 +705,36 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
 static void dock_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct dock_station *ds = data;
+	struct acpi_device *tmp;
+	int surprise_removal = 0;
+
+	/*
+	 * According to acpi spec 3.0a, if a DEVICE_CHECK notification
+	 * is sent and _DCK is present, it is assumed to mean an undock
+	 * request.
+	 */
+	if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK)
+		event = ACPI_NOTIFY_EJECT_REQUEST;
 
+	/*
+	 * dock station: BUS_CHECK - docked or surprise removal
+	 *		 DEVICE_CHECK - undocked
+	 * other device: BUS_CHECK/DEVICE_CHECK - added or surprise removal
+	 *
+	 * To simplify event handling, dock dependent device handler always
+	 * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
+	 * ACPI_NOTIFY_EJECT_REQUEST for removal
+	 */
 	switch (event) {
 	case ACPI_NOTIFY_BUS_CHECK:
-		if (!dock_in_progress(ds) && dock_present(ds)) {
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
+		   &tmp)) {
 			begin_dock(ds);
 			dock(ds);
 			if (!dock_present(ds)) {
 				printk(KERN_ERR PREFIX "Unable to dock!\n");
+				complete_dock(ds);
 				break;
 			}
 			atomic_notifier_call_chain(&dock_notifier_list,
@@ -619,20 +742,19 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
 			hotplug_dock_devices(ds, event);
 			complete_dock(ds);
 			dock_event(ds, event, DOCK_EVENT);
+			dock_lock(ds, 1);
+			break;
 		}
-		break;
-	case ACPI_NOTIFY_DEVICE_CHECK:
-	/*
-         * According to acpi spec 3.0a, if a DEVICE_CHECK notification
-         * is sent and _DCK is present, it is assumed to mean an
-         * undock request.  This notify routine will only be called
-         * for objects defining _DCK, so we will fall through to eject
-         * request here.  However, we will pass an eject request through
-	 * to the driver who wish to hotplug.
-         */
+		if (dock_present(ds) || dock_in_progress(ds))
+			break;
+		/* This is a surprise removal */
+		surprise_removal = 1;
+		event = ACPI_NOTIFY_EJECT_REQUEST;
+		/* Fall back */
 	case ACPI_NOTIFY_EJECT_REQUEST:
 		begin_undock(ds);
-		if (immediate_undock)
+		if ((immediate_undock && !(ds->flags & DOCK_IS_ATA))
+		   || surprise_removal)
 			handle_eject_request(ds, event);
 		else
 			dock_event(ds, event, UNDOCK_EVENT);
@@ -642,6 +764,51 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
 	}
 }
 
+struct dock_data {
+	acpi_handle handle;
+	unsigned long event;
+	struct dock_station *ds;
+};
+
+static void acpi_dock_deferred_cb(void *context)
+{
+	struct dock_data *data = (struct dock_data *)context;
+
+	dock_notify(data->handle, data->event, data->ds);
+	kfree(data);
+}
+
+static int acpi_dock_notifier_call(struct notifier_block *this,
+	unsigned long event, void *data)
+{
+	struct dock_station *dock_station;
+	acpi_handle handle = (acpi_handle)data;
+
+	if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
+	   && event != ACPI_NOTIFY_EJECT_REQUEST)
+		return 0;
+	list_for_each_entry(dock_station, &dock_stations, sibiling) {
+		if (dock_station->handle == handle) {
+			struct dock_data *dock_data;
+
+			dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL);
+			if (!dock_data)
+				return 0;
+			dock_data->handle = handle;
+			dock_data->event = event;
+			dock_data->ds = dock_station;
+			acpi_os_hotplug_execute(acpi_dock_deferred_cb,
+				dock_data);
+			return 0 ;
+		}
+	}
+	return 0;
+}
+
+static struct notifier_block dock_acpi_notifier = {
+	.notifier_call = acpi_dock_notifier_call,
+};
+
 /**
  * find_dock_devices - find devices on the dock station
  * @handle: the handle of the device we are examining
@@ -688,6 +855,8 @@ fdd_out:
 static ssize_t show_docked(struct device *dev,
 			   struct device_attribute *attr, char *buf)
 {
+	struct dock_station *dock_station = *((struct dock_station **)
+		dev->platform_data);
 	return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
 
 }
@@ -699,6 +868,8 @@ static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
 static ssize_t show_flags(struct device *dev,
 			  struct device_attribute *attr, char *buf)
 {
+	struct dock_station *dock_station = *((struct dock_station **)
+		dev->platform_data);
 	return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
 
 }
@@ -711,6 +882,8 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 {
 	int ret;
+	struct dock_station *dock_station = *((struct dock_station **)
+		dev->platform_data);
 
 	if (!count)
 		return -EINVAL;
@@ -727,16 +900,38 @@ static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
 static ssize_t show_dock_uid(struct device *dev,
 			     struct device_attribute *attr, char *buf)
 {
-	unsigned long lbuf;
+	unsigned long long lbuf;
+	struct dock_station *dock_station = *((struct dock_station **)
+		dev->platform_data);
 	acpi_status status = acpi_evaluate_integer(dock_station->handle,
 					"_UID", NULL, &lbuf);
 	if (ACPI_FAILURE(status))
 	    return 0;
 
-	return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf);
+	return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf);
 }
 static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
 
+static ssize_t show_dock_type(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct dock_station *dock_station = *((struct dock_station **)
+		dev->platform_data);
+	char *type;
+
+	if (dock_station->flags & DOCK_IS_DOCK)
+		type = "dock_station";
+	else if (dock_station->flags & DOCK_IS_ATA)
+		type = "ata_bay";
+	else if (dock_station->flags & DOCK_IS_BAT)
+		type = "battery_bay";
+	else
+		type = "unknown";
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", type);
+}
+static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL);
+
 /**
  * dock_add - add a new dock station
  * @handle: the dock station handle
@@ -747,8 +942,9 @@ static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
 static int dock_add(acpi_handle handle)
 {
 	int ret;
-	acpi_status status;
 	struct dock_dependent_device *dd;
+	struct dock_station *dock_station;
+	struct platform_device *dock_device;
 
 	/* allocate & initialize the dock_station private data */
 	dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
@@ -758,22 +954,34 @@ static int dock_add(acpi_handle handle)
 	dock_station->last_dock_time = jiffies - HZ;
 	INIT_LIST_HEAD(&dock_station->dependent_devices);
 	INIT_LIST_HEAD(&dock_station->hotplug_devices);
+	INIT_LIST_HEAD(&dock_station->sibiling);
 	spin_lock_init(&dock_station->dd_lock);
 	mutex_init(&dock_station->hp_lock);
 	ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
 
 	/* initialize platform device stuff */
-	dock_device =
-		platform_device_register_simple(dock_device_name, 0, NULL, 0);
+	dock_station->dock_device =
+		platform_device_register_simple(dock_device_name,
+			dock_station_count, NULL, 0);
+	dock_device = dock_station->dock_device;
 	if (IS_ERR(dock_device)) {
 		kfree(dock_station);
 		dock_station = NULL;
 		return PTR_ERR(dock_device);
 	}
+	platform_device_add_data(dock_device, &dock_station,
+		sizeof(struct dock_station *));
 
 	/* we want the dock device to send uevents */
 	dock_device->dev.uevent_suppress = 0;
 
+	if (is_dock(handle))
+		dock_station->flags |= DOCK_IS_DOCK;
+	if (is_ata(handle))
+		dock_station->flags |= DOCK_IS_ATA;
+	if (is_battery(handle))
+		dock_station->flags |= DOCK_IS_BAT;
+
 	ret = device_create_file(&dock_device->dev, &dev_attr_docked);
 	if (ret) {
 		printk("Error %d adding sysfs file\n", ret);
@@ -812,6 +1020,9 @@ static int dock_add(acpi_handle handle)
 		dock_station = NULL;
 		return ret;
 	}
+	ret = device_create_file(&dock_device->dev, &dev_attr_type);
+	if (ret)
+		printk(KERN_ERR"Error %d adding sysfs file\n", ret);
 
 	/* Find dependent devices */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
@@ -828,24 +1039,12 @@ static int dock_add(acpi_handle handle)
 	}
 	add_dock_dependent_device(dock_station, dd);
 
-	/* register for dock events */
-	status = acpi_install_notify_handler(dock_station->handle,
-					     ACPI_SYSTEM_NOTIFY,
-					     dock_notify, dock_station);
-
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX "Error installing notify handler\n");
-		ret = -ENODEV;
-		goto dock_add_err;
-	}
-
-	printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION);
-
+	dock_station_count++;
+	list_add(&dock_station->sibiling, &dock_stations);
 	return 0;
 
-dock_add_err:
-	kfree(dd);
 dock_add_err_unregister:
+	device_remove_file(&dock_device->dev, &dev_attr_type);
 	device_remove_file(&dock_device->dev, &dev_attr_docked);
 	device_remove_file(&dock_device->dev, &dev_attr_undock);
 	device_remove_file(&dock_device->dev, &dev_attr_uid);
@@ -859,12 +1058,12 @@ dock_add_err_unregister:
 /**
  * dock_remove - free up resources related to the dock station
  */
-static int dock_remove(void)
+static int dock_remove(struct dock_station *dock_station)
 {
 	struct dock_dependent_device *dd, *tmp;
-	acpi_status status;
+	struct platform_device *dock_device = dock_station->dock_device;
 
-	if (!dock_station)
+	if (!dock_station_count)
 		return 0;
 
 	/* remove dependent devices */
@@ -872,14 +1071,8 @@ static int dock_remove(void)
 				 list)
 	    kfree(dd);
 
-	/* remove dock notify handler */
-	status = acpi_remove_notify_handler(dock_station->handle,
-					    ACPI_SYSTEM_NOTIFY,
-					    dock_notify);
-	if (ACPI_FAILURE(status))
-		printk(KERN_ERR "Error removing notify handler\n");
-
 	/* cleanup sysfs */
+	device_remove_file(&dock_device->dev, &dev_attr_type);
 	device_remove_file(&dock_device->dev, &dev_attr_docked);
 	device_remove_file(&dock_device->dev, &dev_attr_undock);
 	device_remove_file(&dock_device->dev, &dev_attr_uid);
@@ -904,41 +1097,60 @@ static int dock_remove(void)
 static acpi_status
 find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-	int *count = context;
 	acpi_status status = AE_OK;
 
 	if (is_dock(handle)) {
 		if (dock_add(handle) >= 0) {
-			(*count)++;
 			status = AE_CTRL_TERMINATE;
 		}
 	}
 	return status;
 }
 
-static int __init dock_init(void)
+static acpi_status
+find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-	int num = 0;
-
-	dock_station = NULL;
+	/* If bay is a dock, it's already handled */
+	if (is_ejectable_bay(handle) && !is_dock(handle))
+		dock_add(handle);
+	return AE_OK;
+}
 
+static int __init dock_init(void)
+{
 	if (acpi_disabled)
 		return 0;
 
 	/* look for a dock station */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX, find_dock, &num, NULL);
+			    ACPI_UINT32_MAX, find_dock, NULL, NULL);
 
-	if (!num)
-		printk(KERN_INFO "No dock devices found.\n");
+	/* look for bay */
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			ACPI_UINT32_MAX, find_bay, NULL, NULL);
+	if (!dock_station_count) {
+		printk(KERN_INFO PREFIX "No dock devices found.\n");
+		return 0;
+	}
 
+	register_acpi_bus_notifier(&dock_acpi_notifier);
+	printk(KERN_INFO PREFIX "%s: %d docks/bays found\n",
+		ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
 	return 0;
 }
 
 static void __exit dock_exit(void)
 {
-	dock_remove();
+	struct dock_station *dock_station;
+
+	unregister_acpi_bus_notifier(&dock_acpi_notifier);
+	list_for_each_entry(dock_station, &dock_stations, sibiling)
+		dock_remove(dock_station);
 }
 
-postcore_initcall(dock_init);
+/*
+ * Must be called before drivers of devices in dock, otherwise we can't know
+ * which devices are in a dock
+ */
+subsys_initcall(dock_init);
 module_exit(dock_exit);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 13593f9f2197..ef42316f89f5 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1,7 +1,7 @@
 /*
- *  ec.c - ACPI Embedded Controller Driver (v2.0)
+ *  ec.c - ACPI Embedded Controller Driver (v2.1)
  *
- *  Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
+ *  Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de>
  *  Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
  *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
@@ -26,7 +26,7 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
-/* Uncomment next line to get verbose print outs*/
+/* Uncomment next line to get verbose printout */
 /* #define DEBUG */
 
 #include <linux/kernel.h>
@@ -38,6 +38,7 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/spinlock.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -65,22 +66,21 @@ enum ec_command {
 	ACPI_EC_COMMAND_QUERY = 0x84,
 };
 
-/* EC events */
-enum ec_event {
-	ACPI_EC_EVENT_OBF_1 = 1,	/* Output buffer full */
-	ACPI_EC_EVENT_IBF_0,		/* Input buffer empty */
-};
-
 #define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
 #define ACPI_EC_UDELAY		100	/* Wait 100us before polling EC again */
 
+#define ACPI_EC_STORM_THRESHOLD 20	/* number of false interrupts
+					   per one transaction */
+
 enum {
-	EC_FLAGS_WAIT_GPE = 0,		/* Don't check status until GPE arrives */
 	EC_FLAGS_QUERY_PENDING,		/* Query is pending */
-	EC_FLAGS_GPE_MODE,		/* Expect GPE to be sent for status change */
+	EC_FLAGS_GPE_MODE,		/* Expect GPE to be sent
+					 * for status change */
 	EC_FLAGS_NO_GPE,		/* Don't use GPE mode */
-	EC_FLAGS_RESCHEDULE_POLL	/* Re-schedule poll */
+	EC_FLAGS_GPE_STORM,		/* GPE storm detected */
+	EC_FLAGS_HANDLERS_INSTALLED	/* Handlers for GPE and
+					 * OpReg are installed */
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -95,6 +95,15 @@ struct acpi_ec_query_handler {
 	u8 query_bit;
 };
 
+struct transaction {
+	const u8 *wdata;
+	u8 *rdata;
+	unsigned short irq_count;
+	u8 command;
+	u8 wlen;
+	u8 rlen;
+};
+
 static struct acpi_ec {
 	acpi_handle handle;
 	unsigned long gpe;
@@ -105,9 +114,8 @@ static struct acpi_ec {
 	struct mutex lock;
 	wait_queue_head_t wait;
 	struct list_head list;
-	struct delayed_work work;
-	atomic_t irq_count;
-	u8 handlers_installed;
+	struct transaction *curr;
+	spinlock_t curr_lock;
 } *boot_ec, *first_ec;
 
 /* 
@@ -150,7 +158,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
 {
 	u8 x = inb(ec->data_addr);
 	pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
-	return inb(ec->data_addr);
+	return x;
 }
 
 static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
@@ -165,158 +173,172 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
 	outb(data, ec->data_addr);
 }
 
-static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
+static int ec_transaction_done(struct acpi_ec *ec)
 {
-	if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
-		return 0;
-	if (event == ACPI_EC_EVENT_OBF_1) {
-		if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
-			return 1;
-	} else if (event == ACPI_EC_EVENT_IBF_0) {
-		if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
-			return 1;
-	}
-
-	return 0;
+	unsigned long flags;
+	int ret = 0;
+	spin_lock_irqsave(&ec->curr_lock, flags);
+	if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
+		ret = 1;
+	spin_unlock_irqrestore(&ec->curr_lock, flags);
+	return ret;
 }
 
-static void ec_schedule_ec_poll(struct acpi_ec *ec)
+static void gpe_transaction(struct acpi_ec *ec, u8 status)
 {
-	if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
-		schedule_delayed_work(&ec->work,
-				      msecs_to_jiffies(ACPI_EC_DELAY));
+	unsigned long flags;
+	spin_lock_irqsave(&ec->curr_lock, flags);
+	if (!ec->curr)
+		goto unlock;
+	if (ec->curr->wlen > 0) {
+		if ((status & ACPI_EC_FLAG_IBF) == 0) {
+			acpi_ec_write_data(ec, *(ec->curr->wdata++));
+			--ec->curr->wlen;
+		} else
+			/* false interrupt, state didn't change */
+			++ec->curr->irq_count;
+
+	} else if (ec->curr->rlen > 0) {
+		if ((status & ACPI_EC_FLAG_OBF) == 1) {
+			*(ec->curr->rdata++) = acpi_ec_read_data(ec);
+			--ec->curr->rlen;
+		} else
+			/* false interrupt, state didn't change */
+			++ec->curr->irq_count;
+	}
+unlock:
+	spin_unlock_irqrestore(&ec->curr_lock, flags);
 }
 
-static void ec_switch_to_poll_mode(struct acpi_ec *ec)
+static int acpi_ec_wait(struct acpi_ec *ec)
 {
+	if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
+			       msecs_to_jiffies(ACPI_EC_DELAY)))
+		return 0;
+	/* missing GPEs, switch back to poll mode */
+	if (printk_ratelimit())
+		pr_info(PREFIX "missing confirmations, "
+				"switch off interrupt mode.\n");
 	set_bit(EC_FLAGS_NO_GPE, &ec->flags);
 	clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-	acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
-	set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+	return 1;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
+static void acpi_ec_gpe_query(void *ec_cxt);
+
+static int ec_check_sci(struct acpi_ec *ec, u8 state)
 {
-	atomic_set(&ec->irq_count, 0);
-	if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
-	    likely(!force_poll)) {
-		if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
-				       msecs_to_jiffies(ACPI_EC_DELAY)))
-			return 0;
-		clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-		if (acpi_ec_check_status(ec, event)) {
-			/* missing GPEs, switch back to poll mode */
-			if (printk_ratelimit())
-				pr_info(PREFIX "missing confirmations, "
-						"switch off interrupt mode.\n");
-			ec_switch_to_poll_mode(ec);
-			ec_schedule_ec_poll(ec);
-			return 0;
-		}
-	} else {
-		unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
-		clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-		while (time_before(jiffies, delay)) {
-			if (acpi_ec_check_status(ec, event))
-				return 0;
-			msleep(1);
-		}
-		if (acpi_ec_check_status(ec,event))
+	if (state & ACPI_EC_FLAG_SCI) {
+		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
+			return acpi_os_execute(OSL_EC_BURST_HANDLER,
+				acpi_ec_gpe_query, ec);
+	}
+	return 0;
+}
+
+static int ec_poll(struct acpi_ec *ec)
+{
+	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+	msleep(1);
+	while (time_before(jiffies, delay)) {
+		gpe_transaction(ec, acpi_ec_read_status(ec));
+		msleep(1);
+		if (ec_transaction_done(ec))
 			return 0;
 	}
-	pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
-		acpi_ec_read_status(ec),
-		(event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
 	return -ETIME;
 }
 
-static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
-					const u8 * wdata, unsigned wdata_len,
-					u8 * rdata, unsigned rdata_len,
+static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+					struct transaction *t,
 					int force_poll)
 {
-	int result = 0;
-	set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+	unsigned long tmp;
+	int ret = 0;
 	pr_debug(PREFIX "transaction start\n");
-	acpi_ec_write_cmd(ec, command);
-	for (; wdata_len > 0; --wdata_len) {
-		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
-		if (result) {
-			pr_err(PREFIX
-			       "write_cmd timeout, command = %d\n", command);
-			goto end;
-		}
-		set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-		acpi_ec_write_data(ec, *(wdata++));
+	/* disable GPE during transaction if storm is detected */
+	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+		clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+		acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 	}
-
-	if (!rdata_len) {
-		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
-		if (result) {
-			pr_err(PREFIX
-			       "finish-write timeout, command = %d\n", command);
-			goto end;
-		}
-	} else if (command == ACPI_EC_COMMAND_QUERY)
+	/* start transaction */
+	spin_lock_irqsave(&ec->curr_lock, tmp);
+	/* following two actions should be kept atomic */
+	t->irq_count = 0;
+	ec->curr = t;
+	acpi_ec_write_cmd(ec, ec->curr->command);
+	if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
 		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
-
-	for (; rdata_len > 0; --rdata_len) {
-		result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
-		if (result) {
-			pr_err(PREFIX "read timeout, command = %d\n", command);
-			goto end;
-		}
-		/* Don't expect GPE after last read */
-		if (rdata_len > 1)
-			set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-		*(rdata++) = acpi_ec_read_data(ec);
-	}
-      end:
+	spin_unlock_irqrestore(&ec->curr_lock, tmp);
+	/* if we selected poll mode or failed in GPE-mode do a poll loop */
+	if (force_poll ||
+	    !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ||
+	    acpi_ec_wait(ec))
+		ret = ec_poll(ec);
 	pr_debug(PREFIX "transaction end\n");
-	return result;
+	spin_lock_irqsave(&ec->curr_lock, tmp);
+	ec->curr = NULL;
+	spin_unlock_irqrestore(&ec->curr_lock, tmp);
+	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+		/* check if we received SCI during transaction */
+		ec_check_sci(ec, acpi_ec_read_status(ec));
+		/* it is safe to enable GPE outside of transaction */
+		acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+	} else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+		   t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+		pr_debug(PREFIX "GPE storm detected\n");
+		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+	}
+	return ret;
+}
+
+static int ec_check_ibf0(struct acpi_ec *ec)
+{
+	u8 status = acpi_ec_read_status(ec);
+	return (status & ACPI_EC_FLAG_IBF) == 0;
 }
 
-static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
-			       const u8 * wdata, unsigned wdata_len,
-			       u8 * rdata, unsigned rdata_len,
+static int ec_wait_ibf0(struct acpi_ec *ec)
+{
+	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+	/* interrupt wait manually if GPE mode is not active */
+	unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ?
+		msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1);
+	while (time_before(jiffies, delay))
+		if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout))
+			return 0;
+	return -ETIME;
+}
+
+static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
 			       int force_poll)
 {
 	int status;
 	u32 glk;
-
-	if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
+	if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
 		return -EINVAL;
-
-	if (rdata)
-		memset(rdata, 0, rdata_len);
-
+	if (t->rdata)
+		memset(t->rdata, 0, t->rlen);
 	mutex_lock(&ec->lock);
 	if (ec->global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status)) {
-			mutex_unlock(&ec->lock);
-			return -ENODEV;
+			status = -ENODEV;
+			goto unlock;
 		}
 	}
-
-	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
-	if (status) {
+	if (ec_wait_ibf0(ec)) {
 		pr_err(PREFIX "input buffer is not empty, "
 				"aborting transaction\n");
+		status = -ETIME;
 		goto end;
 	}
-
-	status = acpi_ec_transaction_unlocked(ec, command,
-					      wdata, wdata_len,
-					      rdata, rdata_len,
-					      force_poll);
-
-      end:
-
+	status = acpi_ec_transaction_unlocked(ec, t, force_poll);
+end:
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
+unlock:
 	mutex_unlock(&ec->lock);
-
 	return status;
 }
 
@@ -327,21 +349,32 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
 int acpi_ec_burst_enable(struct acpi_ec *ec)
 {
 	u8 d;
-	return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1, 0);
+	struct transaction t = {.command = ACPI_EC_BURST_ENABLE,
+				.wdata = NULL, .rdata = &d,
+				.wlen = 0, .rlen = 1};
+
+	return acpi_ec_transaction(ec, &t, 0);
 }
 
 int acpi_ec_burst_disable(struct acpi_ec *ec)
 {
-	return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0, 0);
+	struct transaction t = {.command = ACPI_EC_BURST_DISABLE,
+				.wdata = NULL, .rdata = NULL,
+				.wlen = 0, .rlen = 0};
+
+	return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
+				acpi_ec_transaction(ec, &t, 0) : 0;
 }
 
 static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
 {
 	int result;
 	u8 d;
+	struct transaction t = {.command = ACPI_EC_COMMAND_READ,
+				.wdata = &address, .rdata = &d,
+				.wlen = 1, .rlen = 1};
 
-	result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
-				     &address, 1, &d, 1, 0);
+	result = acpi_ec_transaction(ec, &t, 0);
 	*data = d;
 	return result;
 }
@@ -349,8 +382,11 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
 static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
 {
 	u8 wdata[2] = { address, data };
-	return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
-				   wdata, 2, NULL, 0, 0);
+	struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
+				.wdata = wdata, .rdata = NULL,
+				.wlen = 2, .rlen = 0};
+
+	return acpi_ec_transaction(ec, &t, 0);
 }
 
 /*
@@ -412,12 +448,13 @@ int ec_transaction(u8 command,
 		   u8 * rdata, unsigned rdata_len,
 		   int force_poll)
 {
+	struct transaction t = {.command = command,
+				.wdata = wdata, .rdata = rdata,
+				.wlen = wdata_len, .rlen = rdata_len};
 	if (!first_ec)
 		return -ENODEV;
 
-	return acpi_ec_transaction(first_ec, command, wdata,
-				   wdata_len, rdata, rdata_len,
-				   force_poll);
+	return acpi_ec_transaction(first_ec, &t, force_poll);
 }
 
 EXPORT_SYMBOL(ec_transaction);
@@ -426,7 +463,9 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 {
 	int result;
 	u8 d;
-
+	struct transaction t = {.command = ACPI_EC_COMMAND_QUERY,
+				.wdata = NULL, .rdata = &d,
+				.wlen = 0, .rlen = 1};
 	if (!ec || !data)
 		return -EINVAL;
 
@@ -436,7 +475,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 */
 
-	result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1, 0);
+	result = acpi_ec_transaction(ec, &t, 0);
 	if (result)
 		return result;
 
@@ -513,46 +552,26 @@ static void acpi_ec_gpe_query(void *ec_cxt)
 
 static u32 acpi_ec_gpe_handler(void *data)
 {
-	acpi_status status = AE_OK;
 	struct acpi_ec *ec = data;
-	u8 state = acpi_ec_read_status(ec);
+	u8 status;
 
 	pr_debug(PREFIX "~~~> interrupt\n");
-	atomic_inc(&ec->irq_count);
-	if (atomic_read(&ec->irq_count) > 5) {
-		pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
-		ec_switch_to_poll_mode(ec);
-		goto end;
-	}
-	clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-	if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
+	status = acpi_ec_read_status(ec);
+
+	gpe_transaction(ec, status);
+	if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
 		wake_up(&ec->wait);
 
-	if (state & ACPI_EC_FLAG_SCI) {
-		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
-			status = acpi_os_execute(OSL_EC_BURST_HANDLER,
-				acpi_ec_gpe_query, ec);
-	} else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
-		   !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
-		   in_interrupt()) {
+	ec_check_sci(ec, status);
+	if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+	    !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
 		/* this is non-query, must be confirmation */
 		if (printk_ratelimit())
 			pr_info(PREFIX "non-query interrupt received,"
 				" switching to interrupt mode\n");
 		set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-		clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
 	}
-end:
-	ec_schedule_ec_poll(ec);
-	return ACPI_SUCCESS(status) ?
-	    ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
-}
-
-static void do_ec_poll(struct work_struct *work)
-{
-	struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
-	atomic_set(&ec->irq_count, 0);
-	(void)acpi_ec_gpe_handler(ec);
+	return ACPI_INTERRUPT_HANDLED;
 }
 
 /* --------------------------------------------------------------------------
@@ -696,8 +715,7 @@ static struct acpi_ec *make_acpi_ec(void)
 	mutex_init(&ec->lock);
 	init_waitqueue_head(&ec->wait);
 	INIT_LIST_HEAD(&ec->list);
-	INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
-	atomic_set(&ec->irq_count, 0);
+	spin_lock_init(&ec->curr_lock);
 	return ec;
 }
 
@@ -718,6 +736,7 @@ static acpi_status
 ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 {
 	acpi_status status;
+	unsigned long long tmp;
 
 	struct acpi_ec *ec = context;
 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
@@ -727,31 +746,26 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 
 	/* Get GPE bit assignment (EC events). */
 	/* TODO: Add support for _GPE returning a package */
-	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
 	if (ACPI_FAILURE(status))
 		return status;
+	ec->gpe = tmp;
 	/* Use the global lock for all EC transactions? */
-	acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+	acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
+	ec->global_lock = tmp;
 	ec->handle = handle;
 	return AE_CTRL_TERMINATE;
 }
 
-static void ec_poll_stop(struct acpi_ec *ec)
-{
-	clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
-	cancel_delayed_work(&ec->work);
-}
-
 static void ec_remove_handlers(struct acpi_ec *ec)
 {
-	ec_poll_stop(ec);
 	if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
 				ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
 		pr_err(PREFIX "failed to remove space handler\n");
 	if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
 				&acpi_ec_gpe_handler)))
 		pr_err(PREFIX "failed to remove gpe handler\n");
-	ec->handlers_installed = 0;
+	clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
 }
 
 static int acpi_ec_add(struct acpi_device *device)
@@ -788,7 +802,7 @@ static int acpi_ec_add(struct acpi_device *device)
 
 	if (!first_ec)
 		first_ec = ec;
-	acpi_driver_data(device) = ec;
+	device->driver_data = ec;
 	acpi_ec_add_fs(device);
 	pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
 			  ec->gpe, ec->command_addr, ec->data_addr);
@@ -813,7 +827,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 	}
 	mutex_unlock(&ec->lock);
 	acpi_ec_remove_fs(device);
-	acpi_driver_data(device) = NULL;
+	device->driver_data = NULL;
 	if (ec == first_ec)
 		first_ec = NULL;
 	kfree(ec);
@@ -846,27 +860,36 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
 static int ec_install_handlers(struct acpi_ec *ec)
 {
 	acpi_status status;
-	if (ec->handlers_installed)
+	if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags))
 		return 0;
 	status = acpi_install_gpe_handler(NULL, ec->gpe,
-					  ACPI_GPE_EDGE_TRIGGERED,
-					  &acpi_ec_gpe_handler, ec);
+				  ACPI_GPE_EDGE_TRIGGERED,
+				  &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
-
 	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
 	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
-
 	status = acpi_install_address_space_handler(ec->handle,
 						    ACPI_ADR_SPACE_EC,
 						    &acpi_ec_space_handler,
 						    NULL, ec);
 	if (ACPI_FAILURE(status)) {
-		acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
-		return -ENODEV;
+		if (status == AE_NOT_FOUND) {
+			/*
+			 * Maybe OS fails in evaluating the _REG object.
+			 * The AE_NOT_FOUND error will be ignored and OS
+			 * continue to initialize EC.
+			 */
+			printk(KERN_ERR "Fail in evaluating the _REG object"
+				" of EC device. Broken bios is suspected.\n");
+		} else {
+			acpi_remove_gpe_handler(NULL, ec->gpe,
+				&acpi_ec_gpe_handler);
+			return -ENODEV;
+		}
 	}
 
-	ec->handlers_installed = 1;
+	set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
 	return 0;
 }
 
@@ -887,7 +910,6 @@ static int acpi_ec_start(struct acpi_device *device)
 
 	/* EC is fully operational, allow queries */
 	clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
-	ec_schedule_ec_poll(ec);
 	return ret;
 }
 
@@ -906,7 +928,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
 
 int __init acpi_boot_ec_enable(void)
 {
-	if (!boot_ec || boot_ec->handlers_installed)
+	if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags))
 		return 0;
 	if (!ec_install_handlers(boot_ec)) {
 		first_ec = boot_ec;
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 8892b9824fae..74da6fa52ef1 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acinterp.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 #include <acpi/actables.h>
 #include <acpi/acdispat.h>
@@ -91,13 +90,12 @@ acpi_ex_add_table(u32 table_index,
 
 	/* Init the table handle */
 
-	obj_desc->reference.opcode = AML_LOAD_OP;
+	obj_desc->reference.class = ACPI_REFCLASS_TABLE;
 	*ddb_handle = obj_desc;
 
 	/* Install the new table into the local data structures */
 
-	obj_desc->reference.object = ACPI_CAST_PTR(void,
-			(unsigned long)table_index);
+	obj_desc->reference.value = table_index;
 
 	/* Add the table to the namespace */
 
@@ -280,6 +278,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 		struct acpi_walk_state *walk_state)
 {
 	union acpi_operand_object *ddb_handle;
+	struct acpi_table_header *table;
 	struct acpi_table_desc table_desc;
 	u32 table_index;
 	acpi_status status;
@@ -294,9 +293,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
 	case ACPI_TYPE_REGION:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
-				  obj_desc,
-				  acpi_ut_get_object_type_name(obj_desc)));
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Load table from Region %p\n", obj_desc));
 
 		/* Region must be system_memory (from ACPI spec) */
 
@@ -316,61 +314,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 		}
 
 		/*
-		 * We will simply map the memory region for the table. However, the
-		 * memory region is technically not guaranteed to remain stable and
-		 * we may eventually have to copy the table to a local buffer.
+		 * Map the table header and get the actual table length. The region
+		 * length is not guaranteed to be the same as the table length.
+		 */
+		table = acpi_os_map_memory(obj_desc->region.address,
+					   sizeof(struct acpi_table_header));
+		if (!table) {
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+
+		length = table->length;
+		acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+
+		/* Must have at least an ACPI table header */
+
+		if (length < sizeof(struct acpi_table_header)) {
+			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+		}
+
+		/*
+		 * The memory region is not guaranteed to remain stable and we must
+		 * copy the table to a local buffer. For example, the memory region
+		 * is corrupted after suspend on some machines. Dynamically loaded
+		 * tables are usually small, so this overhead is minimal.
 		 */
+
+		/* Allocate a buffer for the table */
+
+		table_desc.pointer = ACPI_ALLOCATE(length);
+		if (!table_desc.pointer) {
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+
+		/* Map the entire table and copy it */
+
+		table = acpi_os_map_memory(obj_desc->region.address, length);
+		if (!table) {
+			ACPI_FREE(table_desc.pointer);
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+
+		ACPI_MEMCPY(table_desc.pointer, table, length);
+		acpi_os_unmap_memory(table, length);
+
 		table_desc.address = obj_desc->region.address;
-		table_desc.length = obj_desc->region.length;
-		table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
 		break;
 
 	case ACPI_TYPE_BUFFER:	/* Buffer or resolved region_field */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "Load from Buffer or Field %p %s\n", obj_desc,
-				  acpi_ut_get_object_type_name(obj_desc)));
-
-		length = obj_desc->buffer.length;
+				  "Load table from Buffer or Field %p\n",
+				  obj_desc));
 
 		/* Must have at least an ACPI table header */
 
-		if (length < sizeof(struct acpi_table_header)) {
+		if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
 			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 		}
 
-		/* Validate checksum here. It won't get validated in tb_add_table */
+		/* Get the actual table length from the table header */
 
-		status =
-		    acpi_tb_verify_checksum(ACPI_CAST_PTR
-					    (struct acpi_table_header,
-					     obj_desc->buffer.pointer), length);
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
+		table =
+		    ACPI_CAST_PTR(struct acpi_table_header,
+				  obj_desc->buffer.pointer);
+		length = table->length;
+
+		/* Table cannot extend beyond the buffer */
+
+		if (length > obj_desc->buffer.length) {
+			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
+		}
+		if (length < sizeof(struct acpi_table_header)) {
+			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 		}
 
 		/*
-		 * We need to copy the buffer since the original buffer could be
-		 * changed or deleted in the future
+		 * Copy the table from the buffer because the buffer could be modified
+		 * or even deleted in the future
 		 */
 		table_desc.pointer = ACPI_ALLOCATE(length);
 		if (!table_desc.pointer) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
-		ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
-			    length);
-		table_desc.length = length;
-		table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+		ACPI_MEMCPY(table_desc.pointer, table, length);
+		table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
 		break;
 
 	default:
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 	}
 
-	/*
-	 * Install the new table into the local data structures
-	 */
+	/* Validate table checksum (will not get validated in tb_add_table) */
+
+	status = acpi_tb_verify_checksum(table_desc.pointer, length);
+	if (ACPI_FAILURE(status)) {
+		ACPI_FREE(table_desc.pointer);
+		return_ACPI_STATUS(status);
+	}
+
+	/* Complete the table descriptor */
+
+	table_desc.length = length;
+	table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+
+	/* Install the new table into the local data structures */
+
 	status = acpi_tb_add_table(&table_desc, &table_index);
 	if (ACPI_FAILURE(status)) {
 		goto cleanup;
@@ -379,7 +428,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 	/*
 	 * Add the table to the namespace.
 	 *
-	 * Note: We load the table objects relative to the root of the namespace.
+	 * Note: Load the table objects relative to the root of the namespace.
 	 * This appears to go against the ACPI specification, but we do it for
 	 * compatibility with other ACPI implementations.
 	 */
@@ -415,7 +464,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
       cleanup:
 	if (ACPI_FAILURE(status)) {
 
-		/* Delete allocated buffer or mapping */
+		/* Delete allocated table buffer */
 
 		acpi_tb_delete_table(&table_desc);
 	}
@@ -455,9 +504,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Get the table index from the ddb_handle (acpi_size for 64-bit case) */
+	/* Get the table index from the ddb_handle */
 
-	table_index = (u32) (acpi_size) table_desc->reference.object;
+	table_index = table_desc->reference.value;
 
 	/* Invoke table handler if present */
 
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index 261d97516d9b..1d1f35adddde 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -57,7 +57,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
  *
  * FUNCTION:    acpi_ex_convert_to_integer
  *
- * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ * PARAMETERS:  obj_desc        - Object to be converted. Must be an
  *                                Integer, Buffer, or String
  *              result_desc     - Where the new Integer object is returned
  *              Flags           - Used for string conversion
@@ -103,7 +103,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
 	}
 
 	/*
-	 * Convert the buffer/string to an integer.  Note that both buffers and
+	 * Convert the buffer/string to an integer. Note that both buffers and
 	 * strings are treated as raw data - we don't convert ascii to hex for
 	 * strings.
 	 *
@@ -120,7 +120,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
 
 		/*
 		 * Convert string to an integer - for most cases, the string must be
-		 * hexadecimal as per the ACPI specification.  The only exception (as
+		 * hexadecimal as per the ACPI specification. The only exception (as
 		 * of ACPI 3.0) is that the to_integer() operator allows both decimal
 		 * and hexadecimal strings (hex prefixed with "0x").
 		 */
@@ -159,6 +159,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
 		break;
 
 	default:
+
 		/* No other types can get here */
 		break;
 	}
@@ -185,7 +186,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
  *
  * FUNCTION:    acpi_ex_convert_to_buffer
  *
- * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ * PARAMETERS:  obj_desc        - Object to be converted. Must be an
  *                                Integer, Buffer, or String
  *              result_desc     - Where the new buffer object is returned
  *
@@ -365,7 +366,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
 	}
 
 	/*
-	 * Since leading zeros are supressed, we must check for the case where
+	 * Since leading zeros are suppressed, we must check for the case where
 	 * the integer equals 0
 	 *
 	 * Finally, null terminate the string and return the length
@@ -383,7 +384,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
  *
  * FUNCTION:    acpi_ex_convert_to_string
  *
- * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ * PARAMETERS:  obj_desc        - Object to be converted. Must be an
  *                                Integer, Buffer, or String
  *              result_desc     - Where the string object is returned
  *              Type            - String flags (base and conversion type)
@@ -472,7 +473,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
 			base = 10;
 
 			/*
-			 * Calculate the final string length.  Individual string values
+			 * Calculate the final string length. Individual string values
 			 * are variable length (include separator for each)
 			 */
 			for (i = 0; i < obj_desc->buffer.length; i++) {
@@ -511,9 +512,14 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
 		/*
 		 * Create a new string object and string buffer
 		 * (-1 because of extra separator included in string_length from above)
+		 * Allow creation of zero-length strings from zero-length buffers.
 		 */
+		if (string_length) {
+			string_length--;
+		}
+
 		return_desc = acpi_ut_create_string_object((acpi_size)
-							   (string_length - 1));
+							   string_length);
 		if (!return_desc) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
@@ -536,7 +542,9 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
 		 * Null terminate the string
 		 * (overwrites final comma/space from above)
 		 */
-		new_buf--;
+		if (obj_desc->buffer.length) {
+			new_buf--;
+		}
 		*new_buf = 0;
 		break;
 
@@ -617,7 +625,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
 		case ACPI_TYPE_LOCAL_BANK_FIELD:
 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
 			/*
-			 * These types require an Integer operand.  We can convert
+			 * These types require an Integer operand. We can convert
 			 * a Buffer or a String to an Integer if necessary.
 			 */
 			status =
@@ -627,7 +635,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
 
 		case ACPI_TYPE_STRING:
 			/*
-			 * The operand must be a String.  We can convert an
+			 * The operand must be a String. We can convert an
 			 * Integer or Buffer if necessary
 			 */
 			status =
@@ -637,7 +645,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
 
 		case ACPI_TYPE_BUFFER:
 			/*
-			 * The operand must be a Buffer.  We can convert an
+			 * The operand must be a Buffer. We can convert an
 			 * Integer or String if necessary
 			 */
 			status =
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 2be2e2bf95bf..d087a7d28aa5 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -45,7 +45,6 @@
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exdump")
@@ -214,10 +213,11 @@ static struct acpi_exdump_info acpi_ex_dump_index_field[5] = {
 	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"}
 };
 
-static struct acpi_exdump_info acpi_ex_dump_reference[7] = {
+static struct acpi_exdump_info acpi_ex_dump_reference[8] = {
 	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.class), "Class"},
 	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"},
-	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"},
 	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"},
 	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"},
 	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"},
@@ -413,10 +413,10 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
 
 		case ACPI_EXD_REFERENCE:
 
-			acpi_ex_out_string("Opcode",
-					   (acpi_ps_get_opcode_info
-					    (obj_desc->reference.opcode))->
-					   name);
+			acpi_ex_out_string("Class Name",
+					   (char *)
+					   acpi_ut_get_reference_name
+					   (obj_desc));
 			acpi_ex_dump_reference_obj(obj_desc);
 			break;
 
@@ -494,40 +494,41 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
 	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
-		switch (obj_desc->reference.opcode) {
-		case AML_DEBUG_OP:
+		acpi_os_printf("Reference: [%s] ",
+			       acpi_ut_get_reference_name(obj_desc));
+
+		switch (obj_desc->reference.class) {
+		case ACPI_REFCLASS_DEBUG:
 
-			acpi_os_printf("Reference: Debug\n");
+			acpi_os_printf("\n");
 			break;
 
-		case AML_INDEX_OP:
+		case ACPI_REFCLASS_INDEX:
 
-			acpi_os_printf("Reference: Index %p\n",
-				       obj_desc->reference.object);
+			acpi_os_printf("%p\n", obj_desc->reference.object);
 			break;
 
-		case AML_LOAD_OP:
+		case ACPI_REFCLASS_TABLE:
 
-			acpi_os_printf("Reference: [DdbHandle] TableIndex %p\n",
-				       obj_desc->reference.object);
+			acpi_os_printf("Table Index %X\n",
+				       obj_desc->reference.value);
 			break;
 
-		case AML_REF_OF_OP:
+		case ACPI_REFCLASS_REFOF:
 
-			acpi_os_printf("Reference: (RefOf) %p [%s]\n",
-				       obj_desc->reference.object,
+			acpi_os_printf("%p [%s]\n", obj_desc->reference.object,
 				       acpi_ut_get_type_name(((union
 							       acpi_operand_object
-							       *)obj_desc->
+							       *)
+							      obj_desc->
 							      reference.
 							      object)->common.
 							     type));
 			break;
 
-		case AML_ARG_OP:
+		case ACPI_REFCLASS_ARG:
 
-			acpi_os_printf("Reference: Arg%d",
-				       obj_desc->reference.offset);
+			acpi_os_printf("%X", obj_desc->reference.value);
 
 			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 
@@ -542,10 +543,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
 			acpi_os_printf("\n");
 			break;
 
-		case AML_LOCAL_OP:
+		case ACPI_REFCLASS_LOCAL:
 
-			acpi_os_printf("Reference: Local%d",
-				       obj_desc->reference.offset);
+			acpi_os_printf("%X", obj_desc->reference.value);
 
 			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 
@@ -560,21 +560,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
 			acpi_os_printf("\n");
 			break;
 
-		case AML_INT_NAMEPATH_OP:
+		case ACPI_REFCLASS_NAME:
 
-			acpi_os_printf("Reference: Namepath %X [%4.4s]\n",
-				       obj_desc->reference.node->name.integer,
+			acpi_os_printf("- [%4.4s]\n",
 				       obj_desc->reference.node->name.ascii);
 			break;
 
-		default:
-
-			/* Unknown opcode */
+		default:	/* Unknown reference class */
 
-			acpi_os_printf("Unknown Reference opcode=%X\n",
-				       obj_desc->reference.opcode);
+			acpi_os_printf("%2.2X\n", obj_desc->reference.class);
 			break;
-
 		}
 		break;
 
@@ -865,8 +860,8 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
 
 	ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 
-	if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) {
-		acpi_os_printf(" Named Object %p ", obj_desc->reference.node);
+	if (obj_desc->reference.class == ACPI_REFCLASS_NAME) {
+		acpi_os_printf(" %p ", obj_desc->reference.node);
 
 		status =
 		    acpi_ns_handle_to_pathname(obj_desc->reference.node,
@@ -882,14 +877,12 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
 		    ACPI_DESC_TYPE_OPERAND) {
 			acpi_os_printf(" Target: %p",
 				       obj_desc->reference.object);
-			if (obj_desc->reference.opcode == AML_LOAD_OP) {
-				/*
-				 * For DDBHandle reference,
-				 * obj_desc->Reference.Object is the table index
-				 */
-				acpi_os_printf(" [DDBHandle]\n");
+			if (obj_desc->reference.class == ACPI_REFCLASS_TABLE) {
+				acpi_os_printf(" Table Index: %X\n",
+					       obj_desc->reference.value);
 			} else {
-				acpi_os_printf(" [%s]\n",
+				acpi_os_printf(" Target: %p [%s]\n",
+					       obj_desc->reference.object,
 					       acpi_ut_get_type_name(((union
 								       acpi_operand_object
 								       *)
@@ -988,9 +981,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
 
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
-		acpi_os_printf("[Object Reference] %s",
-			       (acpi_ps_get_opcode_info
-				(obj_desc->reference.opcode))->name);
+		acpi_os_printf("[Object Reference] Type [%s] %2.2X",
+			       acpi_ut_get_reference_name(obj_desc),
+			       obj_desc->reference.class);
 		acpi_ex_dump_reference_obj(obj_desc);
 		break;
 
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index 731414a581a6..efb191340059 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -86,10 +86,10 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
 		/*
 		 * Must be a reference to a Local or Arg
 		 */
-		switch (obj_desc->reference.opcode) {
-		case AML_LOCAL_OP:
-		case AML_ARG_OP:
-		case AML_DEBUG_OP:
+		switch (obj_desc->reference.class) {
+		case ACPI_REFCLASS_LOCAL:
+		case ACPI_REFCLASS_ARG:
+		case ACPI_REFCLASS_DEBUG:
 
 			/* The referenced object is the pseudo-node for the local/arg */
 
@@ -98,8 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
 
 		default:
 
-			ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
-				    obj_desc->reference.opcode));
+			ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X",
+				    obj_desc->reference.class));
 			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
 		break;
@@ -127,7 +127,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	reference_obj->reference.opcode = AML_REF_OF_OP;
+	reference_obj->reference.class = ACPI_REFCLASS_REFOF;
 	reference_obj->reference.object = referenced_obj;
 	*return_desc = reference_obj;
 
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 7c3bea575e02..f622f9eac8a1 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -825,16 +825,16 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 				 *
 				 * Must resolve/dereference the local/arg reference first
 				 */
-				switch (operand[0]->reference.opcode) {
-				case AML_LOCAL_OP:
-				case AML_ARG_OP:
+				switch (operand[0]->reference.class) {
+				case ACPI_REFCLASS_LOCAL:
+				case ACPI_REFCLASS_ARG:
 
 					/* Set Operand[0] to the value of the local/arg */
 
 					status =
 					    acpi_ds_method_data_get_value
-					    (operand[0]->reference.opcode,
-					     operand[0]->reference.offset,
+					    (operand[0]->reference.class,
+					     operand[0]->reference.value,
 					     walk_state, &temp_desc);
 					if (ACPI_FAILURE(status)) {
 						goto cleanup;
@@ -848,7 +848,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 					operand[0] = temp_desc;
 					break;
 
-				case AML_REF_OF_OP:
+				case ACPI_REFCLASS_REFOF:
 
 					/* Get the object to which the reference refers */
 
@@ -928,8 +928,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 			 * This must be a reference object produced by either the
 			 * Index() or ref_of() operator
 			 */
-			switch (operand[0]->reference.opcode) {
-			case AML_INDEX_OP:
+			switch (operand[0]->reference.class) {
+			case ACPI_REFCLASS_INDEX:
 
 				/*
 				 * The target type for the Index operator must be
@@ -965,7 +965,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 					return_desc->integer.value =
 					    temp_desc->buffer.
 					    pointer[operand[0]->reference.
-						    offset];
+						    value];
 					break;
 
 				case ACPI_TYPE_PACKAGE:
@@ -985,7 +985,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 				default:
 
 					ACPI_ERROR((AE_INFO,
-						    "Unknown Index TargetType %X in obj %p",
+						    "Unknown Index TargetType %X in reference object %p",
 						    operand[0]->reference.
 						    target_type, operand[0]));
 					status = AE_AML_OPERAND_TYPE;
@@ -993,7 +993,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 				}
 				break;
 
-			case AML_REF_OF_OP:
+			case ACPI_REFCLASS_REFOF:
 
 				return_desc = operand[0]->reference.object;
 
@@ -1013,9 +1013,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
 
 			default:
 				ACPI_ERROR((AE_INFO,
-					    "Unknown opcode in reference(%p) - %X",
+					    "Unknown class in reference(%p) - %2.2X",
 					    operand[0],
-					    operand[0]->reference.opcode));
+					    operand[0]->reference.class));
 
 				status = AE_TYPE;
 				goto cleanup;
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 8e8bbb6ccebd..368def5dffce 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -391,8 +391,8 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
 		/* Initialize the Index reference object */
 
 		index = operand[1]->integer.value;
-		return_desc->reference.offset = (u32) index;
-		return_desc->reference.opcode = AML_INDEX_OP;
+		return_desc->reference.value = (u32) index;
+		return_desc->reference.class = ACPI_REFCLASS_INDEX;
 
 		/*
 		 * At this point, the Source operand is a String, Buffer, or Package.
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
index 5596f42c9676..423ad3635f3d 100644
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -46,8 +46,6 @@
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
-#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exresnte")
@@ -238,10 +236,10 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
 
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
-		switch (source_desc->reference.opcode) {
-		case AML_LOAD_OP:	/* This is a ddb_handle */
-		case AML_REF_OF_OP:
-		case AML_INDEX_OP:
+		switch (source_desc->reference.class) {
+		case ACPI_REFCLASS_TABLE:	/* This is a ddb_handle */
+		case ACPI_REFCLASS_REFOF:
+		case ACPI_REFCLASS_INDEX:
 
 			/* Return an additional reference to the object */
 
@@ -253,10 +251,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
 			/* No named references are allowed here */
 
 			ACPI_ERROR((AE_INFO,
-				    "Unsupported Reference opcode %X (%s)",
-				    source_desc->reference.opcode,
-				    acpi_ps_get_opcode_name(source_desc->
-							    reference.opcode)));
+				    "Unsupported Reference type %X",
+				    source_desc->reference.class));
 
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index b35f7c817acf..89571b92a522 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -47,7 +47,6 @@
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exresolv")
@@ -141,7 +140,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 	acpi_status status = AE_OK;
 	union acpi_operand_object *stack_desc;
 	union acpi_operand_object *obj_desc = NULL;
-	u16 opcode;
+	u8 ref_type;
 
 	ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
 
@@ -152,19 +151,19 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 	switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
-		opcode = stack_desc->reference.opcode;
+		ref_type = stack_desc->reference.class;
 
-		switch (opcode) {
-		case AML_LOCAL_OP:
-		case AML_ARG_OP:
+		switch (ref_type) {
+		case ACPI_REFCLASS_LOCAL:
+		case ACPI_REFCLASS_ARG:
 
 			/*
 			 * Get the local from the method's state info
 			 * Note: this increments the local's object reference count
 			 */
-			status = acpi_ds_method_data_get_value(opcode,
+			status = acpi_ds_method_data_get_value(ref_type,
 							       stack_desc->
-							       reference.offset,
+							       reference.value,
 							       walk_state,
 							       &obj_desc);
 			if (ACPI_FAILURE(status)) {
@@ -173,7 +172,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 
 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 					  "[Arg/Local %X] ValueObj is %p\n",
-					  stack_desc->reference.offset,
+					  stack_desc->reference.value,
 					  obj_desc));
 
 			/*
@@ -184,7 +183,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 			*stack_ptr = obj_desc;
 			break;
 
-		case AML_INDEX_OP:
+		case ACPI_REFCLASS_INDEX:
 
 			switch (stack_desc->reference.target_type) {
 			case ACPI_TYPE_BUFFER_FIELD:
@@ -239,15 +238,15 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 			}
 			break;
 
-		case AML_REF_OF_OP:
-		case AML_DEBUG_OP:
-		case AML_LOAD_OP:
+		case ACPI_REFCLASS_REFOF:
+		case ACPI_REFCLASS_DEBUG:
+		case ACPI_REFCLASS_TABLE:
 
 			/* Just leave the object as-is, do not dereference */
 
 			break;
 
-		case AML_INT_NAMEPATH_OP:	/* Reference to a named object */
+		case ACPI_REFCLASS_NAME:	/* Reference to a named object */
 
 			/* Dereference the name */
 
@@ -273,8 +272,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 		default:
 
 			ACPI_ERROR((AE_INFO,
-				    "Unknown Reference opcode %X (%s) in %p",
-				    opcode, acpi_ps_get_opcode_name(opcode),
+				    "Unknown Reference type %X in %p", ref_type,
 				    stack_desc));
 			status = AE_AML_INTERNAL;
 			break;
@@ -388,13 +386,13 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
 	 * traversing the list of possibly many nested references.
 	 */
 	while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
-		switch (obj_desc->reference.opcode) {
-		case AML_REF_OF_OP:
-		case AML_INT_NAMEPATH_OP:
+		switch (obj_desc->reference.class) {
+		case ACPI_REFCLASS_REFOF:
+		case ACPI_REFCLASS_NAME:
 
 			/* Dereference the reference pointer */
 
-			if (obj_desc->reference.opcode == AML_REF_OF_OP) {
+			if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
 				node = obj_desc->reference.object;
 			} else {	/* AML_INT_NAMEPATH_OP */
 
@@ -429,7 +427,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
 			}
 			break;
 
-		case AML_INDEX_OP:
+		case ACPI_REFCLASS_INDEX:
 
 			/* Get the type of this reference (index into another object) */
 
@@ -455,22 +453,22 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
 			}
 			break;
 
-		case AML_LOAD_OP:
+		case ACPI_REFCLASS_TABLE:
 
 			type = ACPI_TYPE_DDB_HANDLE;
 			goto exit;
 
-		case AML_LOCAL_OP:
-		case AML_ARG_OP:
+		case ACPI_REFCLASS_LOCAL:
+		case ACPI_REFCLASS_ARG:
 
 			if (return_desc) {
 				status =
 				    acpi_ds_method_data_get_value(obj_desc->
 								  reference.
-								  opcode,
+								  class,
 								  obj_desc->
 								  reference.
-								  offset,
+								  value,
 								  walk_state,
 								  &obj_desc);
 				if (ACPI_FAILURE(status)) {
@@ -481,10 +479,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
 				status =
 				    acpi_ds_method_data_get_node(obj_desc->
 								 reference.
-								 opcode,
+								 class,
 								 obj_desc->
 								 reference.
-								 offset,
+								 value,
 								 walk_state,
 								 &node);
 				if (ACPI_FAILURE(status)) {
@@ -499,7 +497,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
 			}
 			break;
 
-		case AML_DEBUG_OP:
+		case ACPI_REFCLASS_DEBUG:
 
 			/* The Debug Object is of type "DebugObject" */
 
@@ -509,8 +507,8 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
 		default:
 
 			ACPI_ERROR((AE_INFO,
-				    "Unknown Reference subtype %X",
-				    obj_desc->reference.opcode));
+				    "Unknown Reference Class %2.2X",
+				    obj_desc->reference.class));
 			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
 	}
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index 54085f16ec28..0bb82593da72 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -225,41 +225,36 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
 
-				/* Decode the Reference */
+				/* Validate the Reference */
 
-				op_info = acpi_ps_get_opcode_info(opcode);
-				if (op_info->class == AML_CLASS_UNKNOWN) {
-					return_ACPI_STATUS(AE_AML_BAD_OPCODE);
-				}
+				switch (obj_desc->reference.class) {
+				case ACPI_REFCLASS_DEBUG:
 
-				switch (obj_desc->reference.opcode) {
-				case AML_DEBUG_OP:
 					target_op = AML_DEBUG_OP;
 
 					/*lint -fallthrough */
 
-				case AML_INDEX_OP:
-				case AML_REF_OF_OP:
-				case AML_ARG_OP:
-				case AML_LOCAL_OP:
-				case AML_LOAD_OP:	/* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
-				case AML_INT_NAMEPATH_OP:	/* Reference to a named object */
-
-					ACPI_DEBUG_ONLY_MEMBERS(ACPI_DEBUG_PRINT
-								((ACPI_DB_EXEC,
-								  "Operand is a Reference, RefOpcode [%s]\n",
-								  (acpi_ps_get_opcode_info
-								   (obj_desc->
-								    reference.
-								    opcode))->
-								  name)));
+				case ACPI_REFCLASS_ARG:
+				case ACPI_REFCLASS_LOCAL:
+				case ACPI_REFCLASS_INDEX:
+				case ACPI_REFCLASS_REFOF:
+				case ACPI_REFCLASS_TABLE:	/* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+				case ACPI_REFCLASS_NAME:	/* Reference to a named object */
+
+					ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+							  "Operand is a Reference, Class [%s] %2.2X\n",
+							  acpi_ut_get_reference_name
+							  (obj_desc),
+							  obj_desc->reference.
+							  class));
 					break;
 
 				default:
+
 					ACPI_ERROR((AE_INFO,
-						    "Operand is a Reference, Unknown Reference Opcode: %X",
-						    obj_desc->reference.
-						    opcode));
+						    "Unknown Reference Class %2.2X in %p",
+						    obj_desc->reference.class,
+						    obj_desc));
 
 					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 				}
@@ -270,8 +265,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Invalid descriptor */
 
-			ACPI_ERROR((AE_INFO,
-				    "Invalid descriptor %p [%s]",
+			ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]",
 				    obj_desc,
 				    acpi_ut_get_descriptor_name(obj_desc)));
 
@@ -343,7 +337,7 @@ acpi_ex_resolve_operands(u16 opcode,
 			if ((opcode == AML_STORE_OP) &&
 			    (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
 			     ACPI_TYPE_LOCAL_REFERENCE)
-			    && ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
+			    && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
 				goto next_operand;
 			}
 			break;
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index 38b55e352495..3318df4cbd98 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -47,7 +47,6 @@
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exstore")
@@ -179,22 +178,26 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
 
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
-		if (source_desc->reference.opcode == AML_INDEX_OP) {
-			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
-					      "[%s, 0x%X]\n",
-					      acpi_ps_get_opcode_name
-					      (source_desc->reference.opcode),
-					      source_desc->reference.offset));
-		} else {
-			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]",
-					      acpi_ps_get_opcode_name
-					      (source_desc->reference.opcode)));
-		}
+		ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s] ",
+				      acpi_ut_get_reference_name(source_desc)));
+
+		/* Decode the reference */
+
+		switch (source_desc->reference.class) {
+		case ACPI_REFCLASS_INDEX:
+
+			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%X\n",
+					      source_desc->reference.value));
+			break;
+
+		case ACPI_REFCLASS_TABLE:
 
-		if (source_desc->reference.opcode == AML_LOAD_OP) {	/* Load and load_table */
 			ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
-					      " Table OwnerId %p\n",
-					      source_desc->reference.object));
+					      "Table Index 0x%X\n",
+					      source_desc->reference.value));
+			break;
+
+		default:
 			break;
 		}
 
@@ -347,15 +350,15 @@ acpi_ex_store(union acpi_operand_object *source_desc,
 	}
 
 	/*
-	 * Examine the Reference opcode.  These cases are handled:
+	 * Examine the Reference class. These cases are handled:
 	 *
 	 * 1) Store to Name (Change the object associated with a name)
 	 * 2) Store to an indexed area of a Buffer or Package
 	 * 3) Store to a Method Local or Arg
 	 * 4) Store to the debug object
 	 */
-	switch (ref_desc->reference.opcode) {
-	case AML_REF_OF_OP:
+	switch (ref_desc->reference.class) {
+	case ACPI_REFCLASS_REFOF:
 
 		/* Storing an object into a Name "container" */
 
@@ -365,7 +368,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
 						      ACPI_IMPLICIT_CONVERSION);
 		break;
 
-	case AML_INDEX_OP:
+	case ACPI_REFCLASS_INDEX:
 
 		/* Storing to an Index (pointer into a packager or buffer) */
 
@@ -374,18 +377,18 @@ acpi_ex_store(union acpi_operand_object *source_desc,
 						  walk_state);
 		break;
 
-	case AML_LOCAL_OP:
-	case AML_ARG_OP:
+	case ACPI_REFCLASS_LOCAL:
+	case ACPI_REFCLASS_ARG:
 
 		/* Store to a method local/arg  */
 
 		status =
-		    acpi_ds_store_object_to_local(ref_desc->reference.opcode,
-						  ref_desc->reference.offset,
+		    acpi_ds_store_object_to_local(ref_desc->reference.class,
+						  ref_desc->reference.value,
 						  source_desc, walk_state);
 		break;
 
-	case AML_DEBUG_OP:
+	case ACPI_REFCLASS_DEBUG:
 
 		/*
 		 * Storing to the Debug object causes the value stored to be
@@ -401,9 +404,9 @@ acpi_ex_store(union acpi_operand_object *source_desc,
 
 	default:
 
-		ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
-			    ref_desc->reference.opcode));
-		ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR);
+		ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X",
+			    ref_desc->reference.class));
+		ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
 
 		status = AE_AML_INTERNAL;
 		break;
@@ -458,7 +461,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
 
 		if (ACPI_GET_OBJECT_TYPE(source_desc) ==
 		    ACPI_TYPE_LOCAL_REFERENCE
-		    && source_desc->reference.opcode == AML_LOAD_OP) {
+		    && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 
 			/* This is a DDBHandle, just add a reference to it */
 
@@ -553,7 +556,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
 
 		/* Store the source value into the target buffer byte */
 
-		obj_desc->buffer.pointer[index_desc->reference.offset] = value;
+		obj_desc->buffer.pointer[index_desc->reference.value] = value;
 		break;
 
 	default:
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index a6d2168b81f9..eef61a00803e 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -121,7 +121,8 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
 		    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
 		    !((ACPI_GET_OBJECT_TYPE(source_desc) ==
 		       ACPI_TYPE_LOCAL_REFERENCE)
-		      && (source_desc->reference.opcode == AML_LOAD_OP))) {
+		      && (source_desc->reference.class ==
+			  ACPI_REFCLASS_TABLE))) {
 
 			/* Conversion successful but still not a valid type */
 
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 2655bc1b4eeb..60d54d1f6b19 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -265,7 +265,7 @@ static int acpi_fan_add(struct acpi_device *device)
 
 	dev_info(&device->dev, "registered as cooling_device%d\n", cdev->id);
 
-	acpi_driver_data(device) = cdev;
+	device->driver_data = cdev;
 	result = sysfs_create_link(&device->dev.kobj,
 				   &cdev->device.kobj,
 				   "thermal_cooling");
@@ -327,8 +327,8 @@ static int acpi_fan_resume(struct acpi_device *device)
 
 	result = acpi_bus_get_power(device->handle, &power_state);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Error reading fan power state\n"));
+		printk(KERN_ERR PREFIX
+				  "Error reading fan power state\n");
 		return result;
 	}
 
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index dba3cfbe8cba..25dccdf179b9 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
 		return_ACPI_STATUS(status);
 	}
 
-	/* Set the vector */
+	/*
+	 * According to the ACPI specification 2.0c and later, the 64-bit
+	 * waking vector should be cleared and the 32-bit waking vector should
+	 * be used, unless we want the wake-up code to be called by the BIOS in
+	 * Protected Mode.  Some systems (for example HP dv5-1004nr) are known
+	 * to fail to resume if the 64-bit vector is used.
+	 */
+	if (facs->version >= 1)
+		facs->xfirmware_waking_vector = 0;
 
-	if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
-		/*
-		 * ACPI 1.0 FACS or short table or optional X_ field is zero
-		 */
-		facs->firmware_waking_vector = (u32) physical_address;
-	} else {
-		/*
-		 * ACPI 2.0 FACS with valid X_ field
-		 */
-		facs->xfirmware_waking_vector = physical_address;
-	}
+	facs->firmware_waking_vector = (u32)physical_address;
 
 	return_ACPI_STATUS(AE_OK);
 }
@@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
 	}
 
 	/* Get the vector */
-
-	if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
-		/*
-		 * ACPI 1.0 FACS or short table or optional X_ field is zero
-		 */
-		*physical_address =
-		    (acpi_physical_address) facs->firmware_waking_vector;
-	} else {
-		/*
-		 * ACPI 2.0 FACS with valid X_ field
-		 */
-		*physical_address =
-		    (acpi_physical_address) facs->xfirmware_waking_vector;
-	}
+	*physical_address = (acpi_physical_address)facs->firmware_waking_vector;
 
 	return_ACPI_STATUS(AE_OK);
 }
@@ -627,6 +612,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
 	}
 	/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
 
+	/*
+	 * Some BIOSes assume that WAK_STS will be cleared on resume and use
+	 * it to determine whether the system is rebooting or resuming. Clear
+	 * it for compatibility.
+	 */
+	acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+
 	acpi_gbl_system_awake_and_running = TRUE;
 
 	/* Enable power button */
diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile
index 3f63d3640696..371a2daf837f 100644
--- a/drivers/acpi/namespace/Makefile
+++ b/drivers/acpi/namespace/Makefile
@@ -5,7 +5,7 @@
 obj-y := nsaccess.o  nsload.o    nssearch.o  nsxfeval.o \
 	 nsalloc.o   nseval.o    nsnames.o   nsutils.o   nsxfname.o \
 	 nsdump.o    nsinit.o    nsobject.o  nswalk.o    nsxfobj.o  \
-	 nsparse.o
+	 nsparse.o   nspredef.o
 
 obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
 
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 0ab22004728a..cc0ae39440e4 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsdump")
@@ -334,9 +333,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
 		case ACPI_TYPE_LOCAL_REFERENCE:
 
 			acpi_os_printf("[%s]\n",
-				       acpi_ps_get_opcode_name(obj_desc->
-							       reference.
-							       opcode));
+				       acpi_ut_get_reference_name(obj_desc));
 			break;
 
 		case ACPI_TYPE_BUFFER_FIELD:
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index d369164e00b0..4cdf03ac2b46 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -78,6 +78,7 @@ ACPI_MODULE_NAME("nseval")
 acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
 {
 	acpi_status status;
+	struct acpi_namespace_node *node;
 
 	ACPI_FUNCTION_TRACE(ns_evaluate);
 
@@ -117,6 +118,8 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
 			  info->resolved_node,
 			  acpi_ns_get_attached_object(info->resolved_node)));
 
+	node = info->resolved_node;
+
 	/*
 	 * Two major cases here:
 	 *
@@ -148,21 +151,22 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
 				info->param_count++;
 		}
 
-		/* Error if too few arguments were passed in */
+		/*
+		 * Warning if too few or too many arguments have been passed by the
+		 * caller. We don't want to abort here with an error because an
+		 * incorrect number of arguments may not cause the method to fail.
+		 * However, the method will fail if there are too few arguments passed
+		 * and the method attempts to use one of the missing ones.
+		 */
 
 		if (info->param_count < info->obj_desc->method.param_count) {
-			ACPI_ERROR((AE_INFO,
+			ACPI_WARNING((AE_INFO,
 				    "Insufficient arguments - "
 				    "method [%4.4s] needs %d, found %d",
 				    acpi_ut_get_node_name(info->resolved_node),
 				    info->obj_desc->method.param_count,
 				    info->param_count));
-			return_ACPI_STATUS(AE_MISSING_ARGUMENTS);
-		}
-
-		/* Just a warning if too many arguments */
-
-		else if (info->param_count >
+		} else if (info->param_count >
 				info->obj_desc->method.param_count) {
 			ACPI_WARNING((AE_INFO,
 				      "Excess arguments - "
@@ -195,7 +199,28 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
 	} else {
 		/*
 		 * 2) Object is not a method, return its current value
+		 *
+		 * Disallow certain object types. For these, "evaluation" is undefined.
 		 */
+		switch (info->resolved_node->type) {
+		case ACPI_TYPE_DEVICE:
+		case ACPI_TYPE_EVENT:
+		case ACPI_TYPE_MUTEX:
+		case ACPI_TYPE_REGION:
+		case ACPI_TYPE_THERMAL:
+		case ACPI_TYPE_LOCAL_SCOPE:
+
+			ACPI_ERROR((AE_INFO,
+				    "[%4.4s] Evaluation of object type [%s] is not supported",
+				    info->resolved_node->name.ascii,
+				    acpi_ut_get_type_name(info->resolved_node->
+							  type)));
+
+			return_ACPI_STATUS(AE_TYPE);
+
+		default:
+			break;
+		}
 
 		/*
 		 * Objects require additional resolution steps (e.g., the Node may be
@@ -239,9 +264,35 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
 		}
 	}
 
-	/*
-	 * Check if there is a return value that must be dealt with
-	 */
+	/* Validation of return values for ACPI-predefined methods and objects */
+
+	if ((status == AE_OK) || (status == AE_CTRL_RETURN_VALUE)) {
+		/*
+		 * If this is the first evaluation, check the return value. This
+		 * ensures that any warnings will only be emitted during the very
+		 * first evaluation of the object.
+		 */
+		if (!(node->flags & ANOBJ_EVALUATED)) {
+			/*
+			 * Check for a predefined ACPI name. If found, validate the
+			 * returned object.
+			 *
+			 * Note: Ignore return status for now, emit warnings if there are
+			 * problems with the returned object. May change later to abort
+			 * the method on invalid return object.
+			 */
+			(void)acpi_ns_check_predefined_names(node,
+							     info->
+							     return_object);
+		}
+
+		/* Mark the node as having been evaluated */
+
+		node->flags |= ANOBJ_EVALUATED;
+	}
+
+	/* Check if there is a return value that must be dealt with */
+
 	if (status == AE_CTRL_RETURN_VALUE) {
 
 		/* If caller does not want the return value, delete it */
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index bd5773878009..42a39a7c96e9 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -115,7 +115,6 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
 	return (AE_OK);
 }
 
-#ifdef ACPI_DEBUG_OUTPUT
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_get_external_pathname
@@ -142,7 +141,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
 
 	size = acpi_ns_get_pathname_length(node);
 	if (!size) {
-		return (NULL);
+		return_PTR(NULL);
 	}
 
 	/* Allocate a buffer to be returned to caller */
@@ -157,12 +156,12 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
 
 	status = acpi_ns_build_external_path(node, size, name_buffer);
 	if (ACPI_FAILURE(status)) {
-		return (NULL);
+		ACPI_FREE(name_buffer);
+		return_PTR(NULL);
 	}
 
 	return_PTR(name_buffer);
 }
-#endif
 
 /*******************************************************************************
  *
diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c
new file mode 100644
index 000000000000..0f17cf0898c9
--- /dev/null
+++ b/drivers/acpi/namespace/nspredef.c
@@ -0,0 +1,900 @@
+/******************************************************************************
+ *
+ * Module Name: nspredef - Validation of ACPI predefined methods and objects
+ *              $Revision: 1.1 $
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2008, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acpredef.h>
+
+#define _COMPONENT          ACPI_NAMESPACE
+ACPI_MODULE_NAME("nspredef")
+
+/*******************************************************************************
+ *
+ * This module validates predefined ACPI objects that appear in the namespace,
+ * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
+ * validation is to detect problems with BIOS-exposed predefined ACPI objects
+ * before the results are returned to the ACPI-related drivers.
+ *
+ * There are several areas that are validated:
+ *
+ *  1) The number of input arguments as defined by the method/object in the
+ *      ASL is validated against the ACPI specification.
+ *  2) The type of the return object (if any) is validated against the ACPI
+ *      specification.
+ *  3) For returned package objects, the count of package elements is
+ *      validated, as well as the type of each package element. Nested
+ *      packages are supported.
+ *
+ * For any problems found, a warning message is issued.
+ *
+ ******************************************************************************/
+/* Local prototypes */
+static acpi_status
+acpi_ns_check_package(char *pathname,
+		      union acpi_operand_object *return_object,
+		      const union acpi_predefined_info *predefined);
+
+static acpi_status
+acpi_ns_check_package_elements(char *pathname,
+			       union acpi_operand_object **elements,
+			       u8 type1, u32 count1, u8 type2, u32 count2);
+
+static acpi_status
+acpi_ns_check_object_type(char *pathname,
+			  union acpi_operand_object *return_object,
+			  u32 expected_btypes, u32 package_index);
+
+static acpi_status
+acpi_ns_check_reference(char *pathname,
+			union acpi_operand_object *return_object);
+
+/*
+ * Names for the types that can be returned by the predefined objects.
+ * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
+ */
+static const char *acpi_rtype_names[] = {
+	"/Integer",
+	"/String",
+	"/Buffer",
+	"/Package",
+	"/Reference",
+};
+
+#define ACPI_NOT_PACKAGE    ACPI_UINT32_MAX
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_predefined_names
+ *
+ * PARAMETERS:  Node            - Namespace node for the method/object
+ *              return_object   - Object returned from the evaluation of this
+ *                                method/object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
+			       union acpi_operand_object *return_object)
+{
+	acpi_status status = AE_OK;
+	const union acpi_predefined_info *predefined;
+	char *pathname;
+
+	/* Match the name for this method/object against the predefined list */
+
+	predefined = acpi_ns_check_for_predefined_name(node);
+	if (!predefined) {
+
+		/* Name was not one of the predefined names */
+
+		return (AE_OK);
+	}
+
+	/* Get the full pathname to the object, for use in error messages */
+
+	pathname = acpi_ns_get_external_pathname(node);
+	if (!pathname) {
+		pathname = ACPI_CAST_PTR(char, predefined->info.name);
+	}
+
+	/*
+	 * Check that the parameter count for this method is in accordance
+	 * with the ACPI specification.
+	 */
+	acpi_ns_check_parameter_count(pathname, node, predefined);
+
+	/*
+	 * If there is no return value, check if we require a return value for
+	 * this predefined name. Either one return value is expected, or none,
+	 * for both methods and other objects.
+	 *
+	 * Exit now if there is no return object. Warning if one was expected.
+	 */
+	if (!return_object) {
+		if ((predefined->info.expected_btypes) &&
+		    (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) {
+			ACPI_ERROR((AE_INFO,
+				    "%s: Missing expected return value",
+				    pathname));
+
+			status = AE_AML_NO_RETURN_VALUE;
+		}
+		goto exit;
+	}
+
+	/*
+	 * We have a return value, but if one wasn't expected, just exit, this is
+	 * not a problem
+	 *
+	 * For example, if "Implicit return value" is enabled, methods will
+	 * always return a value
+	 */
+	if (!predefined->info.expected_btypes) {
+		goto exit;
+	}
+
+	/*
+	 * Check that the type of the return object is what is expected for
+	 * this predefined name
+	 */
+	status = acpi_ns_check_object_type(pathname, return_object,
+					   predefined->info.expected_btypes,
+					   ACPI_NOT_PACKAGE);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* For returned Package objects, check the type of all sub-objects */
+
+	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+		status =
+		    acpi_ns_check_package(pathname, return_object, predefined);
+	}
+
+      exit:
+	if (pathname) {
+		ACPI_FREE(pathname);
+	}
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_parameter_count
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              Node            - Namespace node for the method/object
+ *              Predefined      - Pointer to entry in predefined name table
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
+ *              predefined name is what is expected (i.e., what is defined in
+ *              the ACPI specification for this predefined name.)
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_check_parameter_count(char *pathname,
+			      struct acpi_namespace_node *node,
+			      const union acpi_predefined_info *predefined)
+{
+	u32 param_count;
+	u32 required_params_current;
+	u32 required_params_old;
+
+	/*
+	 * Check that the ASL-defined parameter count is what is expected for
+	 * this predefined name.
+	 *
+	 * Methods have 0-7 parameters. All other types have zero.
+	 */
+	param_count = 0;
+	if (node->type == ACPI_TYPE_METHOD) {
+		param_count = node->object->method.param_count;
+	}
+
+	/* Validate parameter count - allow two different legal counts (_SCP) */
+
+	required_params_current = predefined->info.param_count & 0x0F;
+	required_params_old = predefined->info.param_count >> 4;
+
+	if ((param_count != required_params_current) &&
+	    (param_count != required_params_old)) {
+		ACPI_WARNING((AE_INFO,
+			      "%s: Parameter count mismatch - ASL declared %d, expected %d",
+			      pathname, param_count, required_params_current));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_for_predefined_name
+ *
+ * PARAMETERS:  Node            - Namespace node for the method/object
+ *
+ * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
+ *
+ * DESCRIPTION: Check an object name against the predefined object list.
+ *
+ ******************************************************************************/
+
+const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
+								    acpi_namespace_node
+								    *node)
+{
+	const union acpi_predefined_info *this_name;
+
+	/* Quick check for a predefined name, first character must be underscore */
+
+	if (node->name.ascii[0] != '_') {
+		return (NULL);
+	}
+
+	/* Search info table for a predefined method/object name */
+
+	this_name = predefined_names;
+	while (this_name->info.name[0]) {
+		if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) {
+
+			/* Return pointer to this table entry */
+
+			return (this_name);
+		}
+
+		/*
+		 * Skip next entry in the table if this name returns a Package
+		 * (next entry contains the package info)
+		 */
+		if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
+			this_name++;
+		}
+
+		this_name++;
+	}
+
+	return (NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_package
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              return_object   - Object returned from the evaluation of a
+ *                                method or object
+ *              Predefined      - Pointer to entry in predefined name table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check a returned package object for the correct count and
+ *              correct type of all sub-objects.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_package(char *pathname,
+		      union acpi_operand_object *return_object,
+		      const union acpi_predefined_info *predefined)
+{
+	const union acpi_predefined_info *package;
+	union acpi_operand_object *sub_package;
+	union acpi_operand_object **elements;
+	union acpi_operand_object **sub_elements;
+	acpi_status status;
+	u32 expected_count;
+	u32 count;
+	u32 i;
+	u32 j;
+
+	ACPI_FUNCTION_NAME(ns_check_package);
+
+	/* The package info for this name is in the next table entry */
+
+	package = predefined + 1;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
+			  "%s Validating return Package of Type %X, Count %X\n",
+			  pathname, package->ret_info.type,
+			  return_object->package.count));
+
+	/* Extract package count and elements array */
+
+	elements = return_object->package.elements;
+	count = return_object->package.count;
+
+	/* The package must have at least one element, else invalid */
+
+	if (!count) {
+		ACPI_WARNING((AE_INFO,
+			      "%s: Return Package has no elements (empty)",
+			      pathname));
+
+		return (AE_AML_OPERAND_VALUE);
+	}
+
+	/*
+	 * Decode the type of the expected package contents
+	 *
+	 * PTYPE1 packages contain no subpackages
+	 * PTYPE2 packages contain sub-packages
+	 */
+	switch (package->ret_info.type) {
+	case ACPI_PTYPE1_FIXED:
+
+		/*
+		 * The package count is fixed and there are no sub-packages
+		 *
+		 * If package is too small, exit.
+		 * If package is larger than expected, issue warning but continue
+		 */
+		expected_count =
+		    package->ret_info.count1 + package->ret_info.count2;
+		if (count < expected_count) {
+			goto package_too_small;
+		} else if (count > expected_count) {
+			ACPI_WARNING((AE_INFO,
+				      "%s: Return Package is larger than needed - "
+				      "found %u, expected %u", pathname, count,
+				      expected_count));
+		}
+
+		/* Validate all elements of the returned package */
+
+		status = acpi_ns_check_package_elements(pathname, elements,
+							package->ret_info.
+							object_type1,
+							package->ret_info.
+							count1,
+							package->ret_info.
+							object_type2,
+							package->ret_info.
+							count2);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+		break;
+
+	case ACPI_PTYPE1_VAR:
+
+		/*
+		 * The package count is variable, there are no sub-packages, and all
+		 * elements must be of the same type
+		 */
+		for (i = 0; i < count; i++) {
+			status = acpi_ns_check_object_type(pathname, *elements,
+							   package->ret_info.
+							   object_type1, i);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+			elements++;
+		}
+		break;
+
+	case ACPI_PTYPE1_OPTION:
+
+		/*
+		 * The package count is variable, there are no sub-packages. There are
+		 * a fixed number of required elements, and a variable number of
+		 * optional elements.
+		 *
+		 * Check if package is at least as large as the minimum required
+		 */
+		expected_count = package->ret_info3.count;
+		if (count < expected_count) {
+			goto package_too_small;
+		}
+
+		/* Variable number of sub-objects */
+
+		for (i = 0; i < count; i++) {
+			if (i < package->ret_info3.count) {
+
+				/* These are the required package elements (0, 1, or 2) */
+
+				status =
+				    acpi_ns_check_object_type(pathname,
+							      *elements,
+							      package->
+							      ret_info3.
+							      object_type[i],
+							      i);
+				if (ACPI_FAILURE(status)) {
+					return (status);
+				}
+			} else {
+				/* These are the optional package elements */
+
+				status =
+				    acpi_ns_check_object_type(pathname,
+							      *elements,
+							      package->
+							      ret_info3.
+							      tail_object_type,
+							      i);
+				if (ACPI_FAILURE(status)) {
+					return (status);
+				}
+			}
+			elements++;
+		}
+		break;
+
+	case ACPI_PTYPE2_PKG_COUNT:
+
+		/* First element is the (Integer) count of sub-packages to follow */
+
+		status = acpi_ns_check_object_type(pathname, *elements,
+						   ACPI_RTYPE_INTEGER, 0);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		/*
+		 * Count cannot be larger than the parent package length, but allow it
+		 * to be smaller. The >= accounts for the Integer above.
+		 */
+		expected_count = (u32) (*elements)->integer.value;
+		if (expected_count >= count) {
+			goto package_too_small;
+		}
+
+		count = expected_count;
+		elements++;
+
+		/* Now we can walk the sub-packages */
+
+		/*lint -fallthrough */
+
+	case ACPI_PTYPE2:
+	case ACPI_PTYPE2_FIXED:
+	case ACPI_PTYPE2_MIN:
+	case ACPI_PTYPE2_COUNT:
+
+		/*
+		 * These types all return a single package that consists of a variable
+		 * number of sub-packages
+		 */
+		for (i = 0; i < count; i++) {
+			sub_package = *elements;
+			sub_elements = sub_package->package.elements;
+
+			/* Each sub-object must be of type Package */
+
+			status =
+			    acpi_ns_check_object_type(pathname, sub_package,
+						      ACPI_RTYPE_PACKAGE, i);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+
+			/* Examine the different types of sub-packages */
+
+			switch (package->ret_info.type) {
+			case ACPI_PTYPE2:
+			case ACPI_PTYPE2_PKG_COUNT:
+
+				/* Each subpackage has a fixed number of elements */
+
+				expected_count =
+				    package->ret_info.count1 +
+				    package->ret_info.count2;
+				if (sub_package->package.count !=
+				    expected_count) {
+					count = sub_package->package.count;
+					goto package_too_small;
+				}
+
+				status =
+				    acpi_ns_check_package_elements(pathname,
+								   sub_elements,
+								   package->
+								   ret_info.
+								   object_type1,
+								   package->
+								   ret_info.
+								   count1,
+								   package->
+								   ret_info.
+								   object_type2,
+								   package->
+								   ret_info.
+								   count2);
+				if (ACPI_FAILURE(status)) {
+					return (status);
+				}
+				break;
+
+			case ACPI_PTYPE2_FIXED:
+
+				/* Each sub-package has a fixed length */
+
+				expected_count = package->ret_info2.count;
+				if (sub_package->package.count < expected_count) {
+					count = sub_package->package.count;
+					goto package_too_small;
+				}
+
+				/* Check the type of each sub-package element */
+
+				for (j = 0; j < expected_count; j++) {
+					status =
+					    acpi_ns_check_object_type(pathname,
+								      sub_elements
+								      [j],
+								      package->
+								      ret_info2.
+								      object_type
+								      [j], j);
+					if (ACPI_FAILURE(status)) {
+						return (status);
+					}
+				}
+				break;
+
+			case ACPI_PTYPE2_MIN:
+
+				/* Each sub-package has a variable but minimum length */
+
+				expected_count = package->ret_info.count1;
+				if (sub_package->package.count < expected_count) {
+					count = sub_package->package.count;
+					goto package_too_small;
+				}
+
+				/* Check the type of each sub-package element */
+
+				status =
+				    acpi_ns_check_package_elements(pathname,
+								   sub_elements,
+								   package->
+								   ret_info.
+								   object_type1,
+								   sub_package->
+								   package.
+								   count, 0, 0);
+				if (ACPI_FAILURE(status)) {
+					return (status);
+				}
+				break;
+
+			case ACPI_PTYPE2_COUNT:
+
+				/* First element is the (Integer) count of elements to follow */
+
+				status =
+				    acpi_ns_check_object_type(pathname,
+							      *sub_elements,
+							      ACPI_RTYPE_INTEGER,
+							      0);
+				if (ACPI_FAILURE(status)) {
+					return (status);
+				}
+
+				/* Make sure package is large enough for the Count */
+
+				expected_count =
+				    (u32) (*sub_elements)->integer.value;
+				if (sub_package->package.count < expected_count) {
+					count = sub_package->package.count;
+					goto package_too_small;
+				}
+
+				/* Check the type of each sub-package element */
+
+				status =
+				    acpi_ns_check_package_elements(pathname,
+								   (sub_elements
+								    + 1),
+								   package->
+								   ret_info.
+								   object_type1,
+								   (expected_count
+								    - 1), 0, 0);
+				if (ACPI_FAILURE(status)) {
+					return (status);
+				}
+				break;
+
+			default:
+				break;
+			}
+
+			elements++;
+		}
+		break;
+
+	default:
+
+		/* Should not get here if predefined info table is correct */
+
+		ACPI_WARNING((AE_INFO,
+			      "%s: Invalid internal return type in table entry: %X",
+			      pathname, package->ret_info.type));
+
+		return (AE_AML_INTERNAL);
+	}
+
+	return (AE_OK);
+
+      package_too_small:
+
+	/* Error exit for the case with an incorrect package count */
+
+	ACPI_WARNING((AE_INFO, "%s: Return Package is too small - "
+		      "found %u, expected %u", pathname, count,
+		      expected_count));
+
+	return (AE_AML_OPERAND_VALUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_package_elements
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              Elements        - Pointer to the package elements array
+ *              Type1           - Object type for first group
+ *              Count1          - Count for first group
+ *              Type2           - Object type for second group
+ *              Count2          - Count for second group
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check that all elements of a package are of the correct object
+ *              type. Supports up to two groups of different object types.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_package_elements(char *pathname,
+			       union acpi_operand_object **elements,
+			       u8 type1, u32 count1, u8 type2, u32 count2)
+{
+	union acpi_operand_object **this_element = elements;
+	acpi_status status;
+	u32 i;
+
+	/*
+	 * Up to two groups of package elements are supported by the data
+	 * structure. All elements in each group must be of the same type.
+	 * The second group can have a count of zero.
+	 */
+	for (i = 0; i < count1; i++) {
+		status = acpi_ns_check_object_type(pathname, *this_element,
+						   type1, i);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+		this_element++;
+	}
+
+	for (i = 0; i < count2; i++) {
+		status = acpi_ns_check_object_type(pathname, *this_element,
+						   type2, (i + count1));
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+		this_element++;
+	}
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_object_type
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              return_object   - Object return from the execution of this
+ *                                method/object
+ *              expected_btypes - Bitmap of expected return type(s)
+ *              package_index   - Index of object within parent package (if
+ *                                applicable - ACPI_NOT_PACKAGE otherwise)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check the type of the return object against the expected object
+ *              type(s). Use of Btype allows multiple expected object types.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_object_type(char *pathname,
+			  union acpi_operand_object *return_object,
+			  u32 expected_btypes, u32 package_index)
+{
+	acpi_status status = AE_OK;
+	u32 return_btype;
+	char type_buffer[48];	/* Room for 5 types */
+	u32 this_rtype;
+	u32 i;
+	u32 j;
+
+	/*
+	 * If we get a NULL return_object here, it is a NULL package element,
+	 * and this is always an error.
+	 */
+	if (!return_object) {
+		goto type_error_exit;
+	}
+
+	/* A Namespace node should not get here, but make sure */
+
+	if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
+		ACPI_WARNING((AE_INFO,
+			      "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
+			      pathname, return_object->node.name.ascii,
+			      acpi_ut_get_type_name(return_object->node.type)));
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	/*
+	 * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
+	 * The bitmapped type allows multiple possible return types.
+	 *
+	 * Note, the cases below must handle all of the possible types returned
+	 * from all of the predefined names (including elements of returned
+	 * packages)
+	 */
+	switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+	case ACPI_TYPE_INTEGER:
+		return_btype = ACPI_RTYPE_INTEGER;
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		return_btype = ACPI_RTYPE_BUFFER;
+		break;
+
+	case ACPI_TYPE_STRING:
+		return_btype = ACPI_RTYPE_STRING;
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+		return_btype = ACPI_RTYPE_PACKAGE;
+		break;
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+		return_btype = ACPI_RTYPE_REFERENCE;
+		break;
+
+	default:
+		/* Not one of the supported objects, must be incorrect */
+
+		goto type_error_exit;
+	}
+
+	/* Is the object one of the expected types? */
+
+	if (!(return_btype & expected_btypes)) {
+		goto type_error_exit;
+	}
+
+	/* For reference objects, check that the reference type is correct */
+
+	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+		status = acpi_ns_check_reference(pathname, return_object);
+	}
+
+	return (status);
+
+      type_error_exit:
+
+	/* Create a string with all expected types for this predefined object */
+
+	j = 1;
+	type_buffer[0] = 0;
+	this_rtype = ACPI_RTYPE_INTEGER;
+
+	for (i = 0; i < ACPI_NUM_RTYPES; i++) {
+
+		/* If one of the expected types, concatenate the name of this type */
+
+		if (expected_btypes & this_rtype) {
+			ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]);
+			j = 0;	/* Use name separator from now on */
+		}
+		this_rtype <<= 1;	/* Next Rtype */
+	}
+
+	if (package_index == ACPI_NOT_PACKAGE) {
+		ACPI_WARNING((AE_INFO,
+			      "%s: Return type mismatch - found %s, expected %s",
+			      pathname,
+			      acpi_ut_get_object_type_name(return_object),
+			      type_buffer));
+	} else {
+		ACPI_WARNING((AE_INFO,
+			      "%s: Return Package type mismatch at index %u - "
+			      "found %s, expected %s", pathname, package_index,
+			      acpi_ut_get_object_type_name(return_object),
+			      type_buffer));
+	}
+
+	return (AE_AML_OPERAND_TYPE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_reference
+ *
+ * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
+ *              return_object   - Object returned from the evaluation of a
+ *                                method or object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check a returned reference object for the correct reference
+ *              type. The only reference type that can be returned from a
+ *              predefined method is a named reference. All others are invalid.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_check_reference(char *pathname,
+			union acpi_operand_object *return_object)
+{
+
+	/*
+	 * Check the reference object for the correct reference type (opcode).
+	 * The only type of reference that can be converted to an union acpi_object is
+	 * a reference to a named object (reference class: NAME)
+	 */
+	if (return_object->reference.class == ACPI_REFCLASS_NAME) {
+		return (AE_OK);
+	}
+
+	ACPI_WARNING((AE_INFO,
+		      "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+		      pathname, acpi_ut_get_reference_name(return_object),
+		      return_object->reference.class));
+
+	return (AE_AML_OPERAND_TYPE);
+}
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index 8399276cba1e..a9a80bf811b3 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -331,7 +331,7 @@ acpi_ns_search_and_enter(u32 target_name,
 				      "Found bad character(s) in name, repaired: [%4.4s]\n",
 				      ACPI_CAST_PTR(char, &target_name)));
 		} else {
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					  "Found bad character(s) in name, repaired: [%4.4s]\n",
 					  ACPI_CAST_PTR(char, &target_name)));
 		}
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 38be5865d95d..a085cc39c055 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -48,6 +48,10 @@
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsxfeval")
+
+/* Local prototypes */
+static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
+
 #ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
@@ -69,6 +73,7 @@ ACPI_MODULE_NAME("nsxfeval")
  *              be valid (non-null)
  *
  ******************************************************************************/
+
 acpi_status
 acpi_evaluate_object_typed(acpi_handle handle,
 			   acpi_string pathname,
@@ -283,6 +288,10 @@ acpi_evaluate_object(acpi_handle handle,
 
 			if (ACPI_SUCCESS(status)) {
 
+				/* Dereference Index and ref_of references */
+
+				acpi_ns_resolve_references(info);
+
 				/* Get the size of the returned object */
 
 				status =
@@ -352,6 +361,74 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ns_resolve_references
+ *
+ * PARAMETERS:  Info                    - Evaluation info block
+ *
+ * RETURN:      Info->return_object is replaced with the dereferenced object
+ *
+ * DESCRIPTION: Dereference certain reference objects. Called before an
+ *              internal return object is converted to an external union acpi_object.
+ *
+ * Performs an automatic dereference of Index and ref_of reference objects.
+ * These reference objects are not supported by the union acpi_object, so this is a
+ * last resort effort to return something useful. Also, provides compatibility
+ * with other ACPI implementations.
+ *
+ * NOTE: does not handle references within returned package objects or nested
+ * references, but this support could be added later if found to be necessary.
+ *
+ ******************************************************************************/
+static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
+{
+	union acpi_operand_object *obj_desc = NULL;
+	struct acpi_namespace_node *node;
+
+	/* We are interested in reference objects only */
+
+	if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
+	    ACPI_TYPE_LOCAL_REFERENCE) {
+		return;
+	}
+
+	/*
+	 * Two types of references are supported - those created by Index and
+	 * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
+	 * to an union acpi_object, so it is not dereferenced here. A ddb_handle
+	 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
+	 * an union acpi_object.
+	 */
+	switch (info->return_object->reference.class) {
+	case ACPI_REFCLASS_INDEX:
+
+		obj_desc = *(info->return_object->reference.where);
+		break;
+
+	case ACPI_REFCLASS_REFOF:
+
+		node = info->return_object->reference.object;
+		if (node) {
+			obj_desc = node->object;
+		}
+		break;
+
+	default:
+		return;
+	}
+
+	/* Replace the existing reference object */
+
+	if (obj_desc) {
+		acpi_ut_add_reference(obj_desc);
+		acpi_ut_remove_reference(info->return_object);
+		info->return_object = obj_desc;
+	}
+
+	return;
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_walk_namespace
  *
  * PARAMETERS:  Type                - acpi_object_type to search for
@@ -379,6 +456,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
  *              function, etc.
  *
  ******************************************************************************/
+
 acpi_status
 acpi_walk_namespace(acpi_object_type type,
 		    acpi_handle start_object,
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index a287ed550f54..5efa4e7ddb0b 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -253,6 +253,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
 	node = acpi_ns_map_handle_to_node(handle);
 	if (!node) {
 		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+		status = AE_BAD_PARAMETER;
 		goto cleanup;
 	}
 
@@ -264,6 +265,10 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
 	info->name = node->name.integer;
 	info->valid = 0;
 
+	if (node->type == ACPI_TYPE_METHOD) {
+		info->param_count = node->object->method.param_count;
+	}
+
 	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE(status)) {
 		goto cleanup;
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index cb9864e39bae..25ceae9191ef 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -258,7 +258,7 @@ int __init acpi_numa_init(void)
 
 int acpi_get_pxm(acpi_handle h)
 {
-	unsigned long pxm;
+	unsigned long long pxm;
 	acpi_status status;
 	acpi_handle handle;
 	acpi_handle phandle = h;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 235a1386888a..4be252145cb4 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -608,7 +608,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle,	/* upper bound  */
 	acpi_handle handle;
 	struct acpi_pci_id *pci_id = *id;
 	acpi_status status;
-	unsigned long temp;
+	unsigned long long temp;
 	acpi_object_type type;
 
 	acpi_get_parent(chandle, &handle);
@@ -620,8 +620,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle,	/* upper bound  */
 		if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
 			return;
 
-		status =
-		    acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
+		status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
 					  &temp);
 		if (ACPI_SUCCESS(status)) {
 			u32 val;
@@ -682,6 +681,22 @@ static void acpi_os_execute_deferred(struct work_struct *work)
 	return;
 }
 
+static void acpi_os_execute_hp_deferred(struct work_struct *work)
+{
+	struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
+	if (!dpc) {
+		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
+		return;
+	}
+
+	acpi_os_wait_events_complete(NULL);
+
+	dpc->function(dpc->context);
+	kfree(dpc);
+
+	return;
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_os_execute
@@ -697,12 +712,13 @@ static void acpi_os_execute_deferred(struct work_struct *work)
  *
  ******************************************************************************/
 
-acpi_status acpi_os_execute(acpi_execute_type type,
-			    acpi_osd_exec_callback function, void *context)
+static acpi_status __acpi_os_execute(acpi_execute_type type,
+	acpi_osd_exec_callback function, void *context, int hp)
 {
 	acpi_status status = AE_OK;
 	struct acpi_os_dpc *dpc;
 	struct workqueue_struct *queue;
+	int ret;
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 			  "Scheduling function [%p(%p)] for deferred execution.\n",
 			  function, context));
@@ -726,19 +742,38 @@ acpi_status acpi_os_execute(acpi_execute_type type,
 	dpc->function = function;
 	dpc->context = context;
 
-	INIT_WORK(&dpc->work, acpi_os_execute_deferred);
-	queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq;
-	if (!queue_work(queue, &dpc->work)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			  "Call to queue_work() failed.\n"));
+	if (!hp) {
+		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+		queue = (type == OSL_NOTIFY_HANDLER) ?
+			kacpi_notify_wq : kacpid_wq;
+		ret = queue_work(queue, &dpc->work);
+	} else {
+		INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred);
+		ret = schedule_work(&dpc->work);
+	}
+
+	if (!ret) {
+		printk(KERN_ERR PREFIX
+			  "Call to queue_work() failed.\n");
 		status = AE_ERROR;
 		kfree(dpc);
 	}
 	return_ACPI_STATUS(status);
 }
 
+acpi_status acpi_os_execute(acpi_execute_type type,
+			    acpi_osd_exec_callback function, void *context)
+{
+	return __acpi_os_execute(type, function, context, 0);
+}
 EXPORT_SYMBOL(acpi_os_execute);
 
+acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
+	void *context)
+{
+	return __acpi_os_execute(0, function, context, 1);
+}
+
 void acpi_os_wait_events_complete(void *context)
 {
 	flush_workqueue(kacpid_wq);
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index c06238e55d98..4647039a0d8a 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -719,6 +719,8 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
 		*op = NULL;
 	}
 
+	ACPI_PREEMPTION_POINT();
+
 	return_ACPI_STATUS(AE_OK);
 }
 
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index 15e1702e48d6..68e932f215ea 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
 	union acpi_parse_object *next;
 	const struct acpi_opcode_info *parent_info;
 	union acpi_parse_object *replacement_op = NULL;
+	acpi_status status = AE_OK;
 
 	ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op);
 
@@ -186,7 +187,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
 			replacement_op =
 			    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
 			if (!replacement_op) {
-				goto allocate_error;
+				status = AE_NO_MEMORY;
 			}
 			break;
 
@@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
 				replacement_op =
 				    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
 				if (!replacement_op) {
-					goto allocate_error;
+					status = AE_NO_MEMORY;
 				}
 			} else
 			    if ((op->common.parent->common.aml_opcode ==
@@ -226,13 +227,13 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
 					    acpi_ps_alloc_op(op->common.
 							     aml_opcode);
 					if (!replacement_op) {
-						goto allocate_error;
+						status = AE_NO_MEMORY;
+					} else {
+						replacement_op->named.data =
+						    op->named.data;
+						replacement_op->named.length =
+						    op->named.length;
 					}
-
-					replacement_op->named.data =
-					    op->named.data;
-					replacement_op->named.length =
-					    op->named.length;
 				}
 			}
 			break;
@@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
 			replacement_op =
 			    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
 			if (!replacement_op) {
-				goto allocate_error;
+				status = AE_NO_MEMORY;
 			}
 		}
 
@@ -302,14 +303,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
 	/* Now we can actually delete the subtree rooted at Op */
 
 	acpi_ps_delete_parse_tree(op);
-	return_ACPI_STATUS(AE_OK);
-
-      allocate_error:
-
-	/* Always delete the subtree, even on error */
-
-	acpi_ps_delete_parse_tree(op);
-	return_ACPI_STATUS(AE_NO_MEMORY);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -641,10 +635,12 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
 					    ACPI_WALK_METHOD_RESTART;
 				}
 			} else {
-				/* On error, delete any return object */
+				/* On error, delete any return object or implicit return */
 
 				acpi_ut_remove_reference(previous_walk_state->
 							 return_desc);
+				acpi_ds_clear_implicit_return
+				    (previous_walk_state);
 			}
 		}
 
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index cf47805a7448..fcfdef7b4fdd 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -709,7 +709,7 @@ int acpi_pci_link_free_irq(acpi_handle handle)
 			  acpi_device_bid(link->device)));
 
 	if (link->refcnt == 0) {
-		acpi_ut_evaluate_object(link->device->handle, "_DIS", 0, NULL);
+		acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
 	}
 	mutex_unlock(&acpi_link_lock);
 	return (link->irq.active);
@@ -737,7 +737,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
 	link->device = device;
 	strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
-	acpi_driver_data(device) = link;
+	device->driver_data = link;
 
 	mutex_lock(&acpi_link_lock);
 	result = acpi_pci_link_get_possible(link);
@@ -773,7 +773,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
 
       end:
 	/* disable all links -- to be activated on use */
-	acpi_ut_evaluate_object(device->handle, "_DIS", 0, NULL);
+	acpi_evaluate_object(device->handle, "_DIS", NULL, NULL);
 	mutex_unlock(&acpi_link_lock);
 
 	if (result)
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index c3fed31166b5..1b8f67d21d53 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -190,7 +190,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
 	struct acpi_pci_root *root = NULL;
 	struct acpi_pci_root *tmp;
 	acpi_status status = AE_OK;
-	unsigned long value = 0;
+	unsigned long long value = 0;
 	acpi_handle handle = NULL;
 	struct acpi_device *child;
 
@@ -206,7 +206,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
 	root->device = device;
 	strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
-	acpi_driver_data(device) = root;
+	device->driver_data = root;
 
 	device->ops.bind = acpi_pci_bind;
 
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index 8d4a568be1cc..cd1f4467be7b 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -76,10 +76,10 @@ static struct acpi_pci_driver acpi_pci_slot_driver = {
 };
 
 static int
-check_slot(acpi_handle handle, unsigned long *sun)
+check_slot(acpi_handle handle, unsigned long long *sun)
 {
 	int device = -1;
-	unsigned long adr, sta;
+	unsigned long long adr, sta;
 	acpi_status status;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
@@ -132,7 +132,7 @@ static acpi_status
 register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
 	int device;
-	unsigned long sun;
+	unsigned long long sun;
 	char name[SLOT_NAME_SIZE];
 	struct acpi_pci_slot *slot;
 	struct pci_slot *pci_slot;
@@ -182,7 +182,7 @@ static acpi_status
 walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
 	int device, function;
-	unsigned long adr;
+	unsigned long long adr;
 	acpi_status status;
 	acpi_handle dummy_handle;
 	acpi_walk_callback user_function;
@@ -239,7 +239,7 @@ static int
 walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
 {
 	int seg, bus;
-	unsigned long tmp;
+	unsigned long long tmp;
 	acpi_status status;
 	acpi_handle dummy_handle;
 	struct pci_bus *pci_bus;
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 4ab21cb1c8c7..a1718e56103b 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -54,6 +54,14 @@ ACPI_MODULE_NAME("power");
 #define ACPI_POWER_RESOURCE_STATE_OFF	0x00
 #define ACPI_POWER_RESOURCE_STATE_ON	0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
+
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "acpi."
+int acpi_power_nocheck;
+module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
+
 static int acpi_power_add(struct acpi_device *device);
 static int acpi_power_remove(struct acpi_device *device, int type);
 static int acpi_power_resume(struct acpi_device *device);
@@ -128,16 +136,16 @@ acpi_power_get_context(acpi_handle handle,
 	return 0;
 }
 
-static int acpi_power_get_state(struct acpi_power_resource *resource, int *state)
+static int acpi_power_get_state(acpi_handle handle, int *state)
 {
 	acpi_status status = AE_OK;
-	unsigned long sta = 0;
+	unsigned long long sta = 0;
 
 
-	if (!resource || !state)
+	if (!handle || !state)
 		return -EINVAL;
 
-	status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
@@ -145,7 +153,7 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state
 			      ACPI_POWER_RESOURCE_STATE_OFF;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
-			  resource->name, state ? "on" : "off"));
+			  acpi_ut_get_node_name(handle), state ? "on" : "off"));
 
 	return 0;
 }
@@ -153,7 +161,6 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state
 static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
 {
 	int result = 0, state1;
-	struct acpi_power_resource *resource = NULL;
 	u32 i = 0;
 
 
@@ -161,12 +168,15 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
 		return -EINVAL;
 
 	/* The state of the list is 'on' IFF all resources are 'on'. */
+	/* */
 
 	for (i = 0; i < list->count; i++) {
-		result = acpi_power_get_context(list->handles[i], &resource);
-		if (result)
-			return result;
-		result = acpi_power_get_state(resource, &state1);
+		/*
+		 * The state of the power resource can be obtained by
+		 * using the ACPI handle. In such case it is unnecessary to
+		 * get the Power resource first and then get its state again.
+		 */
+		result = acpi_power_get_state(list->handles[i], &state1);
 		if (result)
 			return result;
 
@@ -226,12 +236,18 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
-	result = acpi_power_get_state(resource, &state);
-	if (result)
-		return result;
-	if (state != ACPI_POWER_RESOURCE_STATE_ON)
-		return -ENOEXEC;
-
+	if (!acpi_power_nocheck) {
+		/*
+		 * If acpi_power_nocheck is set, it is unnecessary to check
+		 * the power state after power transition.
+		 */
+		result = acpi_power_get_state(resource->device->handle,
+				&state);
+		if (result)
+			return result;
+		if (state != ACPI_POWER_RESOURCE_STATE_ON)
+			return -ENOEXEC;
+	}
 	/* Update the power resource's _device_ power state */
 	resource->device->power.state = ACPI_STATE_D0;
 
@@ -277,11 +293,17 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
-	result = acpi_power_get_state(resource, &state);
-	if (result)
-		return result;
-	if (state != ACPI_POWER_RESOURCE_STATE_OFF)
-		return -ENOEXEC;
+	if (!acpi_power_nocheck) {
+		/*
+		 * If acpi_power_nocheck is set, it is unnecessary to check
+		 * the power state after power transition.
+		 */
+		result = acpi_power_get_state(handle, &state);
+		if (result)
+			return result;
+		if (state != ACPI_POWER_RESOURCE_STATE_OFF)
+			return -ENOEXEC;
+	}
 
 	/* Update the power resource's _device_ power state */
 	resource->device->power.state = ACPI_STATE_D3;
@@ -555,7 +577,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
 	if (!resource)
 		goto end;
 
-	result = acpi_power_get_state(resource, &state);
+	result = acpi_power_get_state(resource->device->handle, &state);
 	if (result)
 		goto end;
 
@@ -657,7 +679,7 @@ static int acpi_power_add(struct acpi_device *device)
 	strcpy(resource->name, device->pnp.bus_id);
 	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
-	acpi_driver_data(device) = resource;
+	device->driver_data = resource;
 
 	/* Evalute the object to get the system level and resource order. */
 	status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);
@@ -668,7 +690,7 @@ static int acpi_power_add(struct acpi_device *device)
 	resource->system_level = acpi_object.power_resource.system_level;
 	resource->order = acpi_object.power_resource.resource_order;
 
-	result = acpi_power_get_state(resource, &state);
+	result = acpi_power_get_state(device->handle, &state);
 	if (result)
 		goto end;
 
@@ -733,9 +755,9 @@ static int acpi_power_resume(struct acpi_device *device)
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
-	resource = (struct acpi_power_resource *)acpi_driver_data(device);
+	resource = acpi_driver_data(device);
 
-	result = acpi_power_get_state(resource, &state);
+	result = acpi_power_get_state(device->handle, &state);
 	if (result)
 		return result;
 
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index ee68ac54c0d4..24a362f8034c 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -563,7 +563,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
 
 	/* Check if it is a Device with HID and UID */
 	if (has_uid) {
-		unsigned long value;
+		unsigned long long value;
 		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
 						NULL, &value);
 		if (ACPI_FAILURE(status)) {
@@ -818,7 +818,7 @@ static int acpi_processor_add(struct acpi_device *device)
 	pr->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
-	acpi_driver_data(device) = pr;
+	device->driver_data = pr;
 
 	return 0;
 }
@@ -875,7 +875,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
 static int is_processor_present(acpi_handle handle)
 {
 	acpi_status status;
-	unsigned long sta = 0;
+	unsigned long long sta = 0;
 
 
 	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index cf5b1b7b684f..81b40ed5379e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1587,6 +1587,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 
 	if (acpi_idle_bm_check()) {
 		if (dev->safe_state) {
+			dev->last_state = dev->safe_state;
 			return dev->safe_state->enter(dev, dev->safe_state);
 		} else {
 			local_irq_disable();
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 80c251ec6d2a..dc98f7a6f2c4 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -38,6 +38,7 @@
 
 #include <asm/uaccess.h>
 #endif
+#include <asm/cpufeature.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/processor.h>
@@ -126,7 +127,7 @@ static struct notifier_block acpi_ppc_notifier_block = {
 static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
 {
 	acpi_status status = 0;
-	unsigned long ppc = 0;
+	unsigned long long ppc = 0;
 
 
 	if (!pr)
@@ -334,7 +335,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
 	acpi_status status = AE_OK;
 	acpi_handle handle = NULL;
 
-
 	if (!pr || !pr->performance || !pr->handle)
 		return -EINVAL;
 
@@ -347,13 +347,25 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
 
 	result = acpi_processor_get_performance_control(pr);
 	if (result)
-		return result;
+		goto update_bios;
 
 	result = acpi_processor_get_performance_states(pr);
 	if (result)
-		return result;
+		goto update_bios;
 
 	return 0;
+
+	/*
+	 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
+	 * the BIOS is older than the CPU and does not know its frequencies
+	 */
+ update_bios:
+	if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){
+		if(boot_cpu_has(X86_FEATURE_EST))
+			printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
+			       "frequency support\n");
+	}
+	return result;
 }
 
 int acpi_processor_notify_smm(struct module *calling_module)
@@ -524,13 +536,13 @@ static int acpi_processor_get_psd(struct acpi_processor	*pr)
 
 	psd = buffer.pointer;
 	if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
+		printk(KERN_ERR PREFIX "Invalid _PSD data\n");
 		result = -EFAULT;
 		goto end;
 	}
 
 	if (psd->package.count != 1) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
+		printk(KERN_ERR PREFIX "Invalid _PSD data\n");
 		result = -EFAULT;
 		goto end;
 	}
@@ -543,19 +555,19 @@ static int acpi_processor_get_psd(struct acpi_processor	*pr)
 	status = acpi_extract_package(&(psd->package.elements[0]),
 		&format, &state);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
+		printk(KERN_ERR PREFIX "Invalid _PSD data\n");
 		result = -EFAULT;
 		goto end;
 	}
 
 	if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n"));
+		printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n");
 		result = -EFAULT;
 		goto end;
 	}
 
 	if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n"));
+		printk(KERN_ERR PREFIX "Unknown _PSD:revision\n");
 		result = -EFAULT;
 		goto end;
 	}
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index a56fc6c4394b..3da2df93d924 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -274,7 +274,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)
 static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
 {
 	acpi_status status = 0;
-	unsigned long tpc = 0;
+	unsigned long long tpc = 0;
 
 	if (!pr)
 		return -EINVAL;
@@ -528,13 +528,13 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
 
 	tsd = buffer.pointer;
 	if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+		printk(KERN_ERR PREFIX "Invalid _TSD data\n");
 		result = -EFAULT;
 		goto end;
 	}
 
 	if (tsd->package.count != 1) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+		printk(KERN_ERR PREFIX "Invalid _TSD data\n");
 		result = -EFAULT;
 		goto end;
 	}
@@ -547,19 +547,19 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr)
 	status = acpi_extract_package(&(tsd->package.elements[0]),
 				      &format, &state);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+		printk(KERN_ERR PREFIX "Invalid _TSD data\n");
 		result = -EFAULT;
 		goto end;
 	}
 
 	if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n"));
+		printk(KERN_ERR PREFIX "Unknown _TSD:num_entries\n");
 		result = -EFAULT;
 		goto end;
 	}
 
 	if (pdomain->revision != ACPI_TSD_REV0_REVISION) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n"));
+		printk(KERN_ERR PREFIX "Unknown _TSD:revision\n");
 		result = -EFAULT;
 		goto end;
 	}
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index a6b662c00b67..755baf2ca70a 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -15,9 +15,28 @@ void acpi_reboot(void)
 
 	rr = &acpi_gbl_FADT.reset_register;
 
-	/* Is the reset register supported? */
-	if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
-	    rr->bit_width != 8 || rr->bit_offset != 0)
+	/*
+	 * Is the ACPI reset register supported?
+	 *
+	 * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates
+	 * whether the ACPI reset mechanism is supported.
+	 *
+	 * However, some boxes have this bit clear, yet a valid
+	 * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only
+	 * mechanism that works for them after S3.
+	 *
+	 * This suggests that other operating systems may not be checking
+	 * the RESET_REG_SUP bit, and are using other means to decide
+	 * whether to use the ACPI reboot mechanism or not.
+	 *
+	 * So when acpi reboot is requested,
+	 * only the reset_register is checked. If the following
+	 * conditions are met, it indicates that the reset register is supported.
+	 * 	a. reset_register is not zero
+	 * 	b. the access width is eight
+	 * 	c. the bit_offset is zero
+	 */
+	if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0)
 		return;
 
 	reset_value = acpi_gbl_FADT.reset_value;
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index d9063ea414e3..8eaaecf92009 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acresrc.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_RESOURCES
@@ -560,8 +559,8 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
 			      ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
 			     ((ACPI_TYPE_LOCAL_REFERENCE ==
 			       ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
-			      ((*sub_object_list)->reference.opcode ==
-			       AML_INT_NAMEPATH_OP)))) {
+			      ((*sub_object_list)->reference.class ==
+			       ACPI_REFCLASS_NAME)))) {
 				name_found = TRUE;
 			} else {
 				/* Look at the next element */
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 7804a8c40e7a..c0bbfa2c4193 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acresrc.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_RESOURCES
@@ -310,13 +309,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
 
-				if (obj_desc->reference.opcode !=
-				    AML_INT_NAMEPATH_OP) {
+				if (obj_desc->reference.class !=
+				    ACPI_REFCLASS_NAME) {
 					ACPI_ERROR((AE_INFO,
-						    "(PRT[%X].Source) Need name, found reference op %X",
+						    "(PRT[%X].Source) Need name, found Reference Class %X",
 						    index,
-						    obj_desc->reference.
-						    opcode));
+						    obj_desc->reference.class));
 					return_ACPI_STATUS(AE_BAD_DATA);
 				}
 
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 7b011e7e29fe..6050ce481873 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -931,7 +931,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 	sbs->device = device;
 	strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
-	acpi_driver_data(device) = sbs;
+	device->driver_data = sbs;
 
 	result = acpi_charger_add(sbs);
 	if (result)
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index a4e3767b8c64..e53e590252c0 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -258,7 +258,7 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
 static int acpi_smbus_hc_add(struct acpi_device *device)
 {
 	int status;
-	unsigned long val;
+	unsigned long long val;
 	struct acpi_smb_hc *hc;
 
 	if (!device)
@@ -282,7 +282,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
 	hc->ec = acpi_driver_data(device->parent);
 	hc->offset = (val >> 8) & 0xff;
 	hc->query_bit = val & 0xff;
-	acpi_driver_data(device) = hc;
+	device->driver_data = hc;
 
 	acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
 	printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
@@ -303,7 +303,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
 	hc = acpi_driver_data(device);
 	acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
 	kfree(hc);
-	acpi_driver_data(device) = NULL;
+	device->driver_data = NULL;
 	return 0;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f6f52c1a2aba..a9dda8e0f9f9 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -113,16 +113,16 @@ static int acpi_bus_hot_remove_device(void *context)
 
 
 	if (acpi_bus_trim(device, 1)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				"Removing device failed\n"));
+		printk(KERN_ERR PREFIX
+				"Removing device failed\n");
 		return -1;
 	}
 
 	/* power off device */
 	status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				"Power-off device failed\n"));
+		printk(KERN_WARNING PREFIX
+				"Power-off device failed\n");
 
 	if (device->flags.lockable) {
 		arg_list.count = 1;
@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device,
 {
 	const struct acpi_device_id *id;
 
+	/*
+	 * If the device is not present, it is unnecessary to load device
+	 * driver for it.
+	 */
+	if (!device->status.present)
+		return -ENODEV;
+
 	if (device->flags.hardware_id) {
 		for (id = ids; id->id[0]; id++) {
 			if (!strcmp((char*)id->id, device->pnp.hardware_id))
@@ -384,7 +391,7 @@ static int acpi_device_remove(struct device * dev)
 			acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
 	}
 	acpi_dev->driver = NULL;
-	acpi_driver_data(dev) = NULL;
+	acpi_dev->driver_data = NULL;
 
 	put_device(dev);
 	return 0;
@@ -477,7 +484,7 @@ static int acpi_device_register(struct acpi_device *device,
 
 	result = acpi_device_setup_files(device);
 	if(result)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id));
+		printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id);
 
 	device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
 	return 0;
@@ -537,7 +544,7 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
 	result = driver->ops.add(device);
 	if (result) {
 		device->driver = NULL;
-		acpi_driver_data(device) = NULL;
+		device->driver_data = NULL;
 		return result;
 	}
 
@@ -744,6 +751,16 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
 	if (!acpi_match_device_ids(device, button_device_ids))
 		device->wakeup.flags.run_wake = 1;
 
+	/*
+	 * Don't set Power button GPE as run_wake
+	 * if Fixed Power button is used
+	 */
+	if (!strcmp(device->pnp.hardware_id, "PNP0C0C") &&
+		!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) {
+		device->wakeup.flags.run_wake = 0;
+		device->wakeup.flags.valid = 0;
+	}
+
       end:
 	if (ACPI_FAILURE(status))
 		device->flags.wake_capable = 0;
@@ -807,6 +824,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
 	/* TBD: System wake support and resource requirements. */
 
 	device->power.state = ACPI_STATE_UNKNOWN;
+	acpi_bus_get_power(device->handle, &(device->power.state));
 
 	return 0;
 }
@@ -1153,20 +1171,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
 }
 
 static int
-acpi_is_child_device(struct acpi_device *device,
-			int (*matcher)(struct acpi_device *))
-{
-	int result = -ENODEV;
-
-	do {
-		if (ACPI_SUCCESS(matcher(device)))
-			return AE_OK;
-	} while ((device = device->parent));
-
-	return result;
-}
-
-static int
 acpi_add_single_object(struct acpi_device **child,
 		       struct acpi_device *parent, acpi_handle handle, int type,
 			struct acpi_bus_ops *ops)
@@ -1221,15 +1225,18 @@ acpi_add_single_object(struct acpi_device **child,
 			result = -ENODEV;
 			goto end;
 		}
-		if (!device->status.present) {
-			/* Bay and dock should be handled even if absent */
-			if (!ACPI_SUCCESS(
-			     acpi_is_child_device(device, acpi_bay_match)) &&
-			    !ACPI_SUCCESS(
-			     acpi_is_child_device(device, acpi_dock_match))) {
-					result = -ENODEV;
-					goto end;
-			}
+		/*
+		 * When the device is neither present nor functional, the
+		 * device should not be added to Linux ACPI device tree.
+		 * When the status of the device is not present but functinal,
+		 * it should be added to Linux ACPI tree. For example : bay
+		 * device , dock device.
+		 * In such conditions it is unncessary to check whether it is
+		 * bay device or dock device.
+		 */
+		if (!device->status.present && !device->status.functional) {
+			result = -ENODEV;
+			goto end;
 		}
 		break;
 	default:
@@ -1252,6 +1259,16 @@ acpi_add_single_object(struct acpi_device **child,
 	acpi_device_set_id(device, parent, handle, type);
 
 	/*
+	 * The ACPI device is attached to acpi handle before getting
+	 * the power/wakeup/peformance flags. Otherwise OS can't get
+	 * the corresponding ACPI device by the acpi handle in the course
+	 * of getting the power/wakeup/performance flags.
+	 */
+	result = acpi_device_set_context(device, type);
+	if (result)
+		goto end;
+
+	/*
 	 * Power Management
 	 * ----------------
 	 */
@@ -1281,8 +1298,6 @@ acpi_add_single_object(struct acpi_device **child,
 			goto end;
 	}
 
-	if ((result = acpi_device_set_context(device, type)))
-		goto end;
 
 	result = acpi_device_register(device, parent);
 
@@ -1402,7 +1417,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
 		 * TBD: Need notifications and other detection mechanisms
 		 *      in place before we can fully implement this.
 		 */
-		if (child->status.present) {
+		 /*
+		 * When the device is not present but functional, it is also
+		 * necessary to scan the children of this device.
+		 */
+		if (child->status.present || (!child->status.present &&
+					child->status.functional)) {
 			status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
 						      NULL, NULL);
 			if (ACPI_SUCCESS(status)) {
@@ -1545,7 +1565,6 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
 	return result;
 }
 
-int __init acpi_boot_ec_enable(void);
 
 static int __init acpi_scan_init(void)
 {
@@ -1579,9 +1598,6 @@ static int __init acpi_scan_init(void)
 	 */
 	result = acpi_bus_scan_fixed(acpi_root);
 
-	/* EC region might be needed at bus_scan, so enable it now */
-	acpi_boot_ec_enable();
-
 	if (!result)
 		result = acpi_bus_scan(acpi_root, &ops);
 
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index d13194a031bf..26571bafb158 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -15,6 +15,7 @@
 #include <linux/dmi.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
+#include <linux/reboot.h>
 
 #include <asm/io.h>
 
@@ -24,6 +25,36 @@
 
 u8 sleep_states[ACPI_S_STATE_COUNT];
 
+static void acpi_sleep_tts_switch(u32 acpi_state)
+{
+	union acpi_object in_arg = { ACPI_TYPE_INTEGER };
+	struct acpi_object_list arg_list = { 1, &in_arg };
+	acpi_status status = AE_OK;
+
+	in_arg.integer.value = acpi_state;
+	status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+		/*
+		 * OS can't evaluate the _TTS object correctly. Some warning
+		 * message will be printed. But it won't break anything.
+		 */
+		printk(KERN_NOTICE "Failure in evaluating _TTS object\n");
+	}
+}
+
+static int tts_notify_reboot(struct notifier_block *this,
+			unsigned long code, void *x)
+{
+	acpi_sleep_tts_switch(ACPI_STATE_S5);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block tts_notifier = {
+	.notifier_call	= tts_notify_reboot,
+	.next		= NULL,
+	.priority	= 0,
+};
+
 static int acpi_sleep_prepare(u32 acpi_state)
 {
 #ifdef CONFIG_ACPI_SLEEP
@@ -45,9 +76,8 @@ static int acpi_sleep_prepare(u32 acpi_state)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ACPI_SLEEP
 static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-
 /*
  * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
  * user to request that behavior by using the 'acpi_old_suspend_ordering'
@@ -131,8 +161,9 @@ static void acpi_pm_end(void)
 	 * failing transition to a sleep state.
 	 */
 	acpi_target_sleep_state = ACPI_STATE_S0;
+	acpi_sleep_tts_switch(acpi_target_sleep_state);
 }
-#endif /* CONFIG_PM_SLEEP */
+#endif /* CONFIG_ACPI_SLEEP */
 
 #ifdef CONFIG_SUSPEND
 extern void do_suspend_lowlevel(void);
@@ -155,6 +186,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
 
 	if (sleep_states[acpi_state]) {
 		acpi_target_sleep_state = acpi_state;
+		acpi_sleep_tts_switch(acpi_target_sleep_state);
 	} else {
 		printk(KERN_ERR "ACPI does not support this state: %d\n",
 			pm_state);
@@ -200,6 +232,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
 		break;
 	}
 
+	/* If ACPI is not enabled by the BIOS, we need to enable it here. */
+	acpi_enable();
 	/* Reprogram control registers and execute _BFS */
 	acpi_leave_sleep_state_prep(acpi_state);
 
@@ -296,6 +330,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
 		DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
 		},
 	},
+	{
+	.callback = init_old_suspend_ordering,
+	.ident = "HP xw4600 Workstation",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
+		},
+	},
 	{},
 };
 #endif /* CONFIG_SUSPEND */
@@ -313,6 +355,7 @@ void __init acpi_no_s4_hw_signature(void)
 static int acpi_hibernation_begin(void)
 {
 	acpi_target_sleep_state = ACPI_STATE_S4;
+	acpi_sleep_tts_switch(acpi_target_sleep_state);
 	return 0;
 }
 
@@ -376,7 +419,15 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
  */
 static int acpi_hibernation_begin_old(void)
 {
-	int error = acpi_sleep_prepare(ACPI_STATE_S4);
+	int error;
+	/*
+	 * The _TTS object should always be evaluated before the _PTS object.
+	 * When the old_suspended_ordering is true, the _PTS object is
+	 * evaluated in the acpi_sleep_prepare.
+	 */
+	acpi_sleep_tts_switch(ACPI_STATE_S4);
+
+	error = acpi_sleep_prepare(ACPI_STATE_S4);
 
 	if (!error)
 		acpi_target_sleep_state = ACPI_STATE_S4;
@@ -444,7 +495,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
 	acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
 	struct acpi_device *adev;
 	char acpi_method[] = "_SxD";
-	unsigned long d_min, d_max;
+	unsigned long long d_min, d_max;
 
 	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
 		printk(KERN_DEBUG "ACPI handle has no context!\n");
@@ -596,5 +647,10 @@ int __init acpi_sleep_init(void)
 		pm_power_off = acpi_power_off;
 	}
 	printk(")\n");
+	/*
+	 * Register the tts_notifier to reboot notifier list so that the _TTS
+	 * object can also be evaluated when the system enters S5.
+	 */
+	register_reboot_notifier(&tts_notifier);
 	return 0;
 }
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 24e80fd927e2..1d74171b7940 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -386,8 +386,8 @@ static ssize_t counter_set(struct kobject *kobj,
 		goto end;
 
 	if (!(all_counters[index].flags & ACPI_EVENT_VALID)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-			"Can not change Invalid GPE/Fixed Event status\n"));
+		printk(KERN_WARNING PREFIX
+			"Can not change Invalid GPE/Fixed Event status\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index a4a41ba2484b..2c7885e7ffba 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("tbfadt")
 /* Local prototypes */
 static void inline
 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
-			     u8 bit_width, u64 address);
+			     u8 byte_width, u64 address);
 
 static void acpi_tb_convert_fadt(void);
 
@@ -111,7 +111,7 @@ static struct acpi_fadt_info fadt_info_table[] = {
  * FUNCTION:    acpi_tb_init_generic_address
  *
  * PARAMETERS:  generic_address     - GAS struct to be initialized
- *              bit_width           - Width of this register
+ *              byte_width          - Width of this register
  *              Address             - Address of the register
  *
  * RETURN:      None
@@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = {
 
 static void inline
 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
-			     u8 bit_width, u64 address)
+			     u8 byte_width, u64 address)
 {
 
 	/*
@@ -136,7 +136,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
 	/* All other fields are byte-wide */
 
 	generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO;
-	generic_address->bit_width = bit_width;
+	generic_address->bit_width = byte_width << 3;
 	generic_address->bit_offset = 0;
 	generic_address->access_width = 0;
 }
@@ -342,9 +342,20 @@ static void acpi_tb_convert_fadt(void)
 	 * useful to calculate them once, here.
 	 *
 	 * The PM event blocks are split into two register blocks, first is the
-	 * PM Status Register block, followed immediately by the PM Enable Register
-	 * block. Each is of length (pm1_event_length/2)
+	 * PM Status Register block, followed immediately by the PM Enable
+	 * Register block. Each is of length (xpm1x_event_block.bit_width/2).
+	 *
+	 * On various systems the v2 fields (and particularly the bit widths)
+	 * cannot be relied upon, though. Hence resort to using the v1 length
+	 * here (and warn about the inconsistency).
 	 */
+	if (acpi_gbl_FADT.xpm1a_event_block.bit_width
+	    != acpi_gbl_FADT.pm1_event_length * 8)
+		printk(KERN_WARNING "FADT: "
+		       "X_PM1a_EVT_BLK.bit_width (%u) does not match"
+		       " PM1_EVT_LEN (%u)\n",
+		       acpi_gbl_FADT.xpm1a_event_block.bit_width,
+		       acpi_gbl_FADT.pm1_event_length);
 	pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length);
 
 	/* The PM1A register block is required */
@@ -360,13 +371,20 @@ static void acpi_tb_convert_fadt(void)
 	/* The PM1B register block is optional, ignore if not present */
 
 	if (acpi_gbl_FADT.xpm1b_event_block.address) {
+		if (acpi_gbl_FADT.xpm1b_event_block.bit_width
+		    != acpi_gbl_FADT.pm1_event_length * 8)
+			printk(KERN_WARNING "FADT: "
+			       "X_PM1b_EVT_BLK.bit_width (%u) does not match"
+			       " PM1_EVT_LEN (%u)\n",
+			       acpi_gbl_FADT.xpm1b_event_block.bit_width,
+			       acpi_gbl_FADT.pm1_event_length);
 		acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
 					     pm1_register_length,
 					     (acpi_gbl_FADT.xpm1b_event_block.
 					      address + pm1_register_length));
 		/* Don't forget to copy space_id of the GAS */
 		acpi_gbl_xpm1b_enable.space_id =
-		    acpi_gbl_FADT.xpm1a_event_block.space_id;
+		    acpi_gbl_FADT.xpm1b_event_block.space_id;
 
 	}
 }
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index b22185f55a16..18747ce8dd2f 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -110,7 +110,6 @@ acpi_status
 acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
 {
 	u32 i;
-	u32 length;
 	acpi_status status = AE_OK;
 
 	ACPI_FUNCTION_TRACE(tb_add_table);
@@ -145,25 +144,64 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
 			}
 		}
 
-		length = ACPI_MIN(table_desc->length,
-				  acpi_gbl_root_table_list.tables[i].length);
+		/*
+		 * Check for a table match on the entire table length,
+		 * not just the header.
+		 */
+		if (table_desc->length !=
+		    acpi_gbl_root_table_list.tables[i].length) {
+			continue;
+		}
+
 		if (ACPI_MEMCMP(table_desc->pointer,
 				acpi_gbl_root_table_list.tables[i].pointer,
-				length)) {
+				acpi_gbl_root_table_list.tables[i].length)) {
 			continue;
 		}
 
-		/* Table is already registered */
-
+		/*
+		 * Note: the current mechanism does not unregister a table if it is
+		 * dynamically unloaded. The related namespace entries are deleted,
+		 * but the table remains in the root table list.
+		 *
+		 * The assumption here is that the number of different tables that
+		 * will be loaded is actually small, and there is minimal overhead
+		 * in just keeping the table in case it is needed again.
+		 *
+		 * If this assumption changes in the future (perhaps on large
+		 * machines with many table load/unload operations), tables will
+		 * need to be unregistered when they are unloaded, and slots in the
+		 * root table list should be reused when empty.
+		 */
+
+		/*
+		 * Table is already registered.
+		 * We can delete the table that was passed as a parameter.
+		 */
 		acpi_tb_delete_table(table_desc);
 		*table_index = i;
-		status = AE_ALREADY_EXISTS;
-		goto release;
+
+		if (acpi_gbl_root_table_list.tables[i].
+		    flags & ACPI_TABLE_IS_LOADED) {
+
+			/* Table is still loaded, this is an error */
+
+			status = AE_ALREADY_EXISTS;
+			goto release;
+		} else {
+			/* Table was unloaded, allow it to be reloaded */
+
+			table_desc->pointer =
+			    acpi_gbl_root_table_list.tables[i].pointer;
+			table_desc->address =
+			    acpi_gbl_root_table_list.tables[i].address;
+			status = AE_OK;
+			goto print_header;
+		}
 	}
 
-	/*
-	 * Add the table to the global table list
-	 */
+	/* Add the table to the global root table list */
+
 	status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
 				     table_desc->length, table_desc->flags,
 				     table_index);
@@ -171,6 +209,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
 		goto release;
 	}
 
+      print_header:
 	acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
 
       release:
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 912703691d36..ad6cae938f0b 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -246,18 +246,18 @@ static const struct file_operations acpi_thermal_polling_fops = {
 static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
 {
 	acpi_status status = AE_OK;
-
+	unsigned long long tmp;
 
 	if (!tz)
 		return -EINVAL;
 
 	tz->last_temperature = tz->temperature;
 
-	status =
-	    acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature);
+	status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
+	tz->temperature = tmp;
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
 			  tz->temperature));
 
@@ -267,17 +267,16 @@ static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
 {
 	acpi_status status = AE_OK;
-
+	unsigned long long tmp;
 
 	if (!tz)
 		return -EINVAL;
 
-	status =
-	    acpi_evaluate_integer(tz->device->handle, "_TZP", NULL,
-				  &tz->polling_frequency);
+	status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
+	tz->polling_frequency = tmp;
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
 			  tz->polling_frequency));
 
@@ -356,6 +355,7 @@ do {	\
 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 {
 	acpi_status status = AE_OK;
+	unsigned long long tmp;
 	struct acpi_handle_list devices;
 	int valid = 0;
 	int i;
@@ -363,7 +363,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 	/* Critical Shutdown (required) */
 	if (flag & ACPI_TRIPS_CRITICAL) {
 		status = acpi_evaluate_integer(tz->device->handle,
-				"_CRT", NULL, &tz->trips.critical.temperature);
+				"_CRT", NULL, &tmp);
+		tz->trips.critical.temperature = tmp;
 		/*
 		 * Treat freezing temperatures as invalid as well; some
 		 * BIOSes return really low values and cause reboots at startup.
@@ -388,10 +389,12 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 			} else if (crt > 0) {
 				unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
 				/*
-				 * Allow override to lower critical threshold
+				 * Allow override critical threshold
 				 */
-				if (crt_k < tz->trips.critical.temperature)
-					tz->trips.critical.temperature = crt_k;
+				if (crt_k > tz->trips.critical.temperature)
+					printk(KERN_WARNING PREFIX
+						"Critical threshold %d C\n", crt);
+				tz->trips.critical.temperature = crt_k;
 			}
 		}
 	}
@@ -399,12 +402,13 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 	/* Critical Sleep (optional) */
 	if (flag & ACPI_TRIPS_HOT) {
 		status = acpi_evaluate_integer(tz->device->handle,
-				"_HOT", NULL, &tz->trips.hot.temperature);
+				"_HOT", NULL, &tmp);
 		if (ACPI_FAILURE(status)) {
 			tz->trips.hot.flags.valid = 0;
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					"No hot threshold\n"));
 		} else {
+			tz->trips.hot.temperature = tmp;
 			tz->trips.hot.flags.valid = 1;
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					"Found hot threshold [%lu]\n",
@@ -418,33 +422,40 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 		if (psv == -1) {
 			status = AE_SUPPORT;
 		} else if (psv > 0) {
-			tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv);
+			tmp = CELSIUS_TO_KELVIN(psv);
 			status = AE_OK;
 		} else {
 			status = acpi_evaluate_integer(tz->device->handle,
-				"_PSV", NULL, &tz->trips.passive.temperature);
+				"_PSV", NULL, &tmp);
 		}
 
 		if (ACPI_FAILURE(status))
 			tz->trips.passive.flags.valid = 0;
 		else {
+			tz->trips.passive.temperature = tmp;
 			tz->trips.passive.flags.valid = 1;
 			if (flag == ACPI_TRIPS_INIT) {
 				status = acpi_evaluate_integer(
 						tz->device->handle, "_TC1",
-						NULL, &tz->trips.passive.tc1);
+						NULL, &tmp);
 				if (ACPI_FAILURE(status))
 					tz->trips.passive.flags.valid = 0;
+				else
+					tz->trips.passive.tc1 = tmp;
 				status = acpi_evaluate_integer(
 						tz->device->handle, "_TC2",
-						NULL, &tz->trips.passive.tc2);
+						NULL, &tmp);
 				if (ACPI_FAILURE(status))
 					tz->trips.passive.flags.valid = 0;
+				else
+					tz->trips.passive.tc2 = tmp;
 				status = acpi_evaluate_integer(
 						tz->device->handle, "_TSP",
-						NULL, &tz->trips.passive.tsp);
+						NULL, &tmp);
 				if (ACPI_FAILURE(status))
 					tz->trips.passive.flags.valid = 0;
+				else
+					tz->trips.passive.tsp = tmp;
 			}
 		}
 	}
@@ -479,7 +490,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 
 		if (flag & ACPI_TRIPS_ACTIVE) {
 			status = acpi_evaluate_integer(tz->device->handle,
-				name, NULL, &tz->trips.active[i].temperature);
+							name, NULL, &tmp);
 			if (ACPI_FAILURE(status)) {
 				tz->trips.active[i].flags.valid = 0;
 				if (i == 0)
@@ -500,8 +511,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
 						tz->trips.active[i - 2].temperature :
 						CELSIUS_TO_KELVIN(act));
 				break;
-			} else
+			} else {
+				tz->trips.active[i].temperature = tmp;
 				tz->trips.active[i].flags.valid = 1;
+			}
 		}
 
 		name[2] = 'L';
@@ -1213,8 +1226,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 				  acpi_bus_private_data_handler,
 				  tz->thermal_zone);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				"Error attaching device data\n"));
+		printk(KERN_ERR PREFIX
+				"Error attaching device data\n");
 		return -ENODEV;
 	}
 
@@ -1647,7 +1660,7 @@ static int acpi_thermal_add(struct acpi_device *device)
 	strcpy(tz->name, device->pnp.bus_id);
 	strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
-	acpi_driver_data(device) = tz;
+	device->driver_data = tz;
 	mutex_init(&tz->lock);
 
 
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 8a649f40d162..2a632f8b7a05 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -548,7 +548,7 @@ static unsigned long write_video(const char *buffer, unsigned long count)
 
 	hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
 	if (hci_result == HCI_SUCCESS) {
-		int new_video_out = video_out;
+		unsigned int new_video_out = video_out;
 		if (lcd_out != -1)
 			_set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out);
 		if (crt_out != -1)
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 7dcb67e0b215..241c535c1753 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -232,7 +232,7 @@ acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer)
  * RETURN:      Status
  *
  * DESCRIPTION: Validate that the buffer is of the required length or
- *              allocate a new buffer.  Returned buffer is always zeroed.
+ *              allocate a new buffer. Returned buffer is always zeroed.
  *
  ******************************************************************************/
 
@@ -240,7 +240,7 @@ acpi_status
 acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
 			  acpi_size required_length)
 {
-	acpi_status status = AE_OK;
+	acpi_size input_buffer_length;
 
 	/* Parameter validation */
 
@@ -248,55 +248,58 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
 		return (AE_BAD_PARAMETER);
 	}
 
-	switch (buffer->length) {
+	/*
+	 * Buffer->Length is used as both an input and output parameter. Get the
+	 * input actual length and set the output required buffer length.
+	 */
+	input_buffer_length = buffer->length;
+	buffer->length = required_length;
+
+	/*
+	 * The input buffer length contains the actual buffer length, or the type
+	 * of buffer to be allocated by this routine.
+	 */
+	switch (input_buffer_length) {
 	case ACPI_NO_BUFFER:
 
-		/* Set the exception and returned the required length */
+		/* Return the exception (and the required buffer length) */
 
-		status = AE_BUFFER_OVERFLOW;
-		break;
+		return (AE_BUFFER_OVERFLOW);
 
 	case ACPI_ALLOCATE_BUFFER:
 
 		/* Allocate a new buffer */
 
 		buffer->pointer = acpi_os_allocate(required_length);
-		if (!buffer->pointer) {
-			return (AE_NO_MEMORY);
-		}
-
-		/* Clear the buffer */
-
-		ACPI_MEMSET(buffer->pointer, 0, required_length);
 		break;
 
 	case ACPI_ALLOCATE_LOCAL_BUFFER:
 
 		/* Allocate a new buffer with local interface to allow tracking */
 
-		buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length);
-		if (!buffer->pointer) {
-			return (AE_NO_MEMORY);
-		}
+		buffer->pointer = ACPI_ALLOCATE(required_length);
 		break;
 
 	default:
 
 		/* Existing buffer: Validate the size of the buffer */
 
-		if (buffer->length < required_length) {
-			status = AE_BUFFER_OVERFLOW;
-			break;
+		if (input_buffer_length < required_length) {
+			return (AE_BUFFER_OVERFLOW);
 		}
+		break;
+	}
 
-		/* Clear the buffer */
+	/* Validate allocation from above or input buffer pointer */
 
-		ACPI_MEMSET(buffer->pointer, 0, required_length);
-		break;
+	if (!buffer->pointer) {
+		return (AE_NO_MEMORY);
 	}
 
-	buffer->length = required_length;
-	return (status);
+	/* Have a valid buffer, clear it */
+
+	ACPI_MEMSET(buffer->pointer, 0, required_length);
+	return (AE_OK);
 }
 
 #ifdef NOT_USED_BY_LINUX
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 53499ac90988..5b2f7c27b705 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -42,7 +42,6 @@
  */
 
 #include <acpi/acpi.h>
-#include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
 
 
@@ -176,20 +175,24 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
 
 		/* This is an object reference. */
 
-		switch (internal_object->reference.opcode) {
-		case AML_INT_NAMEPATH_OP:
-
-			/* For namepath, return the object handle ("reference") */
-
-		default:
-
-			/* We are referring to the namespace node */
+		switch (internal_object->reference.class) {
+		case ACPI_REFCLASS_NAME:
 
+			/*
+			 * For namepath, return the object handle ("reference")
+			 * We are referring to the namespace node
+			 */
 			external_object->reference.handle =
 			    internal_object->reference.node;
 			external_object->reference.actual_type =
 			    acpi_ns_get_type(internal_object->reference.node);
 			break;
+
+		default:
+
+			/* All other reference types are unsupported */
+
+			return_ACPI_STATUS(AE_TYPE);
 		}
 		break;
 
@@ -533,7 +536,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
 
 		/* TBD: should validate incoming handle */
 
-		internal_object->reference.opcode = AML_INT_NAMEPATH_OP;
+		internal_object->reference.class = ACPI_REFCLASS_NAME;
 		internal_object->reference.node =
 		    external_object->reference.handle;
 		break;
@@ -743,11 +746,11 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
 		 * We copied the reference object, so we now must add a reference
 		 * to the object pointed to by the reference
 		 *
-		 * DDBHandle reference (from Load/load_table is a special reference,
-		 * it's Reference.Object is the table index, so does not need to
+		 * DDBHandle reference (from Load/load_table) is a special reference,
+		 * it does not have a Reference.Object, so does not need to
 		 * increase the reference count
 		 */
-		if (source_desc->reference.opcode == AML_LOAD_OP) {
+		if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 			break;
 		}
 
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 42609d3a8aa9..d197c6b29e17 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -45,7 +45,6 @@
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
-#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utdelete")
@@ -548,8 +547,8 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
 			 * reference must track changes to the ref count of the index or
 			 * target object.
 			 */
-			if ((object->reference.opcode == AML_INDEX_OP) ||
-			    (object->reference.opcode == AML_INT_NAMEPATH_OP)) {
+			if ((object->reference.class == ACPI_REFCLASS_INDEX) ||
+			    (object->reference.class == ACPI_REFCLASS_NAME)) {
 				next_object = object->reference.object;
 			}
 			break;
@@ -586,6 +585,13 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
 	ACPI_EXCEPTION((AE_INFO, status,
 			"Could not update object reference count"));
 
+	/* Free any stacked Update State objects */
+
+	while (state_list) {
+		state = acpi_ut_pop_generic_state(&state_list);
+		acpi_ut_delete_generic_state(state);
+	}
+
 	return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index a6e71b801d2d..670551b95e56 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -281,7 +281,6 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = {
 	/* ACPI_BITREG_RT_CLOCK_ENABLE      */ {ACPI_REGISTER_PM1_ENABLE,
 						ACPI_BITPOSITION_RT_CLOCK_ENABLE,
 						ACPI_BITMASK_RT_CLOCK_ENABLE},
-	/* ACPI_BITREG_WAKE_ENABLE          */ {ACPI_REGISTER_PM1_ENABLE, 0, 0},
 	/* ACPI_BITREG_PCIEXP_WAKE_DISABLE  */ {ACPI_REGISTER_PM1_ENABLE,
 						ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE,
 						ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
@@ -575,6 +574,47 @@ char *acpi_ut_get_descriptor_name(void *object)
 
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_reference_name
+ *
+ * PARAMETERS:  Object               - An ACPI reference object
+ *
+ * RETURN:      Pointer to a string
+ *
+ * DESCRIPTION: Decode a reference object sub-type to a string.
+ *
+ ******************************************************************************/
+
+/* Printable names of reference object sub-types */
+
+static const char *acpi_gbl_ref_class_names[] = {
+	/* 00 */ "Local",
+	/* 01 */ "Argument",
+	/* 02 */ "RefOf",
+	/* 03 */ "Index",
+	/* 04 */ "DdbHandle",
+	/* 05 */ "Named Object",
+	/* 06 */ "Debug"
+};
+
+const char *acpi_ut_get_reference_name(union acpi_operand_object *object)
+{
+	if (!object)
+		return "NULL Object";
+
+	if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND)
+		return "Not an Operand object";
+
+	if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE)
+		return "Not a Reference object";
+
+	if (object->reference.class > ACPI_REFCLASS_MAX)
+		return "Unknown Reference class";
+
+	return acpi_gbl_ref_class_names[object->reference.class];
+}
+
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 /*
  * Strings and procedures used for debug only
@@ -677,14 +717,14 @@ u8 acpi_ut_valid_object_type(acpi_object_type type)
  *
  * PARAMETERS:  None
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Init library globals.  All globals that require specific
  *              initialization should be initialized here!
  *
  ******************************************************************************/
 
-void acpi_ut_init_globals(void)
+acpi_status acpi_ut_init_globals(void)
 {
 	acpi_status status;
 	u32 i;
@@ -695,7 +735,7 @@ void acpi_ut_init_globals(void)
 
 	status = acpi_ut_create_caches();
 	if (ACPI_FAILURE(status)) {
-		return;
+		return_ACPI_STATUS(status);
 	}
 
 	/* Mutex locked flags */
@@ -772,8 +812,8 @@ void acpi_ut_init_globals(void)
 	acpi_gbl_display_final_mem_stats = FALSE;
 #endif
 
-	return_VOID;
+	return_ACPI_STATUS(AE_OK);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_dbg_level)
-    ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
+ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index f34be6773556..9089a158a874 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -995,6 +995,15 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
 							 state->pkg.
 							 this_target_obj, 0);
 			if (!state) {
+
+				/* Free any stacked Update State objects */
+
+				while (state_list) {
+					state =
+					    acpi_ut_pop_generic_state
+					    (&state_list);
+					acpi_ut_delete_generic_state(state);
+				}
 				return_ACPI_STATUS(AE_NO_MEMORY);
 			}
 		}
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index 916eff399eb3..c354e7a42bcd 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -43,7 +43,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
-#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utobject")
@@ -478,8 +477,8 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
 
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
-		switch (internal_object->reference.opcode) {
-		case AML_INT_NAMEPATH_OP:
+		switch (internal_object->reference.class) {
+		case ACPI_REFCLASS_NAME:
 
 			/*
 			 * Get the actual length of the full pathname to this object.
@@ -503,8 +502,10 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
 			 * required eventually.
 			 */
 			ACPI_ERROR((AE_INFO,
-				    "Unsupported Reference opcode=%X in object %p",
-				    internal_object->reference.opcode,
+				    "Cannot convert to external object - "
+				    "unsupported Reference Class [%s] %X in object %p",
+				    acpi_ut_get_reference_name(internal_object),
+				    internal_object->reference.class,
 				    internal_object));
 			status = AE_TYPE;
 			break;
@@ -513,7 +514,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
 
 	default:
 
-		ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p",
+		ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
+			    "unsupported type [%s] %X in object %p",
+			    acpi_ut_get_object_type_name(internal_object),
 			    ACPI_GET_OBJECT_TYPE(internal_object),
 			    internal_object));
 		status = AE_TYPE;
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index f8bdadf3c32f..c198a4d40583 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -81,7 +81,12 @@ acpi_status __init acpi_initialize_subsystem(void)
 
 	/* Initialize all globals used by the subsystem */
 
-	acpi_ut_init_globals();
+	status = acpi_ut_init_globals();
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status,
+				"During initialization of globals"));
+		return_ACPI_STATUS(status);
+	}
 
 	/* Create the default mutex objects */
 
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 100926143818..e827be36ee8d 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -256,7 +256,7 @@ EXPORT_SYMBOL(acpi_extract_package);
 acpi_status
 acpi_evaluate_integer(acpi_handle handle,
 		      acpi_string pathname,
-		      struct acpi_object_list *arguments, unsigned long *data)
+		      struct acpi_object_list *arguments, unsigned long long *data)
 {
 	acpi_status status = AE_OK;
 	union acpi_object *element;
@@ -288,7 +288,7 @@ acpi_evaluate_integer(acpi_handle handle,
 	*data = element->integer.value;
 	kfree(element);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data));
 
 	return AE_OK;
 }
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index e8a51a1700f7..a29b0ccac65a 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -291,20 +291,20 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
 			int level);
 static int acpi_video_device_lcd_get_level_current(
 			struct acpi_video_device *device,
-			unsigned long *level);
+			unsigned long long *level);
 static int acpi_video_get_next_level(struct acpi_video_device *device,
 				     u32 level_current, u32 event);
 static void acpi_video_switch_brightness(struct acpi_video_device *device,
 					 int event);
 static int acpi_video_device_get_state(struct acpi_video_device *device,
-			    unsigned long *state);
+			    unsigned long long *state);
 static int acpi_video_output_get(struct output_device *od);
 static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
 
 /*backlight device sysfs support*/
 static int acpi_video_get_brightness(struct backlight_device *bd)
 {
-	unsigned long cur_level;
+	unsigned long long cur_level;
 	int i;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
@@ -336,7 +336,7 @@ static struct backlight_ops acpi_backlight_ops = {
 /*video output device sysfs support*/
 static int acpi_video_output_get(struct output_device *od)
 {
-	unsigned long state;
+	unsigned long long state;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)dev_get_drvdata(&od->dev);
 	acpi_video_device_get_state(vd, &state);
@@ -370,7 +370,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
-	unsigned long level;
+	unsigned long long level;
 	int state;
 
 	acpi_video_device_lcd_get_level_current(video, &level);
@@ -410,7 +410,7 @@ static struct thermal_cooling_device_ops video_cooling_ops = {
 /* device */
 
 static int
-acpi_video_device_query(struct acpi_video_device *device, unsigned long *state)
+acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state)
 {
 	int status;
 
@@ -421,7 +421,7 @@ acpi_video_device_query(struct acpi_video_device *device, unsigned long *state)
 
 static int
 acpi_video_device_get_state(struct acpi_video_device *device,
-			    unsigned long *state)
+			    unsigned long long *state)
 {
 	int status;
 
@@ -436,7 +436,7 @@ acpi_video_device_set_state(struct acpi_video_device *device, int state)
 	int status;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
-	unsigned long ret;
+	unsigned long long ret;
 
 
 	arg0.integer.value = state;
@@ -495,7 +495,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 
 static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
-					unsigned long *level)
+					unsigned long long *level)
 {
 	if (device->cap._BQC)
 		return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
@@ -549,7 +549,7 @@ static int
 acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
 {
 	int status;
-	unsigned long tmp;
+	unsigned long long tmp;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 
@@ -564,7 +564,7 @@ acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
 }
 
 static int
-acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id)
+acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
 {
 	int status;
 
@@ -575,7 +575,7 @@ acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id)
 
 static int
 acpi_video_bus_POST_options(struct acpi_video_bus *video,
-			    unsigned long *options)
+			    unsigned long long *options)
 {
 	int status;
 
@@ -918,7 +918,7 @@ static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
 {
 	int status;
 	struct acpi_video_device *dev = seq->private;
-	unsigned long state;
+	unsigned long long state;
 
 
 	if (!dev)
@@ -927,14 +927,14 @@ static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
 	status = acpi_video_device_get_state(dev, &state);
 	seq_printf(seq, "state:     ");
 	if (ACPI_SUCCESS(status))
-		seq_printf(seq, "0x%02lx\n", state);
+		seq_printf(seq, "0x%02llx\n", state);
 	else
 		seq_printf(seq, "<not supported>\n");
 
 	status = acpi_video_device_query(dev, &state);
 	seq_printf(seq, "query:     ");
 	if (ACPI_SUCCESS(status))
-		seq_printf(seq, "0x%02lx\n", state);
+		seq_printf(seq, "0x%02llx\n", state);
 	else
 		seq_printf(seq, "<not supported>\n");
 
@@ -1217,7 +1217,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_video_bus *video = seq->private;
-	unsigned long options;
+	unsigned long long options;
 	int status;
 
 
@@ -1232,7 +1232,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
 			printk(KERN_WARNING PREFIX
 			       "This indicates a BIOS bug. Please contact the manufacturer.\n");
 		}
-		printk("%lx\n", options);
+		printk("%llx\n", options);
 		seq_printf(seq, "can POST: <integrated video>");
 		if (options & 2)
 			seq_printf(seq, " <PCI video>");
@@ -1256,7 +1256,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_video_bus *video = seq->private;
 	int status;
-	unsigned long id;
+	unsigned long long id;
 
 
 	if (!video)
@@ -1303,7 +1303,7 @@ acpi_video_bus_write_POST(struct file *file,
 	struct seq_file *m = file->private_data;
 	struct acpi_video_bus *video = m->private;
 	char str[12] = { 0 };
-	unsigned long opt, options;
+	unsigned long long opt, options;
 
 
 	if (!video || count + 1 > sizeof str)
@@ -1473,7 +1473,7 @@ static int
 acpi_video_bus_get_one_device(struct acpi_device *device,
 			      struct acpi_video_bus *video)
 {
-	unsigned long device_id;
+	unsigned long long device_id;
 	int status;
 	struct acpi_video_device *data;
 	struct acpi_video_device_attrib* attribute;
@@ -1491,7 +1491,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
 
 		strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
 		strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
-		acpi_driver_data(device) = data;
+		device->driver_data = data;
 
 		data->device_id = device_id;
 		data->video = video;
@@ -1530,8 +1530,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
 						     acpi_video_device_notify,
 						     data);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Error installing notify handler\n"));
+			printk(KERN_ERR PREFIX
+					  "Error installing notify handler\n");
 			if(data->brightness)
 				kfree(data->brightness->levels);
 			kfree(data->brightness);
@@ -1724,7 +1724,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
 static void
 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
 {
-	unsigned long level_current, level_next;
+	unsigned long long level_current, level_next;
 	if (!device->brightness)
 		return;
 	acpi_video_device_lcd_get_level_current(device, &level_current);
@@ -1745,8 +1745,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
 
 		status = acpi_video_bus_get_one_device(dev, video);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-					"Cant attach device"));
+			printk(KERN_WARNING PREFIX
+					"Cant attach device");
 			continue;
 		}
 	}
@@ -1982,7 +1982,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
 	video->device = device;
 	strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
 	strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
-	acpi_driver_data(device) = video;
+	device->driver_data = video;
 
 	acpi_video_bus_find_cap(video);
 	error = acpi_video_bus_check(video);
@@ -2003,8 +2003,8 @@ static int acpi_video_bus_add(struct acpi_device *device)
 					     ACPI_DEVICE_NOTIFY,
 					     acpi_video_bus_notify, video);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Error installing notify handler\n"));
+		printk(KERN_ERR PREFIX
+				  "Error installing notify handler\n");
 		error = -ENODEV;
 		goto err_stop_video;
 	}
@@ -2058,7 +2058,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
 	acpi_video_bus_remove_fs(device);
  err_free_video:
 	kfree(video);
-	acpi_driver_data(device) = NULL;
+	device->driver_data = NULL;
 
 	return error;
 }
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c
index cfe2c833474d..47cd7baf9b1b 100644
--- a/drivers/acpi/wmi.c
+++ b/drivers/acpi/wmi.c
@@ -217,6 +217,35 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
 	return 0;
 }
 
+static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)
+{
+	struct guid_block *block = NULL;
+	char method[5];
+	struct acpi_object_list input;
+	union acpi_object params[1];
+	acpi_status status;
+	acpi_handle handle;
+
+	block = &wblock->gblock;
+	handle = wblock->handle;
+
+	if (!block)
+		return AE_NOT_EXIST;
+
+	input.count = 1;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_INTEGER;
+	params[0].integer.value = enable;
+
+	snprintf(method, 5, "WE%02X", block->notify_id);
+	status = acpi_evaluate_object(handle, method, &input, NULL);
+
+	if (status != AE_OK && status != AE_NOT_FOUND)
+		return status;
+	else
+		return AE_OK;
+}
+
 /*
  * Exported WMI functions
  */
@@ -242,7 +271,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
 	char method[4] = "WM";
 
 	if (!find_guid(guid_string, &wblock))
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 
 	block = &wblock->gblock;
 	handle = wblock->handle;
@@ -304,7 +333,7 @@ struct acpi_buffer *out)
 		return AE_BAD_PARAMETER;
 
 	if (!find_guid(guid_string, &wblock))
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 
 	block = &wblock->gblock;
 	handle = wblock->handle;
@@ -314,7 +343,7 @@ struct acpi_buffer *out)
 
 	/* Check GUID is a data block */
 	if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 
 	input.count = 1;
 	input.pointer = wq_params;
@@ -385,7 +414,7 @@ const struct acpi_buffer *in)
 		return AE_BAD_DATA;
 
 	if (!find_guid(guid_string, &wblock))
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 
 	block = &wblock->gblock;
 	handle = wblock->handle;
@@ -395,7 +424,7 @@ const struct acpi_buffer *in)
 
 	/* Check GUID is a data block */
 	if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 
 	input.count = 2;
 	input.pointer = params;
@@ -427,6 +456,7 @@ acpi_status wmi_install_notify_handler(const char *guid,
 wmi_notify_handler handler, void *data)
 {
 	struct wmi_block *block;
+	acpi_status status;
 
 	if (!guid || !handler)
 		return AE_BAD_PARAMETER;
@@ -441,7 +471,9 @@ wmi_notify_handler handler, void *data)
 	block->handler = handler;
 	block->handler_data = data;
 
-	return AE_OK;
+	status = wmi_method_enable(block, 1);
+
+	return status;
 }
 EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
 
@@ -453,6 +485,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
 acpi_status wmi_remove_notify_handler(const char *guid)
 {
 	struct wmi_block *block;
+	acpi_status status;
 
 	if (!guid)
 		return AE_BAD_PARAMETER;
@@ -464,10 +497,12 @@ acpi_status wmi_remove_notify_handler(const char *guid)
 	if (!block->handler)
 		return AE_NULL_ENTRY;
 
+	status = wmi_method_enable(block, 0);
+
 	block->handler = NULL;
 	block->handler_data = NULL;
 
-	return AE_OK;
+	return status;
 }
 EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
 
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 9330b7922f62..c012307d0ba6 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -120,21 +120,6 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
 		ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
 }
 
-static void ata_acpi_eject_device(acpi_handle handle)
-{
-	struct acpi_object_list arg_list;
-	union acpi_object arg;
-
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = 1;
-
-	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
-					      &arg_list, NULL)))
-		printk(KERN_ERR "Failed to evaluate _EJ0!\n");
-}
-
 /* @ap and @dev are the same as ata_acpi_handle_hotplug() */
 static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
 {
@@ -157,7 +142,6 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
  * @ap: ATA port ACPI event occurred
  * @dev: ATA device ACPI event occurred (can be NULL)
  * @event: ACPI event which occurred
- * @is_dock_event: boolean indicating whether the event was a dock one
  *
  * All ACPI bay / device realted events end up in this function.  If
  * the event is port-wide @dev is NULL.  If the event is specific to a
@@ -171,117 +155,100 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
  * ACPI notify handler context.  May sleep.
  */
 static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
-				    u32 event, int is_dock_event)
+				    u32 event)
 {
-	char event_string[12];
-	char *envp[] = { event_string, NULL };
 	struct ata_eh_info *ehi = &ap->link.eh_info;
-	struct kobject *kobj = NULL;
 	int wait = 0;
 	unsigned long flags;
-	acpi_handle handle, tmphandle;
-	unsigned long sta;
-	acpi_status status;
+	acpi_handle handle;
 
-	if (dev) {
-		if (dev->sdev)
-			kobj = &dev->sdev->sdev_gendev.kobj;
+	if (dev)
 		handle = dev->acpi_handle;
-	} else {
-		kobj = &ap->dev->kobj;
+	else
 		handle = ap->acpi_handle;
-	}
-
-	status = acpi_get_handle(handle, "_EJ0", &tmphandle);
-	if (ACPI_FAILURE(status))
-		/* This device does not support hotplug */
-		return;
-
-	if (event == ACPI_NOTIFY_BUS_CHECK ||
-	    event == ACPI_NOTIFY_DEVICE_CHECK)
-		status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
 
 	spin_lock_irqsave(ap->lock, flags);
-
+	/*
+	 * When dock driver calls into the routine, it will always use
+	 * ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
+	 * ACPI_NOTIFY_EJECT_REQUEST for remove
+	 */
 	switch (event) {
 	case ACPI_NOTIFY_BUS_CHECK:
 	case ACPI_NOTIFY_DEVICE_CHECK:
 		ata_ehi_push_desc(ehi, "ACPI event");
 
-		if (ACPI_FAILURE(status)) {
-			ata_port_printk(ap, KERN_ERR,
-				"acpi: failed to determine bay status (0x%x)\n",
-				status);
-			break;
-		}
-
-		if (sta) {
-			ata_ehi_hotplugged(ehi);
-			ata_port_freeze(ap);
-		} else {
-			/* The device has gone - unplug it */
-			ata_acpi_detach_device(ap, dev);
-			wait = 1;
-		}
+		ata_ehi_hotplugged(ehi);
+		ata_port_freeze(ap);
 		break;
 	case ACPI_NOTIFY_EJECT_REQUEST:
 		ata_ehi_push_desc(ehi, "ACPI event");
 
-		if (!is_dock_event)
-			break;
-
-		/* undock event - immediate unplug */
 		ata_acpi_detach_device(ap, dev);
 		wait = 1;
 		break;
 	}
 
-	/* make sure kobj doesn't go away while ap->lock is released */
-	kobject_get(kobj);
-
 	spin_unlock_irqrestore(ap->lock, flags);
 
-	if (wait) {
+	if (wait)
 		ata_port_wait_eh(ap);
-		ata_acpi_eject_device(handle);
-	}
-
-	if (kobj && !is_dock_event) {
-		sprintf(event_string, "BAY_EVENT=%d", event);
-		kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
-	}
-
-	kobject_put(kobj);
 }
 
 static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
 {
 	struct ata_device *dev = data;
 
-	ata_acpi_handle_hotplug(dev->link->ap, dev, event, 1);
+	ata_acpi_handle_hotplug(dev->link->ap, dev, event);
 }
 
 static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
 {
 	struct ata_port *ap = data;
 
-	ata_acpi_handle_hotplug(ap, NULL, event, 1);
+	ata_acpi_handle_hotplug(ap, NULL, event);
 }
 
-static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
+static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
+	u32 event)
 {
-	struct ata_device *dev = data;
+	struct kobject *kobj = NULL;
+	char event_string[20];
+	char *envp[] = { event_string, NULL };
+
+	if (dev) {
+		if (dev->sdev)
+			kobj = &dev->sdev->sdev_gendev.kobj;
+	} else
+		kobj = &ap->dev->kobj;
 
-	ata_acpi_handle_hotplug(dev->link->ap, dev, event, 0);
+	if (kobj) {
+		snprintf(event_string, 20, "BAY_EVENT=%d", event);
+		kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
+	}
 }
 
-static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
+static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data)
 {
-	struct ata_port *ap = data;
+	ata_acpi_uevent(data, NULL, event);
+}
 
-	ata_acpi_handle_hotplug(ap, NULL, event, 0);
+static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
+{
+	struct ata_device *dev = data;
+	ata_acpi_uevent(dev->link->ap, dev, event);
 }
 
+static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
+	.handler = ata_acpi_dev_notify_dock,
+	.uevent = ata_acpi_dev_uevent,
+};
+
+static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
+	.handler = ata_acpi_ap_notify_dock,
+	.uevent = ata_acpi_ap_uevent,
+};
+
 /**
  * ata_acpi_associate - associate ATA host with ACPI objects
  * @host: target ATA host
@@ -315,24 +282,18 @@ void ata_acpi_associate(struct ata_host *host)
 			ata_acpi_associate_ide_port(ap);
 
 		if (ap->acpi_handle) {
-			acpi_install_notify_handler(ap->acpi_handle,
-						    ACPI_SYSTEM_NOTIFY,
-						    ata_acpi_ap_notify, ap);
 			/* we might be on a docking station */
 			register_hotplug_dock_device(ap->acpi_handle,
-					     ata_acpi_ap_notify_dock, ap);
+					     &ata_acpi_ap_dock_ops, ap);
 		}
 
 		for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
 			struct ata_device *dev = &ap->link.device[j];
 
 			if (dev->acpi_handle) {
-				acpi_install_notify_handler(dev->acpi_handle,
-						ACPI_SYSTEM_NOTIFY,
-						ata_acpi_dev_notify, dev);
 				/* we might be on a docking station */
 				register_hotplug_dock_device(dev->acpi_handle,
-					     ata_acpi_dev_notify_dock, dev);
+					     &ata_acpi_dev_dock_ops, dev);
 			}
 		}
 	}
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 5ce07b517c58..bb6e3b338043 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -56,7 +56,11 @@ static void cpuidle_idle_call(void)
 		if (pm_idle_old)
 			pm_idle_old();
 		else
+#if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE)
+			default_idle();
+#else
 			local_irq_enable();
+#endif
 		return;
 	}
 
@@ -67,8 +71,11 @@ static void cpuidle_idle_call(void)
 	target_state = &dev->states[next_state];
 
 	/* enter the state and update stats */
-	dev->last_residency = target_state->enter(dev, target_state);
 	dev->last_state = target_state;
+	dev->last_residency = target_state->enter(dev, target_state);
+	if (dev->last_state)
+		target_state = dev->last_state;
+
 	target_state->time += (unsigned long long)dev->last_residency;
 	target_state->usage++;
 
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 1ef68b315657..43b8cefad2c6 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -171,6 +171,9 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
 	xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
 	xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 
+#if CONFIG_I7300_IDLE_IOAT_CHANNEL
+	device->common.chancnt--;
+#endif
 	for (i = 0; i < device->common.chancnt; i++) {
 		ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
 		if (!ioat_chan) {
diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig
new file mode 100644
index 000000000000..f5b26dd579e4
--- /dev/null
+++ b/drivers/idle/Kconfig
@@ -0,0 +1,16 @@
+
+menu "Memory power savings"
+
+config I7300_IDLE_IOAT_CHANNEL
+	bool
+
+config I7300_IDLE
+	tristate "Intel chipset idle power saving driver"
+	select I7300_IDLE_IOAT_CHANNEL
+	depends on X86_64
+	help
+	  Enable idle power savings with certain Intel server chipsets.
+	  The chipset must have I/O AT support, such as the Intel 7300.
+	  The power savings depends on the type and quantity of DRAM devices.
+
+endmenu
diff --git a/drivers/idle/Makefile b/drivers/idle/Makefile
new file mode 100644
index 000000000000..5f68fc377e21
--- /dev/null
+++ b/drivers/idle/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_I7300_IDLE)			+= i7300_idle.o
+
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
new file mode 100644
index 000000000000..59d1bbc3cd3c
--- /dev/null
+++ b/drivers/idle/i7300_idle.c
@@ -0,0 +1,674 @@
+/*
+ * (C) Copyright 2008 Intel Corporation
+ * Authors:
+ * Andy Henroid <andrew.d.henroid@intel.com>
+ * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ */
+
+/*
+ * Save DIMM power on Intel 7300-based platforms when all CPUs/cores
+ * are idle, using the DIMM thermal throttling capability.
+ *
+ * This driver depends on the Intel integrated DMA controller (I/O AT).
+ * If the driver for I/O AT (drivers/dma/ioatdma*) is also enabled,
+ * this driver should work cooperatively.
+ */
+
+/* #define DEBUG */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/cpumask.h>
+#include <linux/ktime.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/stop_machine.h>
+
+#include <asm/idle.h>
+
+#include "../dma/ioatdma_hw.h"
+#include "../dma/ioatdma_registers.h"
+
+#define I7300_IDLE_DRIVER_VERSION	"1.55"
+#define I7300_PRINT			"i7300_idle:"
+
+static int debug;
+module_param_named(debug, debug, uint, 0644);
+MODULE_PARM_DESC(debug, "Enable debug printks in this driver");
+
+#define dprintk(fmt, arg...) \
+	do { if (debug) printk(KERN_INFO I7300_PRINT fmt, ##arg); } while (0)
+
+/*
+ * Value to set THRTLOW to when initiating throttling
+ *  0 = No throttling
+ *  1 = Throttle when > 4 activations per eval window (Maximum throttling)
+ *  2 = Throttle when > 8 activations
+ *  168 = Throttle when > 168 activations (Minimum throttling)
+ */
+#define MAX_THRTLWLIMIT		168
+static uint i7300_idle_thrtlowlm = 1;
+module_param_named(thrtlwlimit, i7300_idle_thrtlowlm, uint, 0644);
+MODULE_PARM_DESC(thrtlwlimit,
+		"Value for THRTLOWLM activation field "
+		"(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)");
+
+/*
+ * simple invocation and duration statistics
+ */
+static unsigned long total_starts;
+static unsigned long total_us;
+
+#ifdef DEBUG
+static unsigned long past_skip;
+#endif
+
+static struct pci_dev *fbd_dev;
+
+static spinlock_t i7300_idle_lock;
+static int i7300_idle_active;
+
+static u8 i7300_idle_thrtctl_saved;
+static u8 i7300_idle_thrtlow_saved;
+static u32 i7300_idle_mc_saved;
+
+static cpumask_t idle_cpumask;
+static ktime_t start_ktime;
+static unsigned long avg_idle_us;
+
+static struct dentry *debugfs_dir;
+
+/* Begin: I/O AT Helper routines */
+
+#define IOAT_CHANBASE(ioat_ctl, chan) (ioat_ctl + 0x80 + 0x80 * chan)
+/* Snoop control (disable snoops when coherency is not important) */
+#define IOAT_DESC_SADDR_SNP_CTL (1UL << 1)
+#define IOAT_DESC_DADDR_SNP_CTL (1UL << 2)
+
+static struct pci_dev *ioat_dev;
+static struct ioat_dma_descriptor *ioat_desc; /* I/O AT desc & data (1 page) */
+static unsigned long ioat_desc_phys;
+static u8 *ioat_iomap; /* I/O AT memory-mapped control regs (aka CB_BAR) */
+static u8 *ioat_chanbase;
+
+/* Start I/O AT memory copy */
+static int i7300_idle_ioat_start(void)
+{
+	u32 err;
+	/* Clear error (due to circular descriptor pointer) */
+	err = readl(ioat_chanbase + IOAT_CHANERR_OFFSET);
+	if (err)
+		writel(err, ioat_chanbase + IOAT_CHANERR_OFFSET);
+
+	writeb(IOAT_CHANCMD_START, ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+	return 0;
+}
+
+/* Stop I/O AT memory copy */
+static void i7300_idle_ioat_stop(void)
+{
+	int i;
+	u8 sts;
+
+	for (i = 0; i < 5; i++) {
+		writeb(IOAT_CHANCMD_RESET,
+			ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+
+		udelay(10);
+
+		sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+			IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+		if (sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE)
+			break;
+
+	}
+
+	if (i == 5)
+		dprintk("failed to suspend+reset I/O AT after 5 retries\n");
+
+}
+
+/* Test I/O AT by copying 1024 byte from 2k to 1k */
+static int __init i7300_idle_ioat_selftest(u8 *ctl,
+		struct ioat_dma_descriptor *desc, unsigned long desc_phys)
+{
+	u64 chan_sts;
+
+	memset(desc, 0, 2048);
+	memset((u8 *) desc + 2048, 0xab, 1024);
+
+	desc[0].size = 1024;
+	desc[0].ctl = 0;
+	desc[0].src_addr = desc_phys + 2048;
+	desc[0].dst_addr = desc_phys + 1024;
+	desc[0].next = 0;
+
+	writeb(IOAT_CHANCMD_RESET, ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+	writeb(IOAT_CHANCMD_START, ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+
+	udelay(1000);
+
+	chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+			IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+	if (chan_sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_DONE) {
+		/* Not complete, reset the channel */
+		writeb(IOAT_CHANCMD_RESET,
+		       ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+		return -1;
+	}
+
+	if (*(u32 *) ((u8 *) desc + 3068) != 0xabababab ||
+	    *(u32 *) ((u8 *) desc + 2044) != 0xabababab) {
+		dprintk("Data values src 0x%x, dest 0x%x, memset 0x%x\n",
+			*(u32 *) ((u8 *) desc + 2048),
+			*(u32 *) ((u8 *) desc + 1024),
+			*(u32 *) ((u8 *) desc + 3072));
+		return -1;
+	}
+	return 0;
+}
+
+static struct device dummy_dma_dev = {
+	.bus_id = "fallback device",
+	.coherent_dma_mask = DMA_64BIT_MASK,
+	.dma_mask = &dummy_dma_dev.coherent_dma_mask,
+};
+
+/* Setup and initialize I/O AT */
+/* This driver needs I/O AT as the throttling takes effect only when there is
+ * some memory activity. We use I/O AT to set up a dummy copy, while all CPUs
+ * go idle and memory is throttled.
+ */
+static int __init i7300_idle_ioat_init(void)
+{
+	u8 ver, chan_count, ioat_chan;
+	u16 chan_ctl;
+
+	ioat_iomap = (u8 *) ioremap_nocache(pci_resource_start(ioat_dev, 0),
+					    pci_resource_len(ioat_dev, 0));
+
+	if (!ioat_iomap) {
+		printk(KERN_ERR I7300_PRINT "failed to map I/O AT registers\n");
+		goto err_ret;
+	}
+
+	ver = readb(ioat_iomap + IOAT_VER_OFFSET);
+	if (ver != IOAT_VER_1_2) {
+		printk(KERN_ERR I7300_PRINT "unknown I/O AT version (%u.%u)\n",
+			ver >> 4, ver & 0xf);
+		goto err_unmap;
+	}
+
+	chan_count = readb(ioat_iomap + IOAT_CHANCNT_OFFSET);
+	if (!chan_count) {
+		printk(KERN_ERR I7300_PRINT "unexpected # of I/O AT channels "
+			"(%u)\n",
+			chan_count);
+		goto err_unmap;
+	}
+
+	ioat_chan = chan_count - 1;
+	ioat_chanbase = IOAT_CHANBASE(ioat_iomap, ioat_chan);
+
+	chan_ctl = readw(ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+	if (chan_ctl & IOAT_CHANCTRL_CHANNEL_IN_USE) {
+		printk(KERN_ERR I7300_PRINT "channel %d in use\n", ioat_chan);
+		goto err_unmap;
+	}
+
+	writew(IOAT_CHANCTRL_CHANNEL_IN_USE,
+		ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+
+	ioat_desc = (struct ioat_dma_descriptor *)dma_alloc_coherent(
+			&dummy_dma_dev, 4096,
+			(dma_addr_t *)&ioat_desc_phys, GFP_KERNEL);
+	if (!ioat_desc) {
+		printk(KERN_ERR I7300_PRINT "failed to allocate I/O AT desc\n");
+		goto err_mark_unused;
+	}
+
+	writel(ioat_desc_phys & 0xffffffffUL,
+	       ioat_chanbase + IOAT1_CHAINADDR_OFFSET_LOW);
+	writel(ioat_desc_phys >> 32,
+	       ioat_chanbase + IOAT1_CHAINADDR_OFFSET_HIGH);
+
+	if (i7300_idle_ioat_selftest(ioat_iomap, ioat_desc, ioat_desc_phys)) {
+		printk(KERN_ERR I7300_PRINT "I/O AT self-test failed\n");
+		goto err_free;
+	}
+
+	/* Setup circular I/O AT descriptor chain */
+	ioat_desc[0].ctl = IOAT_DESC_SADDR_SNP_CTL | IOAT_DESC_DADDR_SNP_CTL;
+	ioat_desc[0].src_addr = ioat_desc_phys + 2048;
+	ioat_desc[0].dst_addr = ioat_desc_phys + 3072;
+	ioat_desc[0].size = 128;
+	ioat_desc[0].next = ioat_desc_phys + sizeof(struct ioat_dma_descriptor);
+
+	ioat_desc[1].ctl = ioat_desc[0].ctl;
+	ioat_desc[1].src_addr = ioat_desc[0].src_addr;
+	ioat_desc[1].dst_addr = ioat_desc[0].dst_addr;
+	ioat_desc[1].size = ioat_desc[0].size;
+	ioat_desc[1].next = ioat_desc_phys;
+
+	return 0;
+
+err_free:
+	dma_free_coherent(&dummy_dma_dev, 4096, (void *)ioat_desc, 0);
+err_mark_unused:
+	writew(0, ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+err_unmap:
+	iounmap(ioat_iomap);
+err_ret:
+	return -ENODEV;
+}
+
+/* Cleanup I/O AT */
+static void __exit i7300_idle_ioat_exit(void)
+{
+	int i;
+	u64 chan_sts;
+
+	i7300_idle_ioat_stop();
+
+	/* Wait for a while for the channel to halt before releasing */
+	for (i = 0; i < 10; i++) {
+		writeb(IOAT_CHANCMD_RESET,
+		       ioat_chanbase + IOAT1_CHANCMD_OFFSET);
+
+		chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+			IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+		if (chan_sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) {
+			writew(0, ioat_chanbase + IOAT_CHANCTRL_OFFSET);
+			break;
+		}
+		udelay(1000);
+	}
+
+	chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) &
+			IOAT_CHANSTS_DMA_TRANSFER_STATUS;
+
+	/*
+	 * We tried to reset multiple times. If IO A/T channel is still active
+	 * flag an error and return without cleanup. Memory leak is better
+	 * than random corruption in that extreme error situation.
+	 */
+	if (chan_sts == IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) {
+		printk(KERN_ERR I7300_PRINT "Unable to stop IO A/T channels."
+			" Not freeing resources\n");
+		return;
+	}
+
+	dma_free_coherent(&dummy_dma_dev, 4096, (void *)ioat_desc, 0);
+	iounmap(ioat_iomap);
+}
+
+/* End: I/O AT Helper routines */
+
+#define DIMM_THRTLOW 0x64
+#define DIMM_THRTCTL 0x67
+#define DIMM_THRTCTL_THRMHUNT (1UL << 0)
+#define DIMM_MC 0x40
+#define DIMM_GTW_MODE (1UL << 17)
+#define DIMM_GBLACT 0x60
+
+/*
+ * Keep track of an exponential-decaying average of recent idle durations.
+ * The latest duration gets DURATION_WEIGHT_PCT percentage weight
+ * in this average, with the old average getting the remaining weight.
+ *
+ * High weights emphasize recent history, low weights include long history.
+ */
+#define DURATION_WEIGHT_PCT 55
+
+/*
+ * When the decaying average of recent durations or the predicted duration
+ * of the next timer interrupt is shorter than duration_threshold, the
+ * driver will decline to throttle.
+ */
+#define DURATION_THRESHOLD_US 100
+
+
+/* Store DIMM thermal throttle configuration */
+static int i7300_idle_thrt_save(void)
+{
+	u32 new_mc_val;
+	u8 gblactlm;
+
+	pci_read_config_byte(fbd_dev, DIMM_THRTCTL, &i7300_idle_thrtctl_saved);
+	pci_read_config_byte(fbd_dev, DIMM_THRTLOW, &i7300_idle_thrtlow_saved);
+	pci_read_config_dword(fbd_dev, DIMM_MC, &i7300_idle_mc_saved);
+	/*
+	 * Make sure we have Global Throttling Window Mode set to have a
+	 * "short" window. This (mostly) works around an issue where
+	 * throttling persists until the end of the global throttling window
+	 * size. On the tested system, this was resulting in a maximum of
+	 * 64 ms to exit throttling (average 32 ms). The actual numbers
+	 * depends on system frequencies. Setting the short window reduces
+	 * this by a factor of 4096.
+	 *
+	 * We will only do this only if the system is set for
+	 * unlimited-activations while in open-loop throttling (i.e., when
+	 * Global Activation Throttle Limit is zero).
+	 */
+	pci_read_config_byte(fbd_dev, DIMM_GBLACT, &gblactlm);
+	dprintk("thrtctl_saved = 0x%02x, thrtlow_saved = 0x%02x\n",
+		i7300_idle_thrtctl_saved,
+		i7300_idle_thrtlow_saved);
+	dprintk("mc_saved = 0x%08x, gblactlm = 0x%02x\n",
+		i7300_idle_mc_saved,
+		gblactlm);
+	if (gblactlm == 0) {
+		new_mc_val = i7300_idle_mc_saved | DIMM_GTW_MODE;
+		pci_write_config_dword(fbd_dev, DIMM_MC, new_mc_val);
+		return 0;
+	} else {
+		dprintk("could not set GTW_MODE = 1 (OLTT enabled)\n");
+		return -ENODEV;
+	}
+}
+
+/* Restore DIMM thermal throttle configuration */
+static void i7300_idle_thrt_restore(void)
+{
+	pci_write_config_dword(fbd_dev, DIMM_MC, i7300_idle_mc_saved);
+	pci_write_config_byte(fbd_dev, DIMM_THRTLOW, i7300_idle_thrtlow_saved);
+	pci_write_config_byte(fbd_dev, DIMM_THRTCTL, i7300_idle_thrtctl_saved);
+}
+
+/* Enable DIMM thermal throttling */
+static void i7300_idle_start(void)
+{
+	u8 new_ctl;
+	u8 limit;
+
+	new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT;
+	pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
+
+	limit = i7300_idle_thrtlowlm;
+	if (unlikely(limit > MAX_THRTLWLIMIT))
+		limit = MAX_THRTLWLIMIT;
+
+	pci_write_config_byte(fbd_dev, DIMM_THRTLOW, limit);
+
+	new_ctl = i7300_idle_thrtctl_saved | DIMM_THRTCTL_THRMHUNT;
+	pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
+}
+
+/* Disable DIMM thermal throttling */
+static void i7300_idle_stop(void)
+{
+	u8 new_ctl;
+	u8 got_ctl;
+
+	new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT;
+	pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
+
+	pci_write_config_byte(fbd_dev, DIMM_THRTLOW, i7300_idle_thrtlow_saved);
+	pci_write_config_byte(fbd_dev, DIMM_THRTCTL, i7300_idle_thrtctl_saved);
+	pci_read_config_byte(fbd_dev, DIMM_THRTCTL, &got_ctl);
+	WARN_ON_ONCE(got_ctl != i7300_idle_thrtctl_saved);
+}
+
+
+/*
+ * i7300_avg_duration_check()
+ * return 0 if the decaying average of recent idle durations is
+ * more than DURATION_THRESHOLD_US
+ */
+static int i7300_avg_duration_check(void)
+{
+	if (avg_idle_us >= DURATION_THRESHOLD_US)
+		return 0;
+
+#ifdef DEBUG
+	past_skip++;
+#endif
+	return 1;
+}
+
+/* Idle notifier to look at idle CPUs */
+static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val,
+				void *data)
+{
+	unsigned long flags;
+	ktime_t now_ktime;
+	static ktime_t idle_begin_time;
+	static int time_init = 1;
+
+	if (!i7300_idle_thrtlowlm)
+		return 0;
+
+	if (unlikely(time_init)) {
+		time_init = 0;
+		idle_begin_time = ktime_get();
+	}
+
+	spin_lock_irqsave(&i7300_idle_lock, flags);
+	if (val == IDLE_START) {
+
+		cpu_set(smp_processor_id(), idle_cpumask);
+
+		if (cpus_weight(idle_cpumask) != num_online_cpus())
+			goto end;
+
+		now_ktime = ktime_get();
+		idle_begin_time = now_ktime;
+
+		if (i7300_avg_duration_check())
+			goto end;
+
+		i7300_idle_active = 1;
+		total_starts++;
+		start_ktime = now_ktime;
+
+		i7300_idle_start();
+		i7300_idle_ioat_start();
+
+	} else if (val == IDLE_END) {
+		cpu_clear(smp_processor_id(), idle_cpumask);
+		if (cpus_weight(idle_cpumask) == (num_online_cpus() - 1)) {
+			/* First CPU coming out of idle */
+			u64 idle_duration_us;
+
+			now_ktime = ktime_get();
+
+			idle_duration_us = ktime_to_us(ktime_sub
+						(now_ktime, idle_begin_time));
+
+			avg_idle_us =
+				((100 - DURATION_WEIGHT_PCT) * avg_idle_us +
+				 DURATION_WEIGHT_PCT * idle_duration_us) / 100;
+
+			if (i7300_idle_active) {
+				ktime_t idle_ktime;
+
+				idle_ktime = ktime_sub(now_ktime, start_ktime);
+				total_us += ktime_to_us(idle_ktime);
+
+				i7300_idle_ioat_stop();
+				i7300_idle_stop();
+				i7300_idle_active = 0;
+			}
+		}
+	}
+end:
+	spin_unlock_irqrestore(&i7300_idle_lock, flags);
+	return 0;
+}
+
+static struct notifier_block i7300_idle_nb = {
+	.notifier_call = i7300_idle_notifier,
+};
+
+/*
+ * I/O AT controls (PCI bus 0 device 8 function 0)
+ * DIMM controls (PCI bus 0 device 16 function 1)
+ */
+#define IOAT_BUS 0
+#define IOAT_DEVFN PCI_DEVFN(8, 0)
+#define MEMCTL_BUS 0
+#define MEMCTL_DEVFN PCI_DEVFN(16, 1)
+
+struct fbd_ioat {
+	unsigned int vendor;
+	unsigned int ioat_dev;
+};
+
+/*
+ * The i5000 chip-set has the same hooks as the i7300
+ * but support is disabled by default because this driver
+ * has not been validated on that platform.
+ */
+#define SUPPORT_I5000 0
+
+static const struct fbd_ioat fbd_ioat_list[] = {
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB},
+#if SUPPORT_I5000
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT},
+#endif
+	{0, 0}
+};
+
+/* table of devices that work with this driver */
+static const struct pci_device_id pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) },
+#if SUPPORT_I5000
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
+#endif
+	{ } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+/* Check for known platforms with I/O-AT */
+static int __init i7300_idle_platform_probe(void)
+{
+	int i;
+
+	fbd_dev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN);
+	if (!fbd_dev)
+		return -ENODEV;
+
+	for (i = 0; pci_tbl[i].vendor != 0; i++) {
+		if (fbd_dev->vendor == pci_tbl[i].vendor &&
+		    fbd_dev->device == pci_tbl[i].device) {
+			break;
+		}
+	}
+	if (pci_tbl[i].vendor == 0)
+		return -ENODEV;
+
+	ioat_dev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN);
+	if (!ioat_dev)
+		return -ENODEV;
+
+	for (i = 0; fbd_ioat_list[i].vendor != 0; i++) {
+		if (ioat_dev->vendor == fbd_ioat_list[i].vendor &&
+		    ioat_dev->device == fbd_ioat_list[i].ioat_dev) {
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+int stats_open_generic(struct inode *inode, struct file *fp)
+{
+	fp->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count,
+				loff_t *off)
+{
+	unsigned long *p = fp->private_data;
+	char buf[32];
+	int len;
+
+	len = snprintf(buf, 32, "%lu\n", *p);
+	return simple_read_from_buffer(ubuf, count, off, buf, len);
+}
+
+static const struct file_operations idle_fops = {
+	.open	= stats_open_generic,
+	.read	= stats_read_ul,
+};
+
+struct debugfs_file_info {
+	void *ptr;
+	char name[32];
+	struct dentry *file;
+} debugfs_file_list[] = {
+				{&total_starts, "total_starts", NULL},
+				{&total_us, "total_us", NULL},
+#ifdef DEBUG
+				{&past_skip, "past_skip", NULL},
+#endif
+				{NULL, "", NULL}
+			};
+
+static int __init i7300_idle_init(void)
+{
+	spin_lock_init(&i7300_idle_lock);
+	cpus_clear(idle_cpumask);
+	total_us = 0;
+
+	if (i7300_idle_platform_probe())
+		return -ENODEV;
+
+	if (i7300_idle_thrt_save())
+		return -ENODEV;
+
+	if (i7300_idle_ioat_init())
+		return -ENODEV;
+
+	debugfs_dir = debugfs_create_dir("i7300_idle", NULL);
+	if (debugfs_dir) {
+		int i = 0;
+
+		while (debugfs_file_list[i].ptr != NULL) {
+			debugfs_file_list[i].file = debugfs_create_file(
+					debugfs_file_list[i].name,
+					S_IRUSR,
+					debugfs_dir,
+					debugfs_file_list[i].ptr,
+					&idle_fops);
+			i++;
+		}
+	}
+
+	idle_notifier_register(&i7300_idle_nb);
+
+	printk(KERN_INFO "i7300_idle: loaded v%s\n", I7300_IDLE_DRIVER_VERSION);
+	return 0;
+}
+
+static void __exit i7300_idle_exit(void)
+{
+	idle_notifier_unregister(&i7300_idle_nb);
+
+	if (debugfs_dir) {
+		int i = 0;
+
+		while (debugfs_file_list[i].file != NULL) {
+			debugfs_remove(debugfs_file_list[i].file);
+			i++;
+		}
+
+		debugfs_remove(debugfs_dir);
+	}
+	i7300_idle_thrt_restore();
+	i7300_idle_ioat_exit();
+}
+
+module_init(i7300_idle_init);
+module_exit(i7300_idle_exit);
+
+MODULE_AUTHOR("Andy Henroid <andrew.d.henroid@intel.com>");
+MODULE_DESCRIPTION("Intel Chipset DIMM Idle Power Saving Driver v"
+			I7300_IDLE_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index efd3aa08b88b..9494400e8fd0 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -145,6 +145,7 @@ config ACER_WMI
 	depends on NEW_LEDS
 	depends on BACKLIGHT_CLASS_DEVICE
 	depends on SERIO_I8042
+	depends on RFKILL
 	select ACPI_WMI
 	---help---
 	  This is a driver for newer Acer (and Wistron) laptops. It adds
@@ -245,6 +246,17 @@ config MSI_LAPTOP
 
 	  If you have an MSI S270 laptop, say Y or M here.
 
+config PANASONIC_LAPTOP
+	tristate "Panasonic Laptop Extras"
+	depends on X86 && INPUT && ACPI
+        depends on BACKLIGHT_CLASS_DEVICE
+	---help---
+	  This driver adds support for access to backlight control and hotkeys
+	  on Panasonic Let's Note laptops.
+
+	  If you have a Panasonic Let's note laptop (such as the R1(N variant),
+	  R2, R3, R5, T2, W2 and Y2 series), say Y.
+
 config COMPAL_LAPTOP
 	tristate "Compal Laptop Extras"
 	depends on X86
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c6c13f60b452..909e2468cdc9 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_SGI_IOC4)		+= ioc4.o
 obj-$(CONFIG_SONY_LAPTOP)	+= sony-laptop.o
 obj-$(CONFIG_THINKPAD_ACPI)	+= thinkpad_acpi.o
 obj-$(CONFIG_FUJITSU_LAPTOP)	+= fujitsu-laptop.o
+obj-$(CONFIG_PANASONIC_LAPTOP)	+= panasonic-laptop.o
 obj-$(CONFIG_EEPROM_93CX6)	+= eeprom_93cx6.o
 obj-$(CONFIG_INTEL_MENLOW)	+= intel_menlow.o
 obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index d8b0d326e452..0532a2de2ce4 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -33,6 +33,8 @@
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 #include <linux/i8042.h>
+#include <linux/rfkill.h>
+#include <linux/workqueue.h>
 #include <linux/debugfs.h>
 
 #include <acpi/acpi_drivers.h>
@@ -123,21 +125,15 @@ enum interface_flags {
 
 static int max_brightness = 0xF;
 
-static int wireless = -1;
-static int bluetooth = -1;
 static int mailled = -1;
 static int brightness = -1;
 static int threeg = -1;
 static int force_series;
 
 module_param(mailled, int, 0444);
-module_param(wireless, int, 0444);
-module_param(bluetooth, int, 0444);
 module_param(brightness, int, 0444);
 module_param(threeg, int, 0444);
 module_param(force_series, int, 0444);
-MODULE_PARM_DESC(wireless, "Set initial state of Wireless hardware");
-MODULE_PARM_DESC(bluetooth, "Set initial state of Bluetooth hardware");
 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
@@ -145,8 +141,6 @@ MODULE_PARM_DESC(force_series, "Force a different laptop series");
 
 struct acer_data {
 	int mailled;
-	int wireless;
-	int bluetooth;
 	int threeg;
 	int brightness;
 };
@@ -157,6 +151,9 @@ struct acer_debug {
 	u32 wmid_devices;
 };
 
+static struct rfkill *wireless_rfkill;
+static struct rfkill *bluetooth_rfkill;
+
 /* Each low-level interface must define at least some of the following */
 struct wmi_interface {
 	/* The WMI device type */
@@ -476,7 +473,7 @@ struct wmi_interface *iface)
 		}
 		break;
 	default:
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 	}
 	return AE_OK;
 }
@@ -514,7 +511,7 @@ static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
 			break;
 		}
 	default:
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 	}
 
 	/* Actually do the set */
@@ -689,7 +686,7 @@ struct wmi_interface *iface)
 			return 0;
 		}
 	default:
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 	}
 	status = WMI_execute_u32(method_id, 0, &result);
 
@@ -735,7 +732,7 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
 		}
 		break;
 	default:
-		return AE_BAD_ADDRESS;
+		return AE_ERROR;
 	}
 	return WMI_execute_u32(method_id, (u32)value, NULL);
 }
@@ -785,7 +782,7 @@ static struct wmi_interface wmid_interface = {
 
 static acpi_status get_u32(u32 *value, u32 cap)
 {
-	acpi_status status = AE_BAD_ADDRESS;
+	acpi_status status = AE_ERROR;
 
 	switch (interface->type) {
 	case ACER_AMW0:
@@ -846,8 +843,6 @@ static void __init acer_commandline_init(void)
 	 * capability isn't available on the given interface
 	 */
 	set_u32(mailled, ACER_CAP_MAILLED);
-	set_u32(wireless, ACER_CAP_WIRELESS);
-	set_u32(bluetooth, ACER_CAP_BLUETOOTH);
 	set_u32(threeg, ACER_CAP_THREEG);
 	set_u32(brightness, ACER_CAP_BRIGHTNESS);
 }
@@ -933,40 +928,135 @@ static void acer_backlight_exit(void)
 }
 
 /*
- * Read/ write bool sysfs macro
+ * Rfkill devices
  */
-#define show_set_bool(value, cap) \
-static ssize_t \
-show_bool_##value(struct device *dev, struct device_attribute *attr, \
-	char *buf) \
-{ \
-	u32 result; \
-	acpi_status status = get_u32(&result, cap); \
-	if (ACPI_SUCCESS(status)) \
-		return sprintf(buf, "%u\n", result); \
-	return sprintf(buf, "Read error\n"); \
-} \
-\
-static ssize_t \
-set_bool_##value(struct device *dev, struct device_attribute *attr, \
-	const char *buf, size_t count) \
-{ \
-	u32 tmp = simple_strtoul(buf, NULL, 10); \
-	acpi_status status = set_u32(tmp, cap); \
-		if (ACPI_FAILURE(status)) \
-			return -EINVAL; \
-	return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO | S_IWUSR, \
-	show_bool_##value, set_bool_##value);
-
-show_set_bool(wireless, ACER_CAP_WIRELESS);
-show_set_bool(bluetooth, ACER_CAP_BLUETOOTH);
-show_set_bool(threeg, ACER_CAP_THREEG);
+static void acer_rfkill_update(struct work_struct *ignored);
+static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
+static void acer_rfkill_update(struct work_struct *ignored)
+{
+	u32 state;
+	acpi_status status;
+
+	status = get_u32(&state, ACER_CAP_WIRELESS);
+	if (ACPI_SUCCESS(status))
+		rfkill_force_state(wireless_rfkill, state ?
+			RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);
+
+	if (has_cap(ACER_CAP_BLUETOOTH)) {
+		status = get_u32(&state, ACER_CAP_BLUETOOTH);
+		if (ACPI_SUCCESS(status))
+			rfkill_force_state(bluetooth_rfkill, state ?
+				RFKILL_STATE_UNBLOCKED :
+				RFKILL_STATE_SOFT_BLOCKED);
+	}
+
+	schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
+}
+
+static int acer_rfkill_set(void *data, enum rfkill_state state)
+{
+	acpi_status status;
+	u32 *cap = data;
+	status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+	return 0;
+}
+
+static struct rfkill * acer_rfkill_register(struct device *dev,
+enum rfkill_type type, char *name, u32 cap)
+{
+	int err;
+	u32 state;
+	u32 *data;
+	struct rfkill *rfkill_dev;
+
+	rfkill_dev = rfkill_allocate(dev, type);
+	if (!rfkill_dev)
+		return ERR_PTR(-ENOMEM);
+	rfkill_dev->name = name;
+	get_u32(&state, cap);
+	rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED :
+		RFKILL_STATE_SOFT_BLOCKED;
+	data = kzalloc(sizeof(u32), GFP_KERNEL);
+	if (!data) {
+		rfkill_free(rfkill_dev);
+		return ERR_PTR(-ENOMEM);
+	}
+	*data = cap;
+	rfkill_dev->data = data;
+	rfkill_dev->toggle_radio = acer_rfkill_set;
+	rfkill_dev->user_claim_unsupported = 1;
+
+	err = rfkill_register(rfkill_dev);
+	if (err) {
+		kfree(rfkill_dev->data);
+		rfkill_free(rfkill_dev);
+		return ERR_PTR(err);
+	}
+	return rfkill_dev;
+}
+
+static int acer_rfkill_init(struct device *dev)
+{
+	wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
+		"acer-wireless", ACER_CAP_WIRELESS);
+	if (IS_ERR(wireless_rfkill))
+		return PTR_ERR(wireless_rfkill);
+
+	if (has_cap(ACER_CAP_BLUETOOTH)) {
+		bluetooth_rfkill = acer_rfkill_register(dev,
+			RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
+			ACER_CAP_BLUETOOTH);
+		if (IS_ERR(bluetooth_rfkill)) {
+			kfree(wireless_rfkill->data);
+			rfkill_unregister(wireless_rfkill);
+			return PTR_ERR(bluetooth_rfkill);
+		}
+	}
+
+	schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
+
+	return 0;
+}
+
+static void acer_rfkill_exit(void)
+{
+	cancel_delayed_work_sync(&acer_rfkill_work);
+	kfree(wireless_rfkill->data);
+	rfkill_unregister(wireless_rfkill);
+	if (has_cap(ACER_CAP_BLUETOOTH)) {
+		kfree(wireless_rfkill->data);
+		rfkill_unregister(bluetooth_rfkill);
+	}
+	return;
+}
 
 /*
- * Read interface sysfs macro
+ * sysfs interface
  */
+static ssize_t show_bool_threeg(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	u32 result; \
+	acpi_status status = get_u32(&result, ACER_CAP_THREEG);
+	if (ACPI_SUCCESS(status))
+		return sprintf(buf, "%u\n", result);
+	return sprintf(buf, "Read error\n");
+}
+
+static ssize_t set_bool_threeg(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	u32 tmp = simple_strtoul(buf, NULL, 10);
+	acpi_status status = set_u32(tmp, ACER_CAP_THREEG);
+		if (ACPI_FAILURE(status))
+			return -EINVAL;
+	return count;
+}
+static DEVICE_ATTR(threeg, S_IWUGO | S_IRUGO | S_IWUSR, show_bool_threeg,
+	set_bool_threeg);
+
 static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
 	char *buf)
 {
@@ -1026,7 +1116,9 @@ static int __devinit acer_platform_probe(struct platform_device *device)
 			goto error_brightness;
 	}
 
-	return 0;
+	err = acer_rfkill_init(&device->dev);
+
+	return err;
 
 error_brightness:
 	acer_led_exit();
@@ -1040,6 +1132,8 @@ static int acer_platform_remove(struct platform_device *device)
 		acer_led_exit();
 	if (has_cap(ACER_CAP_BRIGHTNESS))
 		acer_backlight_exit();
+
+	acer_rfkill_exit();
 	return 0;
 }
 
@@ -1052,16 +1146,6 @@ pm_message_t state)
 	if (!data)
 		return -ENOMEM;
 
-	if (has_cap(ACER_CAP_WIRELESS)) {
-		get_u32(&value, ACER_CAP_WIRELESS);
-		data->wireless = value;
-	}
-
-	if (has_cap(ACER_CAP_BLUETOOTH)) {
-		get_u32(&value, ACER_CAP_BLUETOOTH);
-		data->bluetooth = value;
-	}
-
 	if (has_cap(ACER_CAP_MAILLED)) {
 		get_u32(&value, ACER_CAP_MAILLED);
 		data->mailled = value;
@@ -1082,15 +1166,6 @@ static int acer_platform_resume(struct platform_device *device)
 	if (!data)
 		return -ENOMEM;
 
-	if (has_cap(ACER_CAP_WIRELESS))
-		set_u32(data->wireless, ACER_CAP_WIRELESS);
-
-	if (has_cap(ACER_CAP_BLUETOOTH))
-		set_u32(data->bluetooth, ACER_CAP_BLUETOOTH);
-
-	if (has_cap(ACER_CAP_THREEG))
-		set_u32(data->threeg, ACER_CAP_THREEG);
-
 	if (has_cap(ACER_CAP_MAILLED))
 		set_u32(data->mailled, ACER_CAP_MAILLED);
 
@@ -1115,12 +1190,6 @@ static struct platform_device *acer_platform_device;
 
 static int remove_sysfs(struct platform_device *device)
 {
-	if (has_cap(ACER_CAP_WIRELESS))
-		device_remove_file(&device->dev, &dev_attr_wireless);
-
-	if (has_cap(ACER_CAP_BLUETOOTH))
-		device_remove_file(&device->dev, &dev_attr_bluetooth);
-
 	if (has_cap(ACER_CAP_THREEG))
 		device_remove_file(&device->dev, &dev_attr_threeg);
 
@@ -1133,20 +1202,6 @@ static int create_sysfs(void)
 {
 	int retval = -ENOMEM;
 
-	if (has_cap(ACER_CAP_WIRELESS)) {
-		retval = device_create_file(&acer_platform_device->dev,
-			&dev_attr_wireless);
-		if (retval)
-			goto error_sysfs;
-	}
-
-	if (has_cap(ACER_CAP_BLUETOOTH)) {
-		retval = device_create_file(&acer_platform_device->dev,
-			&dev_attr_bluetooth);
-		if (retval)
-			goto error_sysfs;
-	}
-
 	if (has_cap(ACER_CAP_THREEG)) {
 		retval = device_create_file(&acer_platform_device->dev,
 			&dev_attr_threeg);
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 7c6dfd03de9f..a9d5228724a6 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -139,6 +139,7 @@ ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10",	/* All new models */
 	    "\\_SB.PCI0.PX40.ECD0._Q10",	/* L3C */
 	    "\\_SB.PCI0.PX40.EC0.Q10",	/* M1A */
 	    "\\_SB.PCI0.LPCB.EC0._Q10",	/* P30 */
+	    "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
 	    "\\_SB.PCI0.PX40.Q10",	/* S1x */
 	    "\\Q10");		/* A2x, L2D, L3D, M2E */
 
@@ -280,7 +281,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
 
 static int read_wireless_status(int mask)
 {
-	ulong status;
+	unsigned long long status;
 	acpi_status rv = AE_OK;
 
 	if (!wireless_status_handle)
@@ -297,7 +298,7 @@ static int read_wireless_status(int mask)
 
 static int read_gps_status(void)
 {
-	ulong status;
+	unsigned long long status;
 	acpi_status rv = AE_OK;
 
 	rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status);
@@ -350,7 +351,7 @@ static void write_status(acpi_handle handle, int out, int mask)
 	static void object##_led_set(struct led_classdev *led_cdev,	\
 				     enum led_brightness value)		\
 	{								\
-		object##_led_wk = value;				\
+		object##_led_wk = (value > 0) ? 1 : 0;			\
 		queue_work(led_workqueue, &object##_led_work);		\
 	}								\
 	static void object##_led_update(struct work_struct *ignored)	\
@@ -404,7 +405,7 @@ static void lcd_blank(int blank)
 
 static int read_brightness(struct backlight_device *bd)
 {
-	ulong value;
+	unsigned long long value;
 	acpi_status rv = AE_OK;
 
 	rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value);
@@ -455,7 +456,7 @@ static ssize_t show_infos(struct device *dev,
 			  struct device_attribute *attr, char *page)
 {
 	int len = 0;
-	ulong temp;
+	unsigned long long temp;
 	char buf[16];		//enough for all info
 	acpi_status rv = AE_OK;
 
@@ -603,7 +604,7 @@ static void set_display(int value)
 
 static int read_display(void)
 {
-	ulong value = 0;
+	unsigned long long value = 0;
 	acpi_status rv = AE_OK;
 
 	/* In most of the case, we know how to set the display, but sometime
@@ -849,7 +850,7 @@ static int asus_hotk_get_info(void)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *model = NULL;
-	ulong bsts_result, hwrs_result;
+	unsigned long long bsts_result, hwrs_result;
 	char *string = NULL;
 	acpi_status status;
 
@@ -996,7 +997,7 @@ static int asus_hotk_add(struct acpi_device *device)
 	hotk->handle = device->handle;
 	strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
-	acpi_driver_data(device) = hotk;
+	device->driver_data = hotk;
 	hotk->device = device;
 
 	result = asus_hotk_check();
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c
index 1ee8501e90f1..9ef98b2d5039 100644
--- a/drivers/misc/eeepc-laptop.c
+++ b/drivers/misc/eeepc-laptop.c
@@ -28,6 +28,8 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <linux/uaccess.h>
+#include <linux/input.h>
+#include <linux/rfkill.h>
 
 #define EEEPC_LAPTOP_VERSION	"0.1"
 
@@ -125,6 +127,10 @@ struct eeepc_hotk {
 					   by this BIOS */
 	uint init_flag;			/* Init flags */
 	u16 event_count[128];		/* count for each event */
+	struct input_dev *inputdev;
+	u16 *keycode_map;
+	struct rfkill *eeepc_wlan_rfkill;
+	struct rfkill *eeepc_bluetooth_rfkill;
 };
 
 /* The actual device the driver binds to */
@@ -140,6 +146,27 @@ static struct platform_driver platform_driver = {
 
 static struct platform_device *platform_device;
 
+struct key_entry {
+	char type;
+	u8 code;
+	u16 keycode;
+};
+
+enum { KE_KEY, KE_END };
+
+static struct key_entry eeepc_keymap[] = {
+	/* Sleep already handled via generic ACPI code */
+	{KE_KEY, 0x10, KEY_WLAN },
+	{KE_KEY, 0x12, KEY_PROG1 },
+	{KE_KEY, 0x13, KEY_MUTE },
+	{KE_KEY, 0x14, KEY_VOLUMEDOWN },
+	{KE_KEY, 0x15, KEY_VOLUMEUP },
+	{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
+	{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
+	{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
+	{KE_END, 0},
+};
+
 /*
  * The hotkey driver declaration
  */
@@ -204,7 +231,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
 {
 	acpi_status status;
-	ulong result;
+	unsigned long long result;
 
 	status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
 	if (ACPI_FAILURE(status)) {
@@ -261,6 +288,44 @@ static int update_bl_status(struct backlight_device *bd)
 }
 
 /*
+ * Rfkill helpers
+ */
+
+static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state)
+{
+	if (state == RFKILL_STATE_SOFT_BLOCKED)
+		return set_acpi(CM_ASL_WLAN, 0);
+	else
+		return set_acpi(CM_ASL_WLAN, 1);
+}
+
+static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
+{
+	if (get_acpi(CM_ASL_WLAN) == 1)
+		*state = RFKILL_STATE_UNBLOCKED;
+	else
+		*state = RFKILL_STATE_SOFT_BLOCKED;
+	return 0;
+}
+
+static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state)
+{
+	if (state == RFKILL_STATE_SOFT_BLOCKED)
+		return set_acpi(CM_ASL_BLUETOOTH, 0);
+	else
+		return set_acpi(CM_ASL_BLUETOOTH, 1);
+}
+
+static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state)
+{
+	if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+		*state = RFKILL_STATE_UNBLOCKED;
+	else
+		*state = RFKILL_STATE_SOFT_BLOCKED;
+	return 0;
+}
+
+/*
  * Sys helpers
  */
 static int parse_arg(const char *buf, unsigned long count, int *val)
@@ -311,13 +376,11 @@ static ssize_t show_sys_acpi(int cm, char *buf)
 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
-EEEPC_CREATE_DEVICE_ATTR(wlan, CM_ASL_WLAN);
 
 static struct attribute *platform_attributes[] = {
 	&dev_attr_camera.attr,
 	&dev_attr_cardr.attr,
 	&dev_attr_disp.attr,
-	&dev_attr_wlan.attr,
 	NULL
 };
 
@@ -328,8 +391,64 @@ static struct attribute_group platform_attribute_group = {
 /*
  * Hotkey functions
  */
+static struct key_entry *eepc_get_entry_by_scancode(int code)
+{
+	struct key_entry *key;
+
+	for (key = eeepc_keymap; key->type != KE_END; key++)
+		if (code == key->code)
+			return key;
+
+	return NULL;
+}
+
+static struct key_entry *eepc_get_entry_by_keycode(int code)
+{
+	struct key_entry *key;
+
+	for (key = eeepc_keymap; key->type != KE_END; key++)
+		if (code == key->keycode && key->type == KE_KEY)
+			return key;
+
+	return NULL;
+}
+
+static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+	struct key_entry *key = eepc_get_entry_by_scancode(scancode);
+
+	if (key && key->type == KE_KEY) {
+		*keycode = key->keycode;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+	struct key_entry *key;
+	int old_keycode;
+
+	if (keycode < 0 || keycode > KEY_MAX)
+		return -EINVAL;
+
+	key = eepc_get_entry_by_scancode(scancode);
+	if (key && key->type == KE_KEY) {
+		old_keycode = key->keycode;
+		key->keycode = keycode;
+		set_bit(keycode, dev->keybit);
+		if (!eepc_get_entry_by_keycode(old_keycode))
+			clear_bit(old_keycode, dev->keybit);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static int eeepc_hotk_check(void)
 {
+	const struct key_entry *key;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	int result;
 
@@ -356,6 +475,31 @@ static int eeepc_hotk_check(void)
 			       "Get control methods supported: 0x%x\n",
 			       ehotk->cm_supported);
 		}
+		ehotk->inputdev = input_allocate_device();
+		if (!ehotk->inputdev) {
+			printk(EEEPC_INFO "Unable to allocate input device\n");
+			return 0;
+		}
+		ehotk->inputdev->name = "Asus EeePC extra buttons";
+		ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
+		ehotk->inputdev->id.bustype = BUS_HOST;
+		ehotk->inputdev->getkeycode = eeepc_getkeycode;
+		ehotk->inputdev->setkeycode = eeepc_setkeycode;
+
+		for (key = eeepc_keymap; key->type != KE_END; key++) {
+			switch (key->type) {
+			case KE_KEY:
+				set_bit(EV_KEY, ehotk->inputdev->evbit);
+				set_bit(key->keycode, ehotk->inputdev->keybit);
+				break;
+			}
+		}
+		result = input_register_device(ehotk->inputdev);
+		if (result) {
+			printk(EEEPC_INFO "Unable to register input device\n");
+			input_free_device(ehotk->inputdev);
+			return 0;
+		}
 	} else {
 		printk(EEEPC_ERR "Hotkey device not present, aborting\n");
 		return -EINVAL;
@@ -363,21 +507,6 @@ static int eeepc_hotk_check(void)
 	return 0;
 }
 
-static void notify_wlan(u32 *event)
-{
-	/* if DISABLE_ASL_WLAN is set, the notify code for fn+f2
-	   will always be 0x10 */
-	if (ehotk->cm_supported & (0x1 << CM_ASL_WLAN)) {
-		const char *method = cm_getv[CM_ASL_WLAN];
-		int value;
-		if (read_acpi_int(ehotk->handle, method, &value))
-			printk(EEEPC_WARNING "Error reading %s\n",
-			       method);
-		else if (value == 1)
-			*event = 0x11;
-	}
-}
-
 static void notify_brn(void)
 {
 	struct backlight_device *bd = eeepc_backlight_device;
@@ -386,14 +515,28 @@ static void notify_brn(void)
 
 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
 {
+	static struct key_entry *key;
 	if (!ehotk)
 		return;
-	if (event == NOTIFY_WLAN_ON && (DISABLE_ASL_WLAN & ehotk->init_flag))
-		notify_wlan(&event);
 	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
 		notify_brn();
 	acpi_bus_generate_proc_event(ehotk->device, event,
 				     ehotk->event_count[event % 128]++);
+	if (ehotk->inputdev) {
+		key = eepc_get_entry_by_scancode(event);
+		if (key) {
+			switch (key->type) {
+			case KE_KEY:
+				input_report_key(ehotk->inputdev, key->keycode,
+						 1);
+				input_sync(ehotk->inputdev);
+				input_report_key(ehotk->inputdev, key->keycode,
+						 0);
+				input_sync(ehotk->inputdev);
+				break;
+			}
+		}
+	}
 }
 
 static int eeepc_hotk_add(struct acpi_device *device)
@@ -411,7 +554,7 @@ static int eeepc_hotk_add(struct acpi_device *device)
 	ehotk->handle = device->handle;
 	strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
 	strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
-	acpi_driver_data(device) = ehotk;
+	device->driver_data = ehotk;
 	ehotk->device = device;
 	result = eeepc_hotk_check();
 	if (result)
@@ -420,6 +563,47 @@ static int eeepc_hotk_add(struct acpi_device *device)
 					     eeepc_hotk_notify, ehotk);
 	if (ACPI_FAILURE(status))
 		printk(EEEPC_ERR "Error installing notify handler\n");
+
+	if (get_acpi(CM_ASL_WLAN) != -1) {
+		ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
+							   RFKILL_TYPE_WLAN);
+
+		if (!ehotk->eeepc_wlan_rfkill)
+			goto end;
+
+		ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
+		ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
+		ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
+		if (get_acpi(CM_ASL_WLAN) == 1)
+			ehotk->eeepc_wlan_rfkill->state =
+				RFKILL_STATE_UNBLOCKED;
+		else
+			ehotk->eeepc_wlan_rfkill->state =
+				RFKILL_STATE_SOFT_BLOCKED;
+		rfkill_register(ehotk->eeepc_wlan_rfkill);
+	}
+
+	if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
+		ehotk->eeepc_bluetooth_rfkill =
+			rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
+
+		if (!ehotk->eeepc_bluetooth_rfkill)
+			goto end;
+
+		ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
+		ehotk->eeepc_bluetooth_rfkill->toggle_radio =
+			eeepc_bluetooth_rfkill_set;
+		ehotk->eeepc_bluetooth_rfkill->get_state =
+			eeepc_bluetooth_rfkill_state;
+		if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+			ehotk->eeepc_bluetooth_rfkill->state =
+				RFKILL_STATE_UNBLOCKED;
+		else
+			ehotk->eeepc_bluetooth_rfkill->state =
+				RFKILL_STATE_SOFT_BLOCKED;
+		rfkill_register(ehotk->eeepc_bluetooth_rfkill);
+	}
+
  end:
 	if (result) {
 		kfree(ehotk);
@@ -553,6 +737,12 @@ static void eeepc_backlight_exit(void)
 {
 	if (eeepc_backlight_device)
 		backlight_device_unregister(eeepc_backlight_device);
+	if (ehotk->inputdev)
+		input_unregister_device(ehotk->inputdev);
+	if (ehotk->eeepc_wlan_rfkill)
+		rfkill_unregister(ehotk->eeepc_wlan_rfkill);
+	if (ehotk->eeepc_bluetooth_rfkill)
+		rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
 	eeepc_backlight_device = NULL;
 }
 
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
index 3e56203e4947..d2cf0bfe3163 100644
--- a/drivers/misc/fujitsu-laptop.c
+++ b/drivers/misc/fujitsu-laptop.c
@@ -44,8 +44,9 @@
  * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are
  * also supported by this driver.
  *
- * This driver has been tested on a Fujitsu Lifebook S6410 and S7020.  It
- * should work on most P-series and S-series Lifebooks, but YMMV.
+ * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and
+ * P8010.  It should work on most P-series and S-series Lifebooks, but
+ * YMMV.
  *
  * The module parameter use_alt_lcd_levels switches between different ACPI
  * brightness controls which are used by different Fujitsu laptops.  In most
@@ -65,7 +66,7 @@
 #include <linux/video_output.h>
 #include <linux/platform_device.h>
 
-#define FUJITSU_DRIVER_VERSION "0.4.2"
+#define FUJITSU_DRIVER_VERSION "0.4.3"
 
 #define FUJITSU_LCD_N_LEVELS 8
 
@@ -83,10 +84,10 @@
 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS     0x87
 
 /* Hotkey details */
-#define LOCK_KEY	0x410	/* codes for the keys in the GIRB register */
-#define DISPLAY_KEY	0x411	/* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */
-#define ENERGY_KEY	0x412	/* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */
-#define REST_KEY	0x413	/* KEY_SUSPEND (R key) */
+#define KEY1_CODE	0x410	/* codes for the keys in the GIRB register */
+#define KEY2_CODE	0x411
+#define KEY3_CODE	0x412
+#define KEY4_CODE	0x413
 
 #define MAX_HOTKEY_RINGBUFFER_SIZE 100
 #define RINGBUFFERSIZE 40
@@ -123,6 +124,7 @@ struct fujitsu_t {
 	char phys[32];
 	struct backlight_device *bl_device;
 	struct platform_device *pf_device;
+	int keycode1, keycode2, keycode3, keycode4;
 
 	unsigned int max_brightness;
 	unsigned int brightness_changed;
@@ -224,7 +226,7 @@ static int set_lcd_level_alt(int level)
 
 static int get_lcd_level(void)
 {
-	unsigned long state = 0;
+	unsigned long long state = 0;
 	acpi_status status = AE_OK;
 
 	vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");
@@ -246,7 +248,7 @@ static int get_lcd_level(void)
 
 static int get_max_brightness(void)
 {
-	unsigned long state = 0;
+	unsigned long long state = 0;
 	acpi_status status = AE_OK;
 
 	vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");
@@ -263,7 +265,7 @@ static int get_max_brightness(void)
 
 static int get_lcd_level_alt(void)
 {
-	unsigned long state = 0;
+	unsigned long long state = 0;
 	acpi_status status = AE_OK;
 
 	vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n");
@@ -384,7 +386,7 @@ static ssize_t store_lcd_level(struct device *dev,
 
 static int get_irb(void)
 {
-	unsigned long state = 0;
+	unsigned long long state = 0;
 	acpi_status status = AE_OK;
 
 	vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n");
@@ -430,7 +432,7 @@ static struct platform_driver fujitsupf_driver = {
 		   }
 };
 
-static int dmi_check_cb_s6410(const struct dmi_system_id *id)
+static void dmi_check_cb_common(const struct dmi_system_id *id)
 {
 	acpi_handle handle;
 	int have_blnf;
@@ -452,24 +454,40 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id)
 			    "auto-detecting disable_adjust\n");
 		disable_brightness_adjust = have_blnf ? 0 : 1;
 	}
+}
+
+static int dmi_check_cb_s6410(const struct dmi_system_id *id)
+{
+	dmi_check_cb_common(id);
+	fujitsu->keycode1 = KEY_SCREENLOCK;	/* "Lock" */
+	fujitsu->keycode2 = KEY_HELP;	/* "Mobility Center" */
+	return 0;
+}
+
+static int dmi_check_cb_p8010(const struct dmi_system_id *id)
+{
+	dmi_check_cb_common(id);
+	fujitsu->keycode1 = KEY_HELP;	/* "Support" */
+	fujitsu->keycode3 = KEY_SWITCHVIDEOMODE;	/* "Presentation" */
+	fujitsu->keycode4 = KEY_WWW;	/* "Internet" */
 	return 0;
 }
 
 static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
 	{
-	 .ident = "Fujitsu Siemens",
+	 .ident = "Fujitsu Siemens S6410",
 	 .matches = {
 		     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
 		     DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
 		     },
 	 .callback = dmi_check_cb_s6410},
 	{
-	 .ident = "FUJITSU LifeBook P8010",
+	 .ident = "Fujitsu LifeBook P8010",
 	 .matches = {
 		     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 		     DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"),
-		    },
-	 .callback = dmi_check_cb_s6410},
+		     },
+	 .callback = dmi_check_cb_p8010},
 	{}
 };
 
@@ -490,7 +508,7 @@ static int acpi_fujitsu_add(struct acpi_device *device)
 	fujitsu->acpi_handle = device->handle;
 	sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
 	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
-	acpi_driver_data(device) = fujitsu;
+	device->driver_data = fujitsu;
 
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_DEVICE_NOTIFY,
@@ -547,7 +565,6 @@ static int acpi_fujitsu_add(struct acpi_device *device)
 	}
 
 	/* do config (detect defaults) */
-	dmi_check_system(fujitsu_dmi_table);
 	use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0;
 	disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0;
 	disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0;
@@ -623,17 +640,17 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
 			keycode = 0;
 			if (disable_brightness_keys != 1) {
 				if (oldb == 0) {
-					acpi_bus_generate_proc_event(fujitsu->
-						dev,
-						ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
-						0);
+					acpi_bus_generate_proc_event
+					    (fujitsu->dev,
+					     ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
+					     0);
 					keycode = KEY_BRIGHTNESSDOWN;
 				} else if (oldb ==
 					   (fujitsu->max_brightness) - 1) {
-					acpi_bus_generate_proc_event(fujitsu->
-						dev,
-						ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
-						0);
+					acpi_bus_generate_proc_event
+					    (fujitsu->dev,
+					     ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
+					     0);
 					keycode = KEY_BRIGHTNESSUP;
 				}
 			}
@@ -646,8 +663,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
 			}
 			if (disable_brightness_keys != 1) {
 				acpi_bus_generate_proc_event(fujitsu->dev,
-					ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
-					0);
+					ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0);
 				keycode = KEY_BRIGHTNESSUP;
 			}
 		} else if (oldb > newb) {
@@ -659,8 +675,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
 			}
 			if (disable_brightness_keys != 1) {
 				acpi_bus_generate_proc_event(fujitsu->dev,
-					ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
-					0);
+					ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0);
 				keycode = KEY_BRIGHTNESSDOWN;
 			}
 		} else {
@@ -703,7 +718,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 	sprintf(acpi_device_name(device), "%s",
 		ACPI_FUJITSU_HOTKEY_DEVICE_NAME);
 	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
-	acpi_driver_data(device) = fujitsu_hotkey;
+	device->driver_data = fujitsu_hotkey;
 
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_DEVICE_NOTIFY,
@@ -742,10 +757,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 	input->id.product = 0x06;
 	input->dev.parent = &device->dev;
 	input->evbit[0] = BIT(EV_KEY);
-	set_bit(KEY_SCREENLOCK, input->keybit);
-	set_bit(KEY_MEDIA, input->keybit);
-	set_bit(KEY_EMAIL, input->keybit);
-	set_bit(KEY_SUSPEND, input->keybit);
+	set_bit(fujitsu->keycode1, input->keybit);
+	set_bit(fujitsu->keycode2, input->keybit);
+	set_bit(fujitsu->keycode3, input->keybit);
+	set_bit(fujitsu->keycode4, input->keybit);
 	set_bit(KEY_UNKNOWN, input->keybit);
 
 	error = input_register_device(input);
@@ -833,24 +848,24 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
 				    irb);
 
 			switch (irb & 0x4ff) {
-			case LOCK_KEY:
-				keycode = KEY_SCREENLOCK;
+			case KEY1_CODE:
+				keycode = fujitsu->keycode1;
 				break;
-			case DISPLAY_KEY:
-				keycode = KEY_MEDIA;
+			case KEY2_CODE:
+				keycode = fujitsu->keycode2;
 				break;
-			case ENERGY_KEY:
-				keycode = KEY_EMAIL;
+			case KEY3_CODE:
+				keycode = fujitsu->keycode3;
 				break;
-			case REST_KEY:
-				keycode = KEY_SUSPEND;
+			case KEY4_CODE:
+				keycode = fujitsu->keycode4;
 				break;
 			case 0:
 				keycode = 0;
 				break;
 			default:
 				vdbg_printk(FUJLAPTOP_DBG_WARN,
-					"Unknown GIRB result [%x]\n", irb);
+					    "Unknown GIRB result [%x]\n", irb);
 				keycode = -1;
 				break;
 			}
@@ -859,12 +874,12 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
 					"Push keycode into ringbuffer [%d]\n",
 					keycode);
 				status = kfifo_put(fujitsu_hotkey->fifo,
-						(unsigned char *)&keycode,
-						sizeof(keycode));
+						   (unsigned char *)&keycode,
+						   sizeof(keycode));
 				if (status != sizeof(keycode)) {
 					vdbg_printk(FUJLAPTOP_DBG_WARN,
-						"Could not push keycode [0x%x]\n",
-						keycode);
+					    "Could not push keycode [0x%x]\n",
+					    keycode);
 				} else {
 					input_report_key(input, keycode, 1);
 					input_sync(input);
@@ -879,8 +894,8 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
 					input_report_key(input, keycode_r, 0);
 					input_sync(input);
 					vdbg_printk(FUJLAPTOP_DBG_TRACE,
-						    "Pop keycode from ringbuffer [%d]\n",
-						    keycode_r);
+					  "Pop keycode from ringbuffer [%d]\n",
+					  keycode_r);
 				}
 			}
 		}
@@ -943,6 +958,11 @@ static int __init fujitsu_init(void)
 	if (!fujitsu)
 		return -ENOMEM;
 	memset(fujitsu, 0, sizeof(struct fujitsu_t));
+	fujitsu->keycode1 = KEY_PROG1;
+	fujitsu->keycode2 = KEY_PROG2;
+	fujitsu->keycode3 = KEY_PROG3;
+	fujitsu->keycode4 = KEY_PROG4;
+	dmi_check_system(fujitsu_dmi_table);
 
 	result = acpi_bus_register_driver(&acpi_fujitsu_driver);
 	if (result < 0) {
@@ -1076,15 +1096,14 @@ MODULE_DESCRIPTION("Fujitsu laptop extras support");
 MODULE_VERSION(FUJITSU_DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
-MODULE_ALIAS
-    ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
-MODULE_ALIAS
-    ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
+MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
+MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
 
 static struct pnp_device_id pnp_ids[] = {
-	{ .id = "FUJ02bf" },
-	{ .id = "FUJ02B1" },
-	{ .id = "FUJ02E3" },
-	{ .id = "" }
+	{.id = "FUJ02bf"},
+	{.id = "FUJ02B1"},
+	{.id = "FUJ02E3"},
+	{.id = ""}
 };
+
 MODULE_DEVICE_TABLE(pnp, pnp_ids);
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c
index 80a136352408..e00a2756e97e 100644
--- a/drivers/misc/intel_menlow.c
+++ b/drivers/misc/intel_menlow.c
@@ -57,7 +57,7 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
-	unsigned long value;
+	unsigned long long value;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 	acpi_status status = AE_OK;
@@ -90,7 +90,7 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
-	unsigned long value;
+	unsigned long long value;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 	acpi_status status = AE_OK;
@@ -104,7 +104,7 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
-	return sprintf(buf, "%ld\n", value);
+	return sprintf(buf, "%llu\n", value);
 }
 
 static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
@@ -115,7 +115,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 	acpi_status status;
-	int temp;
+	unsigned long long temp;
 	unsigned long max_state;
 
 	if (memory_get_int_max_bandwidth(cdev, &max_state))
@@ -131,7 +131,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
 
 	status =
 	    acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list,
-				  (unsigned long *)&temp);
+				  &temp);
 
 	printk(KERN_INFO
 	       "Bandwidth value was %d: status is %d\n", state, status);
@@ -175,7 +175,7 @@ static int intel_menlow_memory_add(struct acpi_device *device)
 		goto end;
 	}
 
-	acpi_driver_data(device) = cdev;
+	device->driver_data = cdev;
 	result = sysfs_create_link(&device->dev.kobj,
 				&cdev->device.kobj, "thermal_cooling");
 	if (result)
@@ -252,7 +252,8 @@ static DEFINE_MUTEX(intel_menlow_attr_lock);
  * @auxtype : AUX0/AUX1
  * @buf: syfs buffer
  */
-static int sensor_get_auxtrip(acpi_handle handle, int index, int *value)
+static int sensor_get_auxtrip(acpi_handle handle, int index,
+							unsigned long long *value)
 {
 	acpi_status status;
 
@@ -260,7 +261,7 @@ static int sensor_get_auxtrip(acpi_handle handle, int index, int *value)
 		return -EINVAL;
 
 	status = acpi_evaluate_integer(handle, index ? GET_AUX1 : GET_AUX0,
-				       NULL, (unsigned long *)value);
+				       NULL, value);
 	if (ACPI_FAILURE(status))
 		return -EIO;
 
@@ -282,13 +283,13 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value)
 	struct acpi_object_list args = {
 		1, &arg
 	};
-	int temp;
+	unsigned long long temp;
 
 	if (index != 0 && index != 1)
 		return -EINVAL;
 
 	status = acpi_evaluate_integer(handle, index ? GET_AUX0 : GET_AUX1,
-				       NULL, (unsigned long *)&temp);
+				       NULL, &temp);
 	if (ACPI_FAILURE(status))
 		return -EIO;
 	if ((index && value < temp) || (!index && value > temp))
@@ -296,7 +297,7 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value)
 
 	arg.integer.value = value;
 	status = acpi_evaluate_integer(handle, index ? SET_AUX1 : SET_AUX0,
-				       &args, (unsigned long *)&temp);
+				       &args, &temp);
 	if (ACPI_FAILURE(status))
 		return -EIO;
 
@@ -312,7 +313,7 @@ static ssize_t aux0_show(struct device *dev,
 			 struct device_attribute *dev_attr, char *buf)
 {
 	struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
-	int value;
+	unsigned long long value;
 	int result;
 
 	result = sensor_get_auxtrip(attr->handle, 0, &value);
@@ -324,7 +325,7 @@ static ssize_t aux1_show(struct device *dev,
 			 struct device_attribute *dev_attr, char *buf)
 {
 	struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
-	int value;
+	unsigned long long value;
 	int result;
 
 	result = sensor_get_auxtrip(attr->handle, 1, &value);
@@ -376,7 +377,7 @@ static ssize_t bios_enabled_show(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
 	acpi_status status;
-	unsigned long bios_enabled;
+	unsigned long long bios_enabled;
 
 	status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &bios_enabled);
 	if (ACPI_FAILURE(status))
@@ -492,7 +493,7 @@ static int __init intel_menlow_module_init(void)
 {
 	int result = -ENODEV;
 	acpi_status status;
-	unsigned long enable;
+	unsigned long long enable;
 
 	if (acpi_disabled)
 		return result;
diff --git a/drivers/misc/panasonic-laptop.c b/drivers/misc/panasonic-laptop.c
new file mode 100644
index 000000000000..a2cb598d8ab5
--- /dev/null
+++ b/drivers/misc/panasonic-laptop.c
@@ -0,0 +1,767 @@
+/*
+ *  Panasonic HotKey and LCD brightness control driver
+ *  (C) 2004 Hiroshi Miura <miura@da-cha.org>
+ *  (C) 2004 NTT DATA Intellilink Co. http://www.intellilink.co.jp/
+ *  (C) YOKOTA Hiroshi <yokota (at) netlab. is. tsukuba. ac. jp>
+ *  (C) 2004 David Bronaugh <dbronaugh>
+ *  (C) 2006-2008 Harald Welte <laforge@gnumonks.org>
+ *
+ *  derived from toshiba_acpi.c, Copyright (C) 2002-2004 John Belmonte
+ *
+ *  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
+ *  publicshed by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ *---------------------------------------------------------------------------
+ *
+ * ChangeLog:
+ *	Sep.23, 2008	Harald Welte <laforge@gnumonks.org>
+ *		-v0.95	rename driver from drivers/acpi/pcc_acpi.c to
+ *			drivers/misc/panasonic-laptop.c
+ *
+ * 	Jul.04, 2008	Harald Welte <laforge@gnumonks.org>
+ * 		-v0.94	replace /proc interface with device attributes
+ * 			support {set,get}keycode on th input device
+ *
+ *      Jun.27, 2008	Harald Welte <laforge@gnumonks.org>
+ *      	-v0.92	merge with 2.6.26-rc6 input API changes
+ *      		remove broken <= 2.6.15 kernel support
+ *      		resolve all compiler warnings
+ *      		various coding style fixes (checkpatch.pl)
+ *      		add support for backlight api
+ *      		major code restructuring
+ *
+ * 	Dac.28, 2007	Harald Welte <laforge@gnumonks.org>
+ * 		-v0.91	merge with 2.6.24-rc6 ACPI changes
+ *
+ * 	Nov.04, 2006	Hiroshi Miura <miura@da-cha.org>
+ * 		-v0.9	remove warning about section reference.
+ * 			remove acpi_os_free
+ * 			add /proc/acpi/pcc/brightness interface for HAL access
+ * 			merge dbronaugh's enhancement
+ * 			Aug.17, 2004 David Bronaugh (dbronaugh)
+ *  				- Added screen brightness setting interface
+ *				  Thanks to FreeBSD crew (acpi_panasonic.c)
+ * 				  for the ideas I needed to accomplish it
+ *
+ *	May.29, 2006	Hiroshi Miura <miura@da-cha.org>
+ *		-v0.8.4 follow to change keyinput structure
+ *			thanks Fabian Yamaguchi <fabs@cs.tu-berlin.de>,
+ *			Jacob Bower <jacob.bower@ic.ac.uk> and
+ *			Hiroshi Yokota for providing solutions.
+ *
+ *	Oct.02, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		-v0.8.2	merge code of YOKOTA Hiroshi
+ *					<yokota@netlab.is.tsukuba.ac.jp>.
+ *			Add sticky key mode interface.
+ *			Refactoring acpi_pcc_generate_keyinput().
+ *
+ *	Sep.15, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		-v0.8	Generate key input event on input subsystem.
+ *			This is based on yet another driver written by
+ *							Ryuta Nakanishi.
+ *
+ *	Sep.10, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		-v0.7	Change proc interface functions using seq_file
+ *			facility as same as other ACPI drivers.
+ *
+ *	Aug.28, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		-v0.6.4 Fix a silly error with status checking
+ *
+ *	Aug.25, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		-v0.6.3 replace read_acpi_int by standard function
+ *							acpi_evaluate_integer
+ *			some clean up and make smart copyright notice.
+ *			fix return value of pcc_acpi_get_key()
+ *			fix checking return value of acpi_bus_register_driver()
+ *
+ *      Aug.22, 2004    David Bronaugh <dbronaugh@linuxboxen.org>
+ *              -v0.6.2 Add check on ACPI data (num_sifr)
+ *                      Coding style cleanups, better error messages/handling
+ *			Fixed an off-by-one error in memory allocation
+ *
+ *      Aug.21, 2004    David Bronaugh <dbronaugh@linuxboxen.org>
+ *              -v0.6.1 Fix a silly error with status checking
+ *
+ *      Aug.20, 2004    David Bronaugh <dbronaugh@linuxboxen.org>
+ *              - v0.6  Correct brightness controls to reflect reality
+ *                      based on information gleaned by Hiroshi Miura
+ *                      and discussions with Hiroshi Miura
+ *
+ *	Aug.10, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		- v0.5  support LCD brightness control
+ *			based on the disclosed information by MEI.
+ *
+ *	Jul.25, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		- v0.4  first post version
+ *		        add function to retrive SIFR
+ *
+ *	Jul.24, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		- v0.3  get proper status of hotkey
+ *
+ *      Jul.22, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		- v0.2  add HotKey handler
+ *
+ *      Jul.17, 2004	Hiroshi Miura <miura@da-cha.org>
+ *		- v0.1  start from toshiba_acpi driver written by John Belmonte
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/backlight.h>
+#include <linux/ctype.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/input.h>
+
+
+#ifndef ACPI_HOTKEY_COMPONENT
+#define ACPI_HOTKEY_COMPONENT	0x10000000
+#endif
+
+#define _COMPONENT		ACPI_HOTKEY_COMPONENT
+
+MODULE_AUTHOR("Hiroshi Miura, David Bronaugh and Harald Welte");
+MODULE_DESCRIPTION("ACPI HotKey driver for Panasonic Let's Note laptops");
+MODULE_LICENSE("GPL");
+
+#define LOGPREFIX "pcc_acpi: "
+
+/* Define ACPI PATHs */
+/* Lets note hotkeys */
+#define METHOD_HKEY_QUERY	"HINF"
+#define METHOD_HKEY_SQTY	"SQTY"
+#define METHOD_HKEY_SINF	"SINF"
+#define METHOD_HKEY_SSET	"SSET"
+#define HKEY_NOTIFY		 0x80
+
+#define ACPI_PCC_DRIVER_NAME	"Panasonic Laptop Support"
+#define ACPI_PCC_DEVICE_NAME	"Hotkey"
+#define ACPI_PCC_CLASS		"pcc"
+
+#define ACPI_PCC_INPUT_PHYS	"panasonic/hkey0"
+
+/* LCD_TYPEs: 0 = Normal, 1 = Semi-transparent
+   ENV_STATEs: Normal temp=0x01, High temp=0x81, N/A=0x00
+*/
+enum SINF_BITS { SINF_NUM_BATTERIES = 0,
+		 SINF_LCD_TYPE,
+		 SINF_AC_MAX_BRIGHT,
+		 SINF_AC_MIN_BRIGHT,
+		 SINF_AC_CUR_BRIGHT,
+		 SINF_DC_MAX_BRIGHT,
+		 SINF_DC_MIN_BRIGHT,
+		 SINF_DC_CUR_BRIGHT,
+		 SINF_MUTE,
+		 SINF_RESERVED,
+		 SINF_ENV_STATE,
+		 SINF_STICKY_KEY = 0x80,
+	};
+/* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */
+
+static int acpi_pcc_hotkey_add(struct acpi_device *device);
+static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
+static int acpi_pcc_hotkey_resume(struct acpi_device *device);
+
+static const struct acpi_device_id pcc_device_ids[] = {
+	{ "MAT0012", 0},
+	{ "MAT0013", 0},
+	{ "MAT0018", 0},
+	{ "MAT0019", 0},
+	{ "", 0},
+};
+
+static struct acpi_driver acpi_pcc_driver = {
+	.name =		ACPI_PCC_DRIVER_NAME,
+	.class =	ACPI_PCC_CLASS,
+	.ids =		pcc_device_ids,
+	.ops =		{
+				.add =		acpi_pcc_hotkey_add,
+				.remove =	acpi_pcc_hotkey_remove,
+				.resume =       acpi_pcc_hotkey_resume,
+			},
+};
+
+#define KEYMAP_SIZE		11
+static const int initial_keymap[KEYMAP_SIZE] = {
+	/*  0 */ KEY_RESERVED,
+	/*  1 */ KEY_BRIGHTNESSDOWN,
+	/*  2 */ KEY_BRIGHTNESSUP,
+	/*  3 */ KEY_DISPLAYTOGGLE,
+	/*  4 */ KEY_MUTE,
+	/*  5 */ KEY_VOLUMEDOWN,
+	/*  6 */ KEY_VOLUMEUP,
+	/*  7 */ KEY_SLEEP,
+	/*  8 */ KEY_PROG1, /* Change CPU boost */
+	/*  9 */ KEY_BATTERY,
+	/* 10 */ KEY_SUSPEND,
+};
+
+struct pcc_acpi {
+	acpi_handle		handle;
+	unsigned long		num_sifr;
+	int			sticky_mode;
+	u32 			*sinf;
+	struct acpi_device	*device;
+	struct input_dev	*input_dev;
+	struct backlight_device	*backlight;
+	int			keymap[KEYMAP_SIZE];
+};
+
+struct pcc_keyinput {
+	struct acpi_hotkey      *hotkey;
+};
+
+/* method access functions */
+static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val)
+{
+	union acpi_object in_objs[] = {
+		{ .integer.type  = ACPI_TYPE_INTEGER,
+		  .integer.value = func, },
+		{ .integer.type  = ACPI_TYPE_INTEGER,
+		  .integer.value = val, },
+	};
+	struct acpi_object_list params = {
+		.count   = ARRAY_SIZE(in_objs),
+		.pointer = in_objs,
+	};
+	acpi_status status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_write_sset");
+
+	status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SSET,
+				      &params, NULL);
+
+	return status == AE_OK;
+}
+
+static inline int acpi_pcc_get_sqty(struct acpi_device *device)
+{
+	unsigned long long s;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_get_sqty");
+
+	status = acpi_evaluate_integer(device->handle, METHOD_HKEY_SQTY,
+				       NULL, &s);
+	if (ACPI_SUCCESS(status))
+		return s;
+	else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "evaluation error HKEY.SQTY\n"));
+		return -EINVAL;
+	}
+}
+
+static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *hkey = NULL;
+	int i;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_retrieve_biosdata");
+
+	status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0,
+				      &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "evaluation error HKEY.SINF\n"));
+		return 0;
+	}
+
+	hkey = buffer.pointer;
+	if (!hkey || (hkey->type != ACPI_TYPE_PACKAGE)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF\n"));
+		goto end;
+	}
+
+	if (pcc->num_sifr < hkey->package.count) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				 "SQTY reports bad SINF length\n"));
+		status = AE_ERROR;
+		goto end;
+	}
+
+	for (i = 0; i < hkey->package.count; i++) {
+		union acpi_object *element = &(hkey->package.elements[i]);
+		if (likely(element->type == ACPI_TYPE_INTEGER)) {
+			sinf[i] = element->integer.value;
+		} else
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					 "Invalid HKEY.SINF data\n"));
+	}
+	sinf[hkey->package.count] = -1;
+
+end:
+	kfree(buffer.pointer);
+	return status == AE_OK;
+}
+
+/* backlight API interface functions */
+
+/* This driver currently treats AC and DC brightness identical,
+ * since we don't need to invent an interface to the core ACPI
+ * logic to receive events in case a power supply is plugged in
+ * or removed */
+
+static int bl_get(struct backlight_device *bd)
+{
+	struct pcc_acpi *pcc = bl_get_data(bd);
+
+	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+		return -EIO;
+
+	return pcc->sinf[SINF_AC_CUR_BRIGHT];
+}
+
+static int bl_set_status(struct backlight_device *bd)
+{
+	struct pcc_acpi *pcc = bl_get_data(bd);
+	int bright = bd->props.brightness;
+	int rc;
+
+	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+		return -EIO;
+
+	if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT])
+		bright = pcc->sinf[SINF_AC_MIN_BRIGHT];
+
+	if (bright < pcc->sinf[SINF_DC_MIN_BRIGHT])
+		bright = pcc->sinf[SINF_DC_MIN_BRIGHT];
+
+	if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT] ||
+	    bright > pcc->sinf[SINF_AC_MAX_BRIGHT])
+		return -EINVAL;
+
+	rc = acpi_pcc_write_sset(pcc, SINF_AC_CUR_BRIGHT, bright);
+	if (rc < 0)
+		return rc;
+
+	return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
+}
+
+static struct backlight_ops pcc_backlight_ops = {
+	.get_brightness	= bl_get,
+	.update_status	= bl_set_status,
+};
+
+
+/* sysfs user interface functions */
+
+static ssize_t show_numbatt(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct acpi_device *acpi = to_acpi_device(dev);
+	struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+		return -EIO;
+
+	return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
+}
+
+static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct acpi_device *acpi = to_acpi_device(dev);
+	struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+		return -EIO;
+
+	return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
+}
+
+static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct acpi_device *acpi = to_acpi_device(dev);
+	struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+		return -EIO;
+
+	return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]);
+}
+
+static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct acpi_device *acpi = to_acpi_device(dev);
+	struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
+		return -EIO;
+
+	return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
+}
+
+static ssize_t set_sticky(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct acpi_device *acpi = to_acpi_device(dev);
+	struct pcc_acpi *pcc = acpi_driver_data(acpi);
+	int val;
+
+	if (count && sscanf(buf, "%i", &val) == 1 &&
+	    (val == 0 || val == 1)) {
+		acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, val);
+		pcc->sticky_mode = val;
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(numbatt, S_IRUGO, show_numbatt, NULL);
+static DEVICE_ATTR(lcdtype, S_IRUGO, show_lcdtype, NULL);
+static DEVICE_ATTR(mute, S_IRUGO, show_mute, NULL);
+static DEVICE_ATTR(sticky_key, S_IRUGO | S_IWUSR, show_sticky, set_sticky);
+
+static struct attribute *pcc_sysfs_entries[] = {
+	&dev_attr_numbatt.attr,
+	&dev_attr_lcdtype.attr,
+	&dev_attr_mute.attr,
+	&dev_attr_sticky_key.attr,
+	NULL,
+};
+
+static struct attribute_group pcc_attr_group = {
+	.name	= NULL,		/* put in device directory */
+	.attrs	= pcc_sysfs_entries,
+};
+
+
+/* hotkey input device driver */
+
+static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+	struct pcc_acpi *pcc = input_get_drvdata(dev);
+
+	if (scancode >= ARRAY_SIZE(pcc->keymap))
+		return -EINVAL;
+
+	*keycode = pcc->keymap[scancode];
+
+	return 0;
+}
+
+static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++) {
+		if (pcc->keymap[i] == keycode)
+			return i+1;
+	}
+
+	return 0;
+}
+
+static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+	struct pcc_acpi *pcc = input_get_drvdata(dev);
+	int oldkeycode;
+
+	if (scancode >= ARRAY_SIZE(pcc->keymap))
+		return -EINVAL;
+
+	if (keycode < 0 || keycode > KEY_MAX)
+		return -EINVAL;
+
+	oldkeycode = pcc->keymap[scancode];
+	pcc->keymap[scancode] = keycode;
+
+	set_bit(keycode, dev->keybit);
+
+	if (!keymap_get_by_keycode(pcc, oldkeycode))
+		clear_bit(oldkeycode, dev->keybit);
+
+	return 0;
+}
+
+static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
+{
+	struct input_dev *hotk_input_dev = pcc->input_dev;
+	int rc;
+	int key_code, hkey_num;
+	unsigned long long result;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_generate_keyinput");
+
+	rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY,
+				   NULL, &result);
+	if (!ACPI_SUCCESS(rc)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				 "error getting hotkey status\n"));
+		return;
+	}
+
+	acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result);
+
+	hkey_num = result & 0xf;
+
+	if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "hotkey number out of range: %d\n",
+				  hkey_num));
+		return;
+	}
+
+	key_code = pcc->keymap[hkey_num];
+
+	if (key_code != KEY_RESERVED) {
+		int pushed = (result & 0x80) ? TRUE : FALSE;
+
+		input_report_key(hotk_input_dev, key_code, pushed);
+		input_sync(hotk_input_dev);
+	}
+
+	return;
+}
+
+static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct pcc_acpi *pcc = (struct pcc_acpi *) data;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_notify");
+
+	switch (event) {
+	case HKEY_NOTIFY:
+		acpi_pcc_generate_keyinput(pcc);
+		break;
+	default:
+		/* nothing to do */
+		break;
+	}
+}
+
+static int acpi_pcc_init_input(struct pcc_acpi *pcc)
+{
+	int i, rc;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_init_input");
+
+	pcc->input_dev = input_allocate_device();
+	if (!pcc->input_dev) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Couldn't allocate input device for hotkey"));
+		return -ENOMEM;
+	}
+
+	pcc->input_dev->evbit[0] = BIT(EV_KEY);
+
+	pcc->input_dev->name = ACPI_PCC_DRIVER_NAME;
+	pcc->input_dev->phys = ACPI_PCC_INPUT_PHYS;
+	pcc->input_dev->id.bustype = BUS_HOST;
+	pcc->input_dev->id.vendor = 0x0001;
+	pcc->input_dev->id.product = 0x0001;
+	pcc->input_dev->id.version = 0x0100;
+	pcc->input_dev->getkeycode = pcc_getkeycode;
+	pcc->input_dev->setkeycode = pcc_setkeycode;
+
+	/* load initial keymap */
+	memcpy(pcc->keymap, initial_keymap, sizeof(pcc->keymap));
+
+	for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++)
+		__set_bit(pcc->keymap[i], pcc->input_dev->keybit);
+	__clear_bit(KEY_RESERVED, pcc->input_dev->keybit);
+
+	input_set_drvdata(pcc->input_dev, pcc);
+
+	rc = input_register_device(pcc->input_dev);
+	if (rc < 0)
+		input_free_device(pcc->input_dev);
+
+	return rc;
+}
+
+/* kernel module interface */
+
+static int acpi_pcc_hotkey_resume(struct acpi_device *device)
+{
+	struct pcc_acpi *pcc = acpi_driver_data(device);
+	acpi_status status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_resume");
+
+	if (device == NULL || pcc == NULL)
+		return -EINVAL;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Sticky mode restore: %d\n",
+			  pcc->sticky_mode));
+
+	status = acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode);
+
+	return status == AE_OK ? 0 : -EINVAL;
+}
+
+static int acpi_pcc_hotkey_add(struct acpi_device *device)
+{
+	acpi_status status;
+	struct pcc_acpi *pcc;
+	int num_sifr, result;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_add");
+
+	if (!device)
+		return -EINVAL;
+
+	num_sifr = acpi_pcc_get_sqty(device);
+
+	if (num_sifr > 255) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large"));
+		return -ENODEV;
+	}
+
+	pcc = kzalloc(sizeof(struct pcc_acpi), GFP_KERNEL);
+	if (!pcc) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Couldn't allocate mem for pcc"));
+		return -ENOMEM;
+	}
+
+	pcc->sinf = kzalloc(sizeof(u32) * (num_sifr + 1), GFP_KERNEL);
+	if (!pcc->sinf) {
+		result = -ENOMEM;
+		goto out_hotkey;
+	}
+
+	pcc->device = device;
+	pcc->handle = device->handle;
+	pcc->num_sifr = num_sifr;
+	device->driver_data = pcc;
+	strcpy(acpi_device_name(device), ACPI_PCC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PCC_CLASS);
+
+	result = acpi_pcc_init_input(pcc);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Error installing keyinput handler\n"));
+		goto out_sinf;
+	}
+
+	/* initialize hotkey input device */
+	status = acpi_install_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
+					     acpi_pcc_hotkey_notify, pcc);
+
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Error installing notify handler\n"));
+		result = -ENODEV;
+		goto out_input;
+	}
+
+	/* initialize backlight */
+	pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
+						   &pcc_backlight_ops);
+	if (IS_ERR(pcc->backlight))
+		goto out_notify;
+
+	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				 "Couldn't retrieve BIOS data\n"));
+		goto out_backlight;
+	}
+
+	/* read the initial brightness setting from the hardware */
+	pcc->backlight->props.max_brightness =
+					pcc->sinf[SINF_AC_MAX_BRIGHT];
+	pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT];
+
+	/* read the initial sticky key mode from the hardware */
+	pcc->sticky_mode = pcc->sinf[SINF_STICKY_KEY];
+
+	/* add sysfs attributes */
+	result = sysfs_create_group(&device->dev.kobj, &pcc_attr_group);
+	if (result)
+		goto out_backlight;
+
+	return 0;
+
+out_backlight:
+	backlight_device_unregister(pcc->backlight);
+out_notify:
+	acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
+				   acpi_pcc_hotkey_notify);
+out_input:
+	input_unregister_device(pcc->input_dev);
+	/* no need to input_free_device() since core input API refcount and
+	 * free()s the device */
+out_sinf:
+	kfree(pcc->sinf);
+out_hotkey:
+	kfree(pcc);
+
+	return result;
+}
+
+static int __init acpi_pcc_init(void)
+{
+	int result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_init");
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	result = acpi_bus_register_driver(&acpi_pcc_driver);
+	if (result < 0) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Error registering hotkey driver\n"));
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
+{
+	struct pcc_acpi *pcc = acpi_driver_data(device);
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_remove");
+
+	if (!device || !pcc)
+		return -EINVAL;
+
+	sysfs_remove_group(&device->dev.kobj, &pcc_attr_group);
+
+	backlight_device_unregister(pcc->backlight);
+
+	acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
+				   acpi_pcc_hotkey_notify);
+
+	input_unregister_device(pcc->input_dev);
+	/* no need to input_free_device() since core input API refcount and
+	 * free()s the device */
+
+	kfree(pcc->sinf);
+	kfree(pcc);
+
+	return 0;
+}
+
+static void __exit acpi_pcc_exit(void)
+{
+	ACPI_FUNCTION_TRACE("acpi_pcc_exit");
+
+	acpi_bus_unregister_driver(&acpi_pcc_driver);
+}
+
+module_init(acpi_pcc_init);
+module_exit(acpi_pcc_exit);
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 60775be22822..5a97d3a9d745 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -970,7 +970,7 @@ static int sony_nc_resume(struct acpi_device *device)
 	/* set the last requested brightness level */
 	if (sony_backlight_device &&
 			!sony_backlight_update_status(sony_backlight_device))
-		printk(KERN_WARNING DRV_PFX "unable to restore brightness level");
+		printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
 
 	/* re-initialize models with specific requirements */
 	dmi_check_system(sony_nc_ids);
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 6b9300779a43..4db1cf9078d9 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -159,7 +159,6 @@ enum {
 #define TPACPI_DEBUG  KERN_DEBUG  TPACPI_LOG
 
 #define TPACPI_DBG_ALL		0xffff
-#define TPACPI_DBG_ALL		0xffff
 #define TPACPI_DBG_INIT		0x0001
 #define TPACPI_DBG_EXIT		0x0002
 #define dbg_printk(a_dbg_level, format, arg...) \
@@ -543,7 +542,7 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm)
 		return -ENODEV;
 	}
 
-	acpi_driver_data(ibm->acpi->device) = ibm;
+	ibm->acpi->device->driver_data = ibm;
 	sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",
 		TPACPI_ACPI_EVENT_PREFIX,
 		ibm->name);
@@ -582,7 +581,8 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 
 	ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
 	if (!ibm->acpi->driver) {
-		printk(TPACPI_ERR "kzalloc(ibm->driver) failed\n");
+		printk(TPACPI_ERR
+		       "failed to allocate memory for ibm->acpi->driver\n");
 		return -ENOMEM;
 	}
 
@@ -838,6 +838,13 @@ static int parse_strtoul(const char *buf,
 	return 0;
 }
 
+static void tpacpi_disable_brightness_delay(void)
+{
+	if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0))
+		printk(TPACPI_NOTICE
+			"ACPI backlight control delay disabled\n");
+}
+
 static int __init tpacpi_query_bcl_levels(acpi_handle handle)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -2139,6 +2146,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 	if (!tp_features.hotkey)
 		return 1;
 
+	tpacpi_disable_brightness_delay();
+
 	hotkey_dev_attributes = create_attr_set(13, NULL);
 	if (!hotkey_dev_attributes)
 		return -ENOMEM;
@@ -2512,6 +2521,8 @@ static void hotkey_suspend(pm_message_t state)
 
 static void hotkey_resume(void)
 {
+	tpacpi_disable_brightness_delay();
+
 	if (hotkey_mask_get())
 		printk(TPACPI_ERR
 		       "error while trying to read hot key mask "
@@ -5983,6 +5994,52 @@ static void fan_exit(void)
 	flush_workqueue(tpacpi_wq);
 }
 
+static void fan_suspend(pm_message_t state)
+{
+	if (!fan_control_allowed)
+		return;
+
+	/* Store fan status in cache */
+	fan_get_status_safe(NULL);
+	if (tp_features.fan_ctrl_status_undef)
+		fan_control_desired_level = TP_EC_FAN_AUTO;
+}
+
+static void fan_resume(void)
+{
+	u8 saved_fan_level;
+	u8 current_level = 7;
+	bool do_set = false;
+
+	/* DSDT *always* updates status on resume */
+	tp_features.fan_ctrl_status_undef = 0;
+
+	saved_fan_level = fan_control_desired_level;
+	if (!fan_control_allowed ||
+	    (fan_get_status_safe(&current_level) < 0))
+		return;
+
+	switch (fan_control_access_mode) {
+	case TPACPI_FAN_WR_ACPI_SFAN:
+		do_set = (saved_fan_level > current_level);
+		break;
+	case TPACPI_FAN_WR_ACPI_FANS:
+	case TPACPI_FAN_WR_TPEC:
+		do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) ||
+			  (saved_fan_level == 7 &&
+			   !(current_level & TP_EC_FAN_FULLSPEED)));
+		break;
+	default:
+		return;
+	}
+	if (do_set) {
+		printk(TPACPI_NOTICE
+			"restoring fan level to 0x%02x\n",
+			saved_fan_level);
+		fan_set_level_safe(saved_fan_level);
+	}
+}
+
 static int fan_read(char *p)
 {
 	int len = 0;
@@ -6174,6 +6231,8 @@ static struct ibm_struct fan_driver_data = {
 	.read = fan_read,
 	.write = fan_write,
 	.exit = fan_exit,
+	.suspend = fan_suspend,
+	.resume = fan_resume,
 };
 
 /****************************************************************************
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index a3e4705dd8f0..955aae4071f7 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -169,7 +169,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
 }
 
 
-
+static struct acpi_dock_ops acpiphp_dock_ops = {
+	.handler = handle_hotplug_event_func,
+};
 
 /* callback routine to register each ACPI PCI slot object */
 static acpi_status
@@ -180,7 +182,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 	struct acpiphp_func *newfunc;
 	acpi_handle tmp;
 	acpi_status status = AE_OK;
-	unsigned long adr, sun;
+	unsigned long long adr, sun;
 	int device, function, retval;
 
 	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
@@ -285,7 +287,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 		 */
 		newfunc->flags &= ~FUNC_HAS_EJ0;
 		if (register_hotplug_dock_device(handle,
-			handle_hotplug_event_func, newfunc))
+			&acpiphp_dock_ops, newfunc))
 			dbg("failed to register dock device\n");
 
 		/* we need to be notified when dock events happen
@@ -528,7 +530,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
 	acpi_status status;
 	acpi_handle dummy_handle;
-	unsigned long tmp;
+	unsigned long long tmp;
 	int device, function;
 	struct pci_dev *dev;
 	struct pci_bus *pci_bus = context;
@@ -573,7 +575,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 static int add_bridge(acpi_handle handle)
 {
 	acpi_status status;
-	unsigned long tmp;
+	unsigned long long tmp;
 	int seg, bus;
 	acpi_handle dummy_handle;
 	struct pci_bus *pci_bus;
@@ -767,7 +769,7 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
 {
 	acpi_status status;
 	int result = -1;
-	unsigned long gsb;
+	unsigned long long gsb;
 	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 	union acpi_object *obj;
 	void *table;
@@ -808,7 +810,7 @@ static acpi_status
 ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
 	acpi_status status;
-	unsigned long sta;
+	unsigned long long sta;
 	acpi_handle tmp;
 	struct pci_dev *pdev;
 	u32 gsi_base;
@@ -872,7 +874,7 @@ static acpi_status
 ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
 	acpi_status status;
-	unsigned long sta;
+	unsigned long long sta;
 	acpi_handle tmp;
 	u32 gsi_base;
 	struct acpiphp_ioapic *pos, *n, *ioapic = NULL;
@@ -1264,7 +1266,7 @@ static int disable_device(struct acpiphp_slot *slot)
 static unsigned int get_slot_status(struct acpiphp_slot *slot)
 {
 	acpi_status status;
-	unsigned long sta = 0;
+	unsigned long long sta = 0;
 	u32 dvid;
 	struct list_head *l;
 	struct acpiphp_func *func;
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 2b7c45e39370..b291ee68b4f1 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -183,7 +183,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
 	union acpi_object args[2]; 
 	struct acpi_object_list params = { .pointer = args, .count = 2 };
 	acpi_status stat; 
-	unsigned long rc;
+	unsigned long long rc;
 	union apci_descriptor *ibm_slot;
 
 	ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index d748698e31a2..3eee70928d45 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -413,7 +413,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
 	/*
 	 * Add the slot's devices to the ACPI infrastructure */
 	if (SN_ACPI_BASE_SUPPORT() && ssdt) {
-		unsigned long adr;
+		unsigned long long adr;
 		struct acpi_device *pdevice;
 		struct acpi_device *device;
 		acpi_handle phandle;
@@ -505,7 +505,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
 	/* free the ACPI resources for the slot */
 	if (SN_ACPI_BASE_SUPPORT() &&
             PCI_CONTROLLER(slot->pci_bus)->acpi_handle) {
-		unsigned long adr;
+		unsigned long long adr;
 		struct acpi_device *device;
 		acpi_handle phandle;
 		acpi_handle chandle = NULL;
diff --git a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
index 821933f9aa57..2a37b3fedb8e 100644
--- a/drivers/pnp/Kconfig
+++ b/drivers/pnp/Kconfig
@@ -20,13 +20,21 @@ menuconfig PNP
 
 	  If unsure, say Y.
 
-if PNP
-
-config PNP_DEBUG
-	bool "PnP Debug Messages"
+config PNP_DEBUG_MESSAGES
+	default y
+	bool "PNP debugging messages"
+	depends on PNP
 	help
-	  Say Y if you want the Plug and Play Layer to print debug messages.
-	  This is useful if you are developing a PnP driver or troubleshooting.
+	  Say Y here if you want the PNP layer to be able to produce debugging
+	  messages if needed.  The messages can be enabled at boot-time with
+	  the pnp.debug kernel parameter.
+
+	  This option allows you to save a bit of space if you do not want
+	  the messages to even be built into the kernel.
+
+	  If you have any doubts about this, say Y here.
+
+if PNP
 
 comment "Protocols"
 
diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile
index e83f34f1b5ba..8de3775ec242 100644
--- a/drivers/pnp/Makefile
+++ b/drivers/pnp/Makefile
@@ -10,7 +10,3 @@ obj-$(CONFIG_ISAPNP)		+= isapnp/
 
 # pnp_system_init goes after pnpacpi/pnpbios init
 obj-y				+= system.o
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 3b8b9d3cb03d..0b8d14050efa 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -166,3 +166,13 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
 struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
 					  resource_size_t start,
 					  resource_size_t end, int flags);
+
+extern int pnp_debug;
+
+#if defined(CONFIG_PNP_DEBUG_MESSAGES)
+#define pnp_dbg(dev, format, arg...)					\
+	({ if (pnp_debug) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; })
+#else
+#define pnp_dbg(dev, format, arg...)					\
+	({ if (0) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; })
+#endif
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 817fe626e15b..16c01c6fa7c5 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -177,6 +177,9 @@ int __pnp_add_device(struct pnp_dev *dev)
 int pnp_add_device(struct pnp_dev *dev)
 {
 	int ret;
+	char buf[128];
+	int len = 0;
+	struct pnp_id *id;
 
 	if (dev->card)
 		return -EINVAL;
@@ -185,17 +188,12 @@ int pnp_add_device(struct pnp_dev *dev)
 	if (ret)
 		return ret;
 
-#ifdef CONFIG_PNP_DEBUG
-	{
-		struct pnp_id *id;
+	buf[0] = '\0';
+	for (id = dev->id; id; id = id->next)
+		len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id);
 
-		dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs",
-			dev->protocol->name);
-		for (id = dev->id; id; id = id->next)
-			printk(" %s", id->id);
-		printk(" (%s)\n", dev->active ? "active" : "disabled");
-	}
-#endif
+	pnp_dbg(&dev->dev, "%s device, IDs%s (%s)\n",
+		dev->protocol->name, buf, dev->active ? "active" : "disabled");
 	return 0;
 }
 
@@ -214,3 +212,14 @@ static int __init pnp_init(void)
 }
 
 subsys_initcall(pnp_init);
+
+int pnp_debug;
+
+#if defined(CONFIG_PNP_DEBUG_MESSAGES)
+static int __init pnp_debug_setup(char *__unused)
+{
+	pnp_debug = 1;
+	return 1;
+}
+__setup("pnp.debug", pnp_debug_setup);
+#endif
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index e3f7e89c4dfb..527ee764c93f 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -114,7 +114,6 @@ static int pnp_device_probe(struct device *dev)
 	} else
 		goto fail;
 
-	dev_dbg(dev, "driver attached\n");
 	return error;
 
 fail:
@@ -211,8 +210,6 @@ struct bus_type pnp_bus_type = {
 
 int pnp_register_driver(struct pnp_driver *drv)
 {
-	pnp_dbg("the driver '%s' has been registered", drv->name);
-
 	drv->driver.name = drv->name;
 	drv->driver.bus = &pnp_bus_type;
 
@@ -222,7 +219,6 @@ int pnp_register_driver(struct pnp_driver *drv)
 void pnp_unregister_driver(struct pnp_driver *drv)
 {
 	driver_unregister(&drv->driver);
-	pnp_dbg("the driver '%s' has been unregistered", drv->name);
 }
 
 /**
diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile
index 3e38f06f8d78..cac18bbfb817 100644
--- a/drivers/pnp/isapnp/Makefile
+++ b/drivers/pnp/isapnp/Makefile
@@ -5,7 +5,3 @@
 isapnp-proc-$(CONFIG_PROC_FS) = proc.o
 
 obj-y := core.o compat.o $(isapnp-proc-y)
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 46455fbab6d5..e851160e14f0 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -901,7 +901,7 @@ static int isapnp_get_resources(struct pnp_dev *dev)
 {
 	int i, ret;
 
-	dev_dbg(&dev->dev, "get resources\n");
+	pnp_dbg(&dev->dev, "get resources\n");
 	pnp_init_resources(dev);
 	isapnp_cfg_begin(dev->card->number, dev->number);
 	dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
@@ -939,13 +939,13 @@ static int isapnp_set_resources(struct pnp_dev *dev)
 	struct resource *res;
 	int tmp;
 
-	dev_dbg(&dev->dev, "set resources\n");
+	pnp_dbg(&dev->dev, "set resources\n");
 	isapnp_cfg_begin(dev->card->number, dev->number);
 	dev->active = 1;
 	for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
 		res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
 		if (pnp_resource_enabled(res)) {
-			dev_dbg(&dev->dev, "  set io  %d to %#llx\n",
+			pnp_dbg(&dev->dev, "  set io  %d to %#llx\n",
 				tmp, (unsigned long long) res->start);
 			isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
 					  res->start);
@@ -957,14 +957,14 @@ static int isapnp_set_resources(struct pnp_dev *dev)
 			int irq = res->start;
 			if (irq == 2)
 				irq = 9;
-			dev_dbg(&dev->dev, "  set irq %d to %d\n", tmp, irq);
+			pnp_dbg(&dev->dev, "  set irq %d to %d\n", tmp, irq);
 			isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
 		}
 	}
 	for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
 		res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
 		if (pnp_resource_enabled(res)) {
-			dev_dbg(&dev->dev, "  set dma %d to %lld\n",
+			pnp_dbg(&dev->dev, "  set dma %d to %lld\n",
 				tmp, (unsigned long long) res->start);
 			isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
 		}
@@ -972,7 +972,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
 	for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
 		res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
 		if (pnp_resource_enabled(res)) {
-			dev_dbg(&dev->dev, "  set mem %d to %#llx\n",
+			pnp_dbg(&dev->dev, "  set mem %d to %#llx\n",
 				tmp, (unsigned long long) res->start);
 			isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
 					  (res->start >> 8) & 0xffff);
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index b526eaad3f6c..00fd3577b985 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -25,7 +25,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
 
 	res = pnp_get_resource(dev, IORESOURCE_IO, idx);
 	if (res) {
-		dev_dbg(&dev->dev, "  io %d already set to %#llx-%#llx "
+		pnp_dbg(&dev->dev, "  io %d already set to %#llx-%#llx "
 			"flags %#lx\n", idx, (unsigned long long) res->start,
 			(unsigned long long) res->end, res->flags);
 		return 0;
@@ -38,7 +38,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
 
 	if (!rule->size) {
 		res->flags |= IORESOURCE_DISABLED;
-		dev_dbg(&dev->dev, "  io %d disabled\n", idx);
+		pnp_dbg(&dev->dev, "  io %d disabled\n", idx);
 		goto __add;
 	}
 
@@ -49,7 +49,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
 		res->start += rule->align;
 		res->end = res->start + rule->size - 1;
 		if (res->start > rule->max || !rule->align) {
-			dev_dbg(&dev->dev, "  couldn't assign io %d "
+			pnp_dbg(&dev->dev, "  couldn't assign io %d "
 				"(min %#llx max %#llx)\n", idx,
 				(unsigned long long) rule->min,
 				(unsigned long long) rule->max);
@@ -68,7 +68,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 
 	res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
 	if (res) {
-		dev_dbg(&dev->dev, "  mem %d already set to %#llx-%#llx "
+		pnp_dbg(&dev->dev, "  mem %d already set to %#llx-%#llx "
 			"flags %#lx\n", idx, (unsigned long long) res->start,
 			(unsigned long long) res->end, res->flags);
 		return 0;
@@ -90,7 +90,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 
 	if (!rule->size) {
 		res->flags |= IORESOURCE_DISABLED;
-		dev_dbg(&dev->dev, "  mem %d disabled\n", idx);
+		pnp_dbg(&dev->dev, "  mem %d disabled\n", idx);
 		goto __add;
 	}
 
@@ -101,7 +101,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 		res->start += rule->align;
 		res->end = res->start + rule->size - 1;
 		if (res->start > rule->max || !rule->align) {
-			dev_dbg(&dev->dev, "  couldn't assign mem %d "
+			pnp_dbg(&dev->dev, "  couldn't assign mem %d "
 				"(min %#llx max %#llx)\n", idx,
 				(unsigned long long) rule->min,
 				(unsigned long long) rule->max);
@@ -126,7 +126,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
 
 	res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
 	if (res) {
-		dev_dbg(&dev->dev, "  irq %d already set to %d flags %#lx\n",
+		pnp_dbg(&dev->dev, "  irq %d already set to %d flags %#lx\n",
 			idx, (int) res->start, res->flags);
 		return 0;
 	}
@@ -138,7 +138,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
 
 	if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
 		res->flags |= IORESOURCE_DISABLED;
-		dev_dbg(&dev->dev, "  irq %d disabled\n", idx);
+		pnp_dbg(&dev->dev, "  irq %d disabled\n", idx);
 		goto __add;
 	}
 
@@ -160,11 +160,11 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
 		res->start = -1;
 		res->end = -1;
 		res->flags |= IORESOURCE_DISABLED;
-		dev_dbg(&dev->dev, "  irq %d disabled (optional)\n", idx);
+		pnp_dbg(&dev->dev, "  irq %d disabled (optional)\n", idx);
 		goto __add;
 	}
 
-	dev_dbg(&dev->dev, "  couldn't assign irq %d\n", idx);
+	pnp_dbg(&dev->dev, "  couldn't assign irq %d\n", idx);
 	return -EBUSY;
 
 __add:
@@ -184,7 +184,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
 
 	res = pnp_get_resource(dev, IORESOURCE_DMA, idx);
 	if (res) {
-		dev_dbg(&dev->dev, "  dma %d already set to %d flags %#lx\n",
+		pnp_dbg(&dev->dev, "  dma %d already set to %d flags %#lx\n",
 			idx, (int) res->start, res->flags);
 		return 0;
 	}
@@ -205,7 +205,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
 	res->start = res->end = MAX_DMA_CHANNELS;
 #endif
 	res->flags |= IORESOURCE_DISABLED;
-	dev_dbg(&dev->dev, "  disable dma %d\n", idx);
+	pnp_dbg(&dev->dev, "  disable dma %d\n", idx);
 
 __add:
 	pnp_add_dma_resource(dev, res->start, res->flags);
@@ -238,7 +238,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set)
 	int nport = 0, nmem = 0, nirq = 0, ndma = 0;
 	int ret = 0;
 
-	dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
+	pnp_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
 	mutex_lock(&pnp_res_mutex);
 	pnp_clean_resource_table(dev);
 
@@ -270,7 +270,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set)
 
 	mutex_unlock(&pnp_res_mutex);
 	if (ret < 0) {
-		dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
+		pnp_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
 		pnp_clean_resource_table(dev);
 	} else
 		dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
@@ -286,7 +286,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
 	int i, ret;
 
 	if (!pnp_can_configure(dev)) {
-		dev_dbg(&dev->dev, "configuration not supported\n");
+		pnp_dbg(&dev->dev, "configuration not supported\n");
 		return -ENODEV;
 	}
 
@@ -313,7 +313,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
 int pnp_start_dev(struct pnp_dev *dev)
 {
 	if (!pnp_can_write(dev)) {
-		dev_dbg(&dev->dev, "activation not supported\n");
+		pnp_dbg(&dev->dev, "activation not supported\n");
 		return -EINVAL;
 	}
 
@@ -336,7 +336,7 @@ int pnp_start_dev(struct pnp_dev *dev)
 int pnp_stop_dev(struct pnp_dev *dev)
 {
 	if (!pnp_can_disable(dev)) {
-		dev_dbg(&dev->dev, "disabling not supported\n");
+		pnp_dbg(&dev->dev, "disabling not supported\n");
 		return -EINVAL;
 	}
 	if (dev->protocol->disable(dev) < 0) {
diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile
index 2d7a1e6908be..905326fcca85 100644
--- a/drivers/pnp/pnpacpi/Makefile
+++ b/drivers/pnp/pnpacpi/Makefile
@@ -3,7 +3,3 @@
 #
 
 obj-y := core.o rsparser.o
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 53561d72b4ee..383e47c392a4 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -75,7 +75,7 @@ static int __init ispnpidacpi(char *id)
 
 static int pnpacpi_get_resources(struct pnp_dev *dev)
 {
-	dev_dbg(&dev->dev, "get resources\n");
+	pnp_dbg(&dev->dev, "get resources\n");
 	return pnpacpi_parse_allocated_resource(dev);
 }
 
@@ -86,7 +86,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
 	int ret;
 	acpi_status status;
 
-	dev_dbg(&dev->dev, "set resources\n");
+	pnp_dbg(&dev->dev, "set resources\n");
 	ret = pnpacpi_build_resource_template(dev, &buffer);
 	if (ret)
 		return ret;
@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
 	acpi_status status;
 	struct pnp_dev *dev;
 
+	/*
+	 * If a PnPacpi device is not present , the device
+	 * driver should not be loaded.
+	 */
 	status = acpi_get_handle(device->handle, "_CRS", &temp);
 	if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
-	    is_exclusive_device(device))
+	    is_exclusive_device(device) || (!device->status.present))
 		return 0;
 
 	dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
@@ -255,14 +259,14 @@ int pnpacpi_disabled __initdata;
 static int __init pnpacpi_init(void)
 {
 	if (acpi_disabled || pnpacpi_disabled) {
-		pnp_info("PnP ACPI: disabled");
+		printk(KERN_INFO "pnp: PnP ACPI: disabled\n");
 		return 0;
 	}
-	pnp_info("PnP ACPI init");
+	printk(KERN_INFO "pnp: PnP ACPI init\n");
 	pnp_register_protocol(&pnpacpi_protocol);
 	register_acpi_bus_type(&acpi_pnp_bus);
 	acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
-	pnp_info("PnP ACPI: found %d devices", num);
+	printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num);
 	unregister_acpi_bus_type(&acpi_pnp_bus);
 	pnp_platform_devices = 1;
 	return 0;
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 95015cbfd33f..adf17856bacc 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -132,7 +132,8 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
 	pnp_add_irq_resource(dev, irq, flags);
 }
 
-static int dma_flags(int type, int bus_master, int transfer)
+static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
+		     int transfer)
 {
 	int flags = 0;
 
@@ -154,7 +155,7 @@ static int dma_flags(int type, int bus_master, int transfer)
 	default:
 		/* Set a default value ? */
 		flags |= IORESOURCE_DMA_COMPATIBLE;
-		pnp_err("Invalid DMA type");
+		dev_err(&dev->dev, "invalid DMA type %d\n", type);
 	}
 	switch (transfer) {
 	case ACPI_TRANSFER_8:
@@ -169,7 +170,7 @@ static int dma_flags(int type, int bus_master, int transfer)
 	default:
 		/* Set a default value ? */
 		flags |= IORESOURCE_DMA_8AND16BIT;
-		pnp_err("Invalid DMA transfer type");
+		dev_err(&dev->dev, "invalid DMA transfer type %d\n", transfer);
 	}
 
 	return flags;
@@ -336,7 +337,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
 	case ACPI_RESOURCE_TYPE_DMA:
 		dma = &res->data.dma;
 		if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
-			flags = dma_flags(dma->type, dma->bus_master,
+			flags = dma_flags(dev, dma->type, dma->bus_master,
 					  dma->transfer);
 		else
 			flags = IORESOURCE_DISABLED;
@@ -449,7 +450,7 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
 	acpi_handle handle = dev->data;
 	acpi_status status;
 
-	dev_dbg(&dev->dev, "parse allocated resources\n");
+	pnp_dbg(&dev->dev, "parse allocated resources\n");
 
 	pnp_init_resources(dev);
 
@@ -477,7 +478,7 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
 	for (i = 0; i < p->channel_count; i++)
 		map |= 1 << p->channels[i];
 
-	flags = dma_flags(p->type, p->bus_master, p->transfer);
+	flags = dma_flags(dev, p->type, p->bus_master, p->transfer);
 	pnp_register_dma_resource(dev, option_flags, map, flags);
 }
 
@@ -608,8 +609,8 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
 	unsigned char flags = 0;
 
 	status = acpi_resource_to_address64(r, p);
-	if (!ACPI_SUCCESS(status)) {
-		pnp_warn("PnPACPI: failed to convert resource type %d",
+	if (ACPI_FAILURE(status)) {
+		dev_warn(&dev->dev, "can't convert resource type %d\n",
 			 r->type);
 		return;
 	}
@@ -735,7 +736,7 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
 	acpi_status status;
 	struct acpipnp_parse_option_s parse_data;
 
-	dev_dbg(&dev->dev, "parse resource options\n");
+	pnp_dbg(&dev->dev, "parse resource options\n");
 
 	parse_data.dev = dev;
 	parse_data.option_flags = 0;
@@ -843,7 +844,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
 
 	if (!pnp_resource_enabled(p)) {
 		irq->interrupt_count = 0;
-		dev_dbg(&dev->dev, "  encode irq (%s)\n",
+		pnp_dbg(&dev->dev, "  encode irq (%s)\n",
 			p ? "disabled" : "missing");
 		return;
 	}
@@ -855,7 +856,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
 	irq->interrupt_count = 1;
 	irq->interrupts[0] = p->start;
 
-	dev_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
+	pnp_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
 		(int) p->start,
 		triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
 		polarity == ACPI_ACTIVE_LOW ? "low" : "high",
@@ -872,7 +873,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
 
 	if (!pnp_resource_enabled(p)) {
 		extended_irq->interrupt_count = 0;
-		dev_dbg(&dev->dev, "  encode extended irq (%s)\n",
+		pnp_dbg(&dev->dev, "  encode extended irq (%s)\n",
 			p ? "disabled" : "missing");
 		return;
 	}
@@ -885,7 +886,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
 	extended_irq->interrupt_count = 1;
 	extended_irq->interrupts[0] = p->start;
 
-	dev_dbg(&dev->dev, "  encode irq %d %s %s %s\n", (int) p->start,
+	pnp_dbg(&dev->dev, "  encode irq %d %s %s %s\n", (int) p->start,
 		triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
 		polarity == ACPI_ACTIVE_LOW ? "low" : "high",
 		extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
@@ -899,7 +900,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
 
 	if (!pnp_resource_enabled(p)) {
 		dma->channel_count = 0;
-		dev_dbg(&dev->dev, "  encode dma (%s)\n",
+		pnp_dbg(&dev->dev, "  encode dma (%s)\n",
 			p ? "disabled" : "missing");
 		return;
 	}
@@ -934,7 +935,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
 	dma->channel_count = 1;
 	dma->channels[0] = p->start;
 
-	dev_dbg(&dev->dev, "  encode dma %d "
+	pnp_dbg(&dev->dev, "  encode dma %d "
 		"type %#x transfer %#x master %d\n",
 		(int) p->start, dma->type, dma->transfer, dma->bus_master);
 }
@@ -958,7 +959,7 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
 		io->address_length = 0;
 	}
 
-	dev_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
+	pnp_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
 		io->minimum + io->address_length - 1, io->io_decode);
 }
 
@@ -976,7 +977,7 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
 		fixed_io->address_length = 0;
 	}
 
-	dev_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
+	pnp_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
 		fixed_io->address + fixed_io->address_length - 1);
 }
 
@@ -999,7 +1000,7 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev,
 		memory24->address_length = 0;
 	}
 
-	dev_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
+	pnp_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
 		memory24->minimum,
 		memory24->minimum + memory24->address_length - 1,
 		memory24->write_protect);
@@ -1023,7 +1024,7 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev,
 		memory32->alignment = 0;
 	}
 
-	dev_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
+	pnp_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
 		memory32->minimum,
 		memory32->minimum + memory32->address_length - 1,
 		memory32->write_protect);
@@ -1046,7 +1047,7 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
 		fixed_memory32->address_length = 0;
 	}
 
-	dev_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
+	pnp_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
 		fixed_memory32->address,
 		fixed_memory32->address + fixed_memory32->address_length - 1,
 		fixed_memory32->write_protect);
@@ -1060,7 +1061,7 @@ int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
 	struct acpi_resource *resource = buffer->pointer;
 	int port = 0, irq = 0, dma = 0, mem = 0;
 
-	dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
+	pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt);
 	while (i < res_cnt) {
 		switch (resource->type) {
 		case ACPI_RESOURCE_TYPE_IRQ:
diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile
index 310e2b3a7710..3cd3ed760605 100644
--- a/drivers/pnp/pnpbios/Makefile
+++ b/drivers/pnp/pnpbios/Makefile
@@ -5,7 +5,3 @@
 pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
 
 obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
-
-ifeq ($(CONFIG_PNP_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 2bfe13369df5..996f64838079 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -211,7 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev)
 	if (!pnpbios_is_dynamic(dev))
 		return -EPERM;
 
-	dev_dbg(&dev->dev, "get resources\n");
+	pnp_dbg(&dev->dev, "get resources\n");
 	node = kzalloc(node_info.max_node_size, GFP_KERNEL);
 	if (!node)
 		return -1;
@@ -234,7 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev)
 	if (!pnpbios_is_dynamic(dev))
 		return -EPERM;
 
-	dev_dbg(&dev->dev, "set resources\n");
+	pnp_dbg(&dev->dev, "set resources\n");
 	node = kzalloc(node_info.max_node_size, GFP_KERNEL);
 	if (!node)
 		return -1;
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index ca567671379e..87b4f49a5251 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -87,7 +87,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
 	if (!p)
 		return NULL;
 
-	dev_dbg(&dev->dev, "parse allocated resources\n");
+	pnp_dbg(&dev->dev, "parse allocated resources\n");
 
 	pnp_init_resources(dev);
 
@@ -324,7 +324,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
 	if (!p)
 		return NULL;
 
-	dev_dbg(&dev->dev, "parse resource options\n");
+	pnp_dbg(&dev->dev, "parse resource options\n");
 	option_flags = 0;
 	while ((char *)p < (char *)end) {
 
@@ -519,7 +519,7 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
 	p[10] = (len >> 8) & 0xff;
 	p[11] = ((len >> 8) >> 8) & 0xff;
 
-	dev_dbg(&dev->dev, "  encode mem %#lx-%#lx\n", base, base + len - 1);
+	pnp_dbg(&dev->dev, "  encode mem %#lx-%#lx\n", base, base + len - 1);
 }
 
 static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
@@ -549,7 +549,7 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
 	p[18] = (len >> 16) & 0xff;
 	p[19] = (len >> 24) & 0xff;
 
-	dev_dbg(&dev->dev, "  encode mem32 %#lx-%#lx\n", base, base + len - 1);
+	pnp_dbg(&dev->dev, "  encode mem32 %#lx-%#lx\n", base, base + len - 1);
 }
 
 static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
@@ -575,7 +575,7 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
 	p[10] = (len >> 16) & 0xff;
 	p[11] = (len >> 24) & 0xff;
 
-	dev_dbg(&dev->dev, "  encode fixed_mem32 %#lx-%#lx\n", base,
+	pnp_dbg(&dev->dev, "  encode fixed_mem32 %#lx-%#lx\n", base,
 		base + len - 1);
 }
 
@@ -592,7 +592,7 @@ static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
 	p[1] = map & 0xff;
 	p[2] = (map >> 8) & 0xff;
 
-	dev_dbg(&dev->dev, "  encode irq mask %#lx\n", map);
+	pnp_dbg(&dev->dev, "  encode irq mask %#lx\n", map);
 }
 
 static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
@@ -607,7 +607,7 @@ static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
 
 	p[1] = map & 0xff;
 
-	dev_dbg(&dev->dev, "  encode dma mask %#lx\n", map);
+	pnp_dbg(&dev->dev, "  encode dma mask %#lx\n", map);
 }
 
 static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
@@ -630,7 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
 	p[5] = (base >> 8) & 0xff;
 	p[7] = len & 0xff;
 
-	dev_dbg(&dev->dev, "  encode io %#lx-%#lx\n", base, base + len - 1);
+	pnp_dbg(&dev->dev, "  encode io %#lx-%#lx\n", base, base + len - 1);
 }
 
 static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
@@ -651,7 +651,7 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
 	p[2] = (base >> 8) & 0xff;
 	p[3] = len & 0xff;
 
-	dev_dbg(&dev->dev, "  encode fixed_io %#lx-%#lx\n", base,
+	pnp_dbg(&dev->dev, "  encode fixed_io %#lx-%#lx\n", base,
 		base + len - 1);
 }
 
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index c144bd575611..8473fe5ed7ff 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -337,9 +337,8 @@ void pnp_fixup_device(struct pnp_dev *dev)
 	for (f = pnp_fixups; *f->id; f++) {
 		if (!compare_pnp_id(dev->id, f->id))
 			continue;
-#ifdef DEBUG
-		dev_dbg(&dev->dev, "%s: calling %pF\n", f->id, f->quirk_function);
-#endif
+		pnp_dbg(&dev->dev, "%s: calling %pF\n", f->id,
+			f->quirk_function);
 		f->quirk_function(dev);
 	}
 }
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index dbae23acdd5b..f604061d2bb0 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -294,7 +294,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
 	u8 progif;
 
 	if (pci->irq == irq) {
-		dev_dbg(&pnp->dev, "device %s using irq %d\n",
+		pnp_dbg(&pnp->dev, "  device %s using irq %d\n",
 			pci_name(pci), irq);
 		return 1;
 	}
@@ -316,7 +316,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
 		if ((progif & 0x5) != 0x5)
 			if (pci_get_legacy_ide_irq(pci, 0) == irq ||
 			    pci_get_legacy_ide_irq(pci, 1) == irq) {
-				dev_dbg(&pnp->dev, "legacy IDE device %s "
+				pnp_dbg(&pnp->dev, "  legacy IDE device %s "
 					"using irq %d\n", pci_name(pci), irq);
 				return 1;
 			}
@@ -517,7 +517,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 	res->start = irq;
 	res->end = irq;
 
-	dev_dbg(&dev->dev, "  add irq %d flags %#x\n", irq, flags);
+	pnp_dbg(&dev->dev, "  add irq %d flags %#x\n", irq, flags);
 	return pnp_res;
 }
 
@@ -538,7 +538,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
 	res->start = dma;
 	res->end = dma;
 
-	dev_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
+	pnp_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
 	return pnp_res;
 }
 
@@ -562,7 +562,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
 	res->start = start;
 	res->end = end;
 
-	dev_dbg(&dev->dev, "  add io  %#llx-%#llx flags %#x\n",
+	pnp_dbg(&dev->dev, "  add io  %#llx-%#llx flags %#x\n",
 		(unsigned long long) start, (unsigned long long) end, flags);
 	return pnp_res;
 }
@@ -587,7 +587,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
 	res->start = start;
 	res->end = end;
 
-	dev_dbg(&dev->dev, "  add mem %#llx-%#llx flags %#x\n",
+	pnp_dbg(&dev->dev, "  add mem %#llx-%#llx flags %#x\n",
 		(unsigned long long) start, (unsigned long long) end, flags);
 	return pnp_res;
 }
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index b42df1620718..63087d5ce609 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -75,18 +75,17 @@ char *pnp_resource_type_name(struct resource *res)
 
 void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
 {
-#ifdef DEBUG
 	char buf[128];
 	int len;
 	struct pnp_resource *pnp_res;
 	struct resource *res;
 
 	if (list_empty(&dev->resources)) {
-		dev_dbg(&dev->dev, "%s: no current resources\n", desc);
+		pnp_dbg(&dev->dev, "%s: no current resources\n", desc);
 		return;
 	}
 
-	dev_dbg(&dev->dev, "%s: current resources:\n", desc);
+	pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
 	list_for_each_entry(pnp_res, &dev->resources, list) {
 		res = &pnp_res->res;
 		len = 0;
@@ -95,7 +94,7 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
 				 pnp_resource_type_name(res));
 
 		if (res->flags & IORESOURCE_DISABLED) {
-			dev_dbg(&dev->dev, "%sdisabled\n", buf);
+			pnp_dbg(&dev->dev, "%sdisabled\n", buf);
 			continue;
 		}
 
@@ -116,9 +115,8 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
 					 res->flags);
 			break;
 		}
-		dev_dbg(&dev->dev, "%s\n", buf);
+		pnp_dbg(&dev->dev, "%s\n", buf);
 	}
-#endif
 }
 
 char *pnp_option_priority_name(struct pnp_option *option)
@@ -136,7 +134,6 @@ char *pnp_option_priority_name(struct pnp_option *option)
 
 void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
 {
-#ifdef DEBUG
 	char buf[128];
 	int len = 0, i;
 	struct pnp_port *port;
@@ -208,6 +205,5 @@ void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
 				 "flags %#x", dma->map, dma->flags);
 		break;
 	}
-	dev_dbg(&dev->dev, "%s\n", buf);
-#endif
+	pnp_dbg(&dev->dev, "%s\n", buf);
 }