Merge branch 'thinkpad-acpi' into release
diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt
index 2b3a6b5..5ee2a02 100644
--- a/Documentation/laptops/acer-wmi.txt
+++ b/Documentation/laptops/acer-wmi.txt
@@ -1,9 +1,9 @@
 Acer Laptop WMI Extras Driver
 http://code.google.com/p/aceracpi
-Version 0.2
-18th August 2008
+Version 0.3
+4th April 2009
 
-Copyright 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
 
 acer-wmi is a driver to allow you to control various parts of your Acer laptop
 hardware under Linux which are exposed via ACPI-WMI.
@@ -36,6 +36,10 @@
 Supported Hardware
 ******************
 
+NOTE: The Acer Aspire One is not supported hardware. It cannot work with
+acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been
+blacklisted until that happens.
+
 Please see the website for the current list of known working hardare:
 
 http://code.google.com/p/aceracpi/wiki/SupportedHardware
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index a4cff5d..4e18d51 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -303,7 +303,7 @@
 		outb(3, 0x22);
 	} else if ((pr != NULL) && pr->flags.bm_control) {
 		/* Disable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
 	}
 	switch (longhaul_version) {
 
@@ -326,7 +326,7 @@
 	case TYPE_POWERSAVER:
 		if (longhaul_flags & USE_ACPI_C3) {
 			/* Don't allow wakeup */
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+			acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
 			do_powersaver(cx->address, clock_ratio_index, dir);
 		} else {
 			do_powersaver(0, clock_ratio_index, dir);
@@ -339,7 +339,7 @@
 		outb(0, 0x22);
 	} else if ((pr != NULL) && pr->flags.bm_control) {
 		/* Enable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
 	}
 	outb(pic2_mask,0xA1);	/* restore mask */
 	outb(pic1_mask,0x21);
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8a851d0..431f8b4 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,9 +11,9 @@
 	select PNP
 	select CPU_IDLE
 	default y
-	---help---
+	help
 	  Advanced Configuration and Power Interface (ACPI) support for 
-	  Linux requires an ACPI compliant platform (hardware/firmware),
+	  Linux requires an ACPI-compliant platform (hardware/firmware),
 	  and assumes the presence of OS-directed configuration and power
 	  management (OSPM) software.  This option will enlarge your 
 	  kernel by about 70K.
@@ -23,20 +23,19 @@
 	  the Plug-and-Play BIOS specification (PnP BIOS), the 
 	  MultiProcessor Specification (MPS), and the Advanced Power 
 	  Management (APM) specification.  If both ACPI and APM support 
-	  are configured, whichever is loaded first shall be used.
+	  are configured, ACPI is used.
 
-	  The ACPI SourceForge project contains the latest source code, 
-	  documentation, tools, mailing list subscription, and other 
-	  information.  This project is available at:
-	  <http://sourceforge.net/projects/acpi>
+	  The project home page for the Linux ACPI subsystem is here:
+	  <http://www.lesswatts.org/projects/acpi/>
 
 	  Linux support for ACPI is based on Intel Corporation's ACPI
-	  Component Architecture (ACPI CA).  For more information see:
-	  <http://developer.intel.com/technology/iapc/acpi>
+	  Component Architecture (ACPI CA).  For more information on the
+	  ACPI CA, see:
+	  <http://acpica.org/>
 
-	  ACPI is an open industry specification co-developed by Compaq, 
-	  Intel, Microsoft, Phoenix, and Toshiba.  The specification is 
-	  available at:
+	  ACPI is an open industry specification co-developed by
+	  Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.
+	  The specification is available at:
 	  <http://www.acpi.info>
 
 if ACPI
@@ -49,14 +48,14 @@
 config ACPI_PROCFS
 	bool "Deprecated /proc/acpi files"
 	depends on PROC_FS
-	---help---
+	help
 	  For backwards compatibility, this option allows
 	  deprecated /proc/acpi/ files to exist, even when
 	  they have been replaced by functions in /sys.
 	  The deprecated files (and their replacements) include:
 
 	  /proc/acpi/sleep (/sys/power/state)
-	  /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
+	  /proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
 	  /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
 	  /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
 	  /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
@@ -66,11 +65,12 @@
 	  and functions which do not yet exist in /sys.
 
 	  Say N to delete /proc/acpi/ files that have moved to /sys/
+
 config ACPI_PROCFS_POWER
 	bool "Deprecated power /proc/acpi directories"
 	depends on PROC_FS
 	default y
-	---help---
+	help
 	  For backwards compatibility, this option allows
           deprecated power /proc/acpi/ directories to exist, even when
           they have been replaced by functions in /sys.
@@ -86,19 +86,19 @@
 	bool "Future power /sys interface"
 	select POWER_SUPPLY
 	default y
-	---help---
+	help
 	  Say N to disable power /sys interface
 
 config ACPI_PROC_EVENT
 	bool "Deprecated /proc/acpi/event support"
 	depends on PROC_FS
 	default y
-	---help---
-	  A user-space daemon, acpi, typically read /proc/acpi/event
-	  and handled all ACPI sub-system generated events.
+	help
+	  A user-space daemon, acpid, typically reads /proc/acpi/event
+	  and handles all ACPI-generated events.
 
-	  These events are now delivered to user-space via
-	  either the input layer, or as netlink events.
+	  These events are now delivered to user-space either
+	  via the input layer or as netlink events.
 
 	  This build option enables the old code for legacy
 	  user-space implementation.  After some time, this will
@@ -112,10 +112,13 @@
 	depends on X86
 	default y
 	help
-	  This driver adds support for the AC Adapter object, which indicates
-	  whether a system is on AC, or not. If you have a system that can
+	  This driver supports the AC Adapter object, which indicates
+	  whether a system is on AC or not.  If you have a system that can
 	  switch between A/C and battery, say Y.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called ac.
+
 config ACPI_BATTERY
 	tristate "Battery"
 	depends on X86
@@ -125,15 +128,21 @@
 	  /proc/acpi/battery. If you have a mobile system with a battery, 
 	  say Y.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called battery.
+
 config ACPI_BUTTON
 	tristate "Button"
 	depends on INPUT
 	default y
 	help
-	  This driver handles events on the power, sleep and lid buttons.
+	  This driver handles events on the power, sleep, and lid buttons.
 	  A daemon reads /proc/acpi/event and perform user-defined actions
 	  such as shutting down the system.  This is necessary for
-	  software controlled poweroff.
+	  software-controlled poweroff.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called button.
 
 config ACPI_VIDEO
 	tristate "Video"
@@ -141,38 +150,45 @@
 	depends on INPUT
 	select THERMAL
 	help
-	  This driver implement the ACPI Extensions For Display Adapters
+	  This driver implements the ACPI Extensions For Display Adapters
 	  for integrated graphics devices on motherboard, as specified in
-	  ACPI 2.0 Specification, Appendix B, allowing to perform some basic
-	  control like defining the video POST device, retrieving EDID information
-	  or to setup a video output, etc.
-	  Note that this is an ref. implementation only.  It may or may not work
-	  for your integrated video device.
+	  ACPI 2.0 Specification, Appendix B.  This supports basic operations
+	  such as defining the video POST device, retrieving EDID information,
+	  and setting up a video output.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called video.
 
 config ACPI_FAN
 	tristate "Fan"
 	select THERMAL
 	default y
 	help
-	  This driver adds support for ACPI fan devices, allowing user-mode 
+	  This driver supports ACPI fan devices, allowing user-mode
 	  applications to perform basic fan control (on, off, status).
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called fan.
+
 config ACPI_DOCK
 	bool "Dock"
 	depends on EXPERIMENTAL
 	help
-	  This driver adds support for ACPI controlled docking stations and removable
-	  drive bays such as the IBM ultrabay or the Dell Module Bay.
+	  This driver supports ACPI-controlled docking stations and removable
+	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
 
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
 	default y
 	help
-	  This driver installs ACPI as the idle handler for Linux, and uses
-	  ACPI C2 and C3 processor states to save power, on systems that
+	  This driver installs ACPI as the idle handler for Linux and uses
+	  ACPI C2 and C3 processor states to save power on systems that
 	  support it.  It is required by several flavors of cpufreq
-	  Performance-state drivers.
+	  performance-state drivers.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called processor.
 
 config ACPI_HOTPLUG_CPU
 	bool
@@ -186,11 +202,14 @@
 	select THERMAL
 	default y
 	help
-	  This driver adds support for ACPI thermal zones.  Most mobile and
+	  This driver supports ACPI thermal zones.  Most mobile and
 	  some desktop systems support ACPI thermal zones.  It is HIGHLY
 	  recommended that this option be enabled, as your processor(s)
 	  may be damaged without it.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called thermal.
+
 config ACPI_NUMA
 	bool "NUMA support"
 	depends on NUMA
@@ -218,7 +237,7 @@
 	int "Disable ACPI for systems before Jan 1st this year" if X86_32
 	default 0
 	help
-	  enter a 4-digit year, eg. 2001 to disable ACPI by default
+	  Enter a 4-digit year, e.g., 2001, to disable ACPI by default
 	  on platforms with DMI BIOS date before January 1st that year.
 	  "acpi=force" can be used to override this mechanism.
 
@@ -249,10 +268,13 @@
 	tristate "PCI slot detection driver"
 	default n
 	help
-	  This driver will attempt to discover all PCI slots in your system,
-	  and creates entries in /sys/bus/pci/slots/. This feature can
-	  help you correlate PCI bus addresses with the physical geography
-	  of your slots. If you are unsure, say N.
+	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
+	  slots in the system.  This can help correlate PCI bus addresses,
+	  i.e., segment/bus/device/function tuples, with physical slots in
+	  the system.  If you are unsure, say N.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called pci_slot.
 
 config X86_PM_TIMER
 	bool "Power Management Timer Support" if EMBEDDED
@@ -271,43 +293,43 @@
 	  systems require this timer. 
 
 config ACPI_CONTAINER
-	tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+	tristate "Container and Module Devices (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 	default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
-	 ---help---
-	  This allows _physical_ insertion and removal of CPUs and memory.
-	  This can be useful, for example, on NUMA machines that support
-	  ACPI based physical hotplug of nodes, or non-NUMA machines that
-	  support physical cpu/memory hot-plug.
+	help
+	  This driver supports ACPI Container and Module devices (IDs
+	  ACPI0004, PNP0A05, and PNP0A06).
 
-	  If one selects "m", this driver can be loaded with
-	  "modprobe container".
+	  This helps support hotplug of nodes, CPUs, and memory.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called container.
 
 config ACPI_HOTPLUG_MEMORY
 	tristate "Memory Hotplug"
 	depends on MEMORY_HOTPLUG
 	default n
 	help
-	  This driver adds supports for ACPI Memory Hotplug.  This driver
-	  provides support for fielding notifications on ACPI memory
-	  devices (PNP0C80) which represent memory ranges that may be
-	  onlined or offlined during runtime.  
+	  This driver supports ACPI memory hotplug.  The driver
+	  fields notifications on ACPI memory devices (PNP0C80),
+	  which represent memory ranges that may be onlined or
+	  offlined during runtime.
 
-	  Enabling this driver assumes that your platform hardware
-	  and firmware have support for hot-plugging physical memory. If
-	  your system does not support physically adding or ripping out 
-	  memory DIMMs at some platform defined granularity (individually 
-	  or as a bank) at runtime, then you need not enable this driver.
+	  If your hardware and firmware do not support adding or
+	  removing memory devices at runtime, you need not enable
+	  this driver.
 
-	  If one selects "m," this driver can be loaded using the following
-	  command: 
-		$>modprobe acpi_memhotplug 
+	  To compile this driver as a module, choose M here:
+	  the module will be called acpi_memhotplug.
 
 config ACPI_SBS
 	tristate "Smart Battery System"
 	depends on X86
 	help
-	  This driver adds support for the Smart Battery System, another
+	  This driver supports the Smart Battery System, another
 	  type of access to battery information, found on some laptops.
 
+	  To compile this driver as a module, choose M here:
+	  the modules will be called sbs and sbshc.
+
 endif	# ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index b130ea0..61675e2 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -32,10 +32,8 @@
 processor-objs	+= processor_perflib.o
 endif
 
-obj-y				+= bus.o glue.o
-obj-y				+= scan.o
-# Keep EC driver first. Initialization of others depend on it.
-obj-y				+= ec.o
+obj-y				+= bus.o glue.o scan.o ec.o \
+					power.o system.o event.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
@@ -51,8 +49,6 @@
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
 obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
-obj-y				+= power.o
-obj-y				+= system.o event.o
 obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
 obj-$(CONFIG_ACPI_NUMA)		+= numa.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 3f23298..17e5082 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -18,7 +18,7 @@
 	 excreate.o  exmisc.o   exoparg2.o  exregion.o  exstore.o   exutils.o \
 	 exdump.o    exmutex.o  exoparg3.o  exresnte.o  exstoren.o
 
-obj-y += hwacpi.o  hwgpe.o  hwregs.o  hwsleep.o hwxface.o
+obj-y += hwacpi.o  hwgpe.o  hwregs.o  hwsleep.o hwxface.o hwvalid.o
 
 obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
 
@@ -41,4 +41,4 @@
 
 obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
 		utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
-		utstate.o utmutex.o utobject.o utresrc.o
+		utstate.o utmutex.o utobject.o utresrc.o utlock.o
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ddb40f5..16e5210 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -148,9 +148,12 @@
 ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
 ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS;
 
-/* These addresses are calculated from FADT address values */
+/* These addresses are calculated from the FADT Event Block addresses */
 
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status;
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
+
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status;
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
 
 /*
@@ -162,6 +165,10 @@
 ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
 ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
 
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
+
 /*****************************************************************************
  *
  * Mutual exlusion within ACPICA subsystem
@@ -245,6 +252,7 @@
 ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
 ACPI_EXTERN u8 acpi_gbl_events_initialized;
 ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
+ACPI_EXTERN u8 acpi_gbl_osi_data;
 
 #ifndef DEFINE_ACPI_GLOBALS
 
@@ -371,7 +379,6 @@
 ACPI_EXTERN char *acpi_gbl_db_filename;
 ACPI_EXTERN u32 acpi_gbl_db_debug_level;
 ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
 ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
 
 /*
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 58c69dc..4afa3d8 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -64,14 +64,22 @@
  */
 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
 
-acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value);
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control);
+
+acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value);
 
 acpi_status acpi_hw_register_write(u32 register_id, u32 value);
 
 acpi_status acpi_hw_clear_acpi_status(void);
 
 /*
+ * hwvalid - Port I/O with validation
+ */
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width);
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
+
+/*
  * hwgpe - GPE support
  */
 acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 492d027..772ee5c 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -108,6 +108,14 @@
 #endif
 #endif
 
+/* Lock structure for reader/writer interfaces */
+
+struct acpi_rw_lock {
+	acpi_mutex writer_mutex;
+	acpi_mutex reader_mutex;
+	u32 num_readers;
+};
+
 /*
  * Predefined handles for spinlocks used within the subsystem.
  * These spinlocks are created by acpi_ut_mutex_initialize
@@ -772,7 +780,19 @@
  * must be preserved.
  */
 #define ACPI_PM1_STATUS_PRESERVED_BITS          0x0800	/* Bit 11 */
-#define ACPI_PM1_CONTROL_PRESERVED_BITS         0x0200	/* Bit 9 (whatever) */
+
+/* Write-only bits must be zeroed by software */
+
+#define ACPI_PM1_CONTROL_WRITEONLY_BITS         0x2004	/* Bits 13, 2 */
+
+/* For control registers, both ignored and reserved bits must be preserved */
+
+#define ACPI_PM1_CONTROL_IGNORED_BITS           0x0201	/* Bits 9, 0(SCI_EN) */
+#define ACPI_PM1_CONTROL_RESERVED_BITS          0xC1F8	/* Bits 14-15, 3-8 */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS \
+	       (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
+
+#define ACPI_PM2_CONTROL_PRESERVED_BITS         0xFFFFFFFE	/* All except bit 0 */
 
 /*
  * Register IDs
@@ -781,12 +801,10 @@
 #define ACPI_REGISTER_PM1_STATUS                0x01
 #define ACPI_REGISTER_PM1_ENABLE                0x02
 #define ACPI_REGISTER_PM1_CONTROL               0x03
-#define ACPI_REGISTER_PM1A_CONTROL              0x04
-#define ACPI_REGISTER_PM1B_CONTROL              0x05
-#define ACPI_REGISTER_PM2_CONTROL               0x06
-#define ACPI_REGISTER_PM_TIMER                  0x07
-#define ACPI_REGISTER_PROCESSOR_BLOCK           0x08
-#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x09
+#define ACPI_REGISTER_PM2_CONTROL               0x04
+#define ACPI_REGISTER_PM_TIMER                  0x05
+#define ACPI_REGISTER_PROCESSOR_BLOCK           0x06
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x07
 
 /* Masks used to access the bit_registers */
 
@@ -818,7 +836,7 @@
 #define ACPI_BITMASK_SCI_ENABLE                 0x0001
 #define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
 #define ACPI_BITMASK_GLOBAL_LOCK_RELEASE        0x0004
-#define ACPI_BITMASK_SLEEP_TYPE_X               0x1C00
+#define ACPI_BITMASK_SLEEP_TYPE                 0x1C00
 #define ACPI_BITMASK_SLEEP_ENABLE               0x2000
 
 #define ACPI_BITMASK_ARB_DISABLE                0x0001
@@ -844,11 +862,35 @@
 #define ACPI_BITPOSITION_SCI_ENABLE             0x00
 #define ACPI_BITPOSITION_BUS_MASTER_RLD         0x01
 #define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE    0x02
-#define ACPI_BITPOSITION_SLEEP_TYPE_X           0x0A
+#define ACPI_BITPOSITION_SLEEP_TYPE             0x0A
 #define ACPI_BITPOSITION_SLEEP_ENABLE           0x0D
 
 #define ACPI_BITPOSITION_ARB_DISABLE            0x00
 
+/* Structs and definitions for _OSI support and I/O port validation */
+
+#define ACPI_OSI_WIN_2000               0x01
+#define ACPI_OSI_WIN_XP                 0x02
+#define ACPI_OSI_WIN_XP_SP1             0x03
+#define ACPI_OSI_WINSRV_2003            0x04
+#define ACPI_OSI_WIN_XP_SP2             0x05
+#define ACPI_OSI_WINSRV_2003_SP1        0x06
+#define ACPI_OSI_WIN_VISTA              0x07
+
+#define ACPI_ALWAYS_ILLEGAL             0x00
+
+struct acpi_interface_info {
+	char *name;
+	u8 value;
+};
+
+struct acpi_port_info {
+	char *name;
+	u16 start;
+	u16 end;
+	u8 osi_dependency;
+};
+
 /*****************************************************************************
  *
  * Resource descriptors
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 9c127e8..91ac7d7 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -292,10 +292,6 @@
 #define ACPI_GET_DESCRIPTOR_TYPE(d)     (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
 #define ACPI_SET_DESCRIPTOR_TYPE(d, t)  (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
 
-/* Macro to test the object type */
-
-#define ACPI_GET_OBJECT_TYPE(d)         (((union acpi_operand_object *)(void *)(d))->common.type)
-
 /*
  * Macros for the master AML opcode table
  */
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index eb6f038..544dcf8 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -97,7 +97,6 @@
 #define AOPOBJ_OBJECT_INITIALIZED   0x08
 #define AOPOBJ_SETUP_COMPLETE       0x10
 #define AOPOBJ_SINGLE_DATUM         0x20
-#define AOPOBJ_INVALID              0x40	/* Used if host OS won't allow an op_region address */
 
 /******************************************************************************
  *
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 16a9ca9..63f656a 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -52,41 +52,44 @@
  * 1) PTYPE1 packages do not contain sub-packages.
  *
  * ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
  *
  * ACPI_PTYPE1_VAR: Variable length:
- *    object type (Int/Buf/Ref)
+ *      object type (Int/Buf/Ref)
  *
- * ACPI_PTYPE1_OPTION: Package has some required and some optional elements:
- *      Used for _PRW
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
+ *      (Used for _PRW)
  *
  *
  * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the
  *    different types describe the contents of each of the sub-packages.
  *
  * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
+ *      (Used for _ALR,_MLS,_PSS,_TRT,_TSS)
  *
  * ACPI_PTYPE2_COUNT: Each subpackage has a count as first element:
- *     object type
+ *      object type
+ *      (Used for _CSD,_PSD,_TSD)
  *
  * ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
+ *      (Used for _CST)
  *
- * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length:
- *      Used for _PRT
+ * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length
+ *      (Used for _PRT)
  *
  * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
- *      Used for _HPX
+ *      (Used for _HPX)
  *
  *****************************************************************************/
 
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 7ce6e33..01c76b8 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -49,7 +49,7 @@
 /*
  * tbfadt - FADT parse/convert/validate
  */
-void acpi_tb_parse_fadt(u32 table_index, u8 flags);
+void acpi_tb_parse_fadt(u32 table_index);
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
 
@@ -79,7 +79,7 @@
 
 void acpi_tb_terminate(void);
 
-void acpi_tb_delete_namespace_by_owner(u32 table_index);
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
 
 acpi_status acpi_tb_allocate_owner_id(u32 table_index);
 
@@ -109,9 +109,8 @@
 
 void
 acpi_tb_install_table(acpi_physical_address address,
-		      u8 flags, char *signature, u32 table_index);
+		      char *signature, u32 table_index);
 
-acpi_status
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
+acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
 
 #endif				/* __ACTABLES_H__ */
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 80d8813..897810b 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -346,6 +346,21 @@
 acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
 
 /*
+ * utlock - reader/writer locks
+ */
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock);
+
+/*
  * utobject - internal object create/delete/cache routines
  */
 union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index eb144b1..3aae13f 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -180,11 +180,23 @@
 
 	/* Walk entire namespace from the supplied root */
 
-	status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-				     acpi_ds_init_one_object, &info, NULL);
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * We don't use acpi_walk_namespace since we do not want to acquire
+	 * the namespace reader lock.
+	 */
+	status =
+	    acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+				   ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
+				   &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 	}
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 	status = acpi_get_table_by_index(table_index, &table);
 	if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index da0f546..22b1a3c 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -713,6 +713,6 @@
 
 	/* Get the object type */
 
-	return_VALUE(ACPI_GET_OBJECT_TYPE(object));
+	return_VALUE(object->type);
 }
 #endif
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 15c628e..dab3f48 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -565,7 +565,7 @@
 
 	/* Re-type the object according to its argument */
 
-	node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
+	node->type = obj_desc->common.type;
 
 	/* Attach obj to node */
 
@@ -619,7 +619,7 @@
 
 	/* Perform per-object initialization */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		/*
@@ -803,7 +803,7 @@
 	default:
 
 		ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc->common.type));
 
 		status = AE_AML_OPERAND_TYPE;
 		break;
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 0c3b4dd..b4c87b5 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -397,30 +397,6 @@
 	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
 					   extra_desc->extra.aml_length,
 					   extra_desc->extra.aml_start);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	/* Validate the region address/length via the host OS */
-
-	status = acpi_os_validate_address(obj_desc->region.space_id,
-					  obj_desc->region.address,
-					  (acpi_size) obj_desc->region.length,
-					  acpi_ut_get_node_name(node));
-
-	if (ACPI_FAILURE(status)) {
-		/*
-		 * Invalid address/length. We will emit an error message and mark
-		 * the region as invalid, so that it will cause an additional error if
-		 * it is ever used. Then return AE_OK.
-		 */
-		ACPI_EXCEPTION((AE_INFO, status,
-				"During address validation of OpRegion [%4.4s]",
-				node->name.ascii));
-		obj_desc->common.flags |= AOPOBJ_INVALID;
-		status = AE_OK;
-	}
-
 	return_ACPI_STATUS(status);
 }
 
@@ -484,7 +460,7 @@
 
 	/* Host object must be a Buffer */
 
-	if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
+	if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
 		ACPI_ERROR((AE_INFO,
 			    "Target of Create Field is not a Buffer object - %s",
 			    acpi_ut_get_object_type_name(buffer_desc)));
@@ -1365,10 +1341,8 @@
 			if ((ACPI_GET_DESCRIPTOR_TYPE
 			     (walk_state->results->results.obj_desc[0]) ==
 			     ACPI_DESC_TYPE_OPERAND)
-			    &&
-			    (ACPI_GET_OBJECT_TYPE
-			     (walk_state->results->results.obj_desc[0]) ==
-			     ACPI_TYPE_LOCAL_REFERENCE)
+			    && ((walk_state->results->results.obj_desc[0])->
+				common.type == ACPI_TYPE_LOCAL_REFERENCE)
 			    && ((walk_state->results->results.obj_desc[0])->
 				reference.class != ACPI_REFCLASS_INDEX)) {
 				status =
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
index dabc23a..dfa1041 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -816,7 +816,7 @@
 		goto push_result;
 	}
 
-	type = ACPI_GET_OBJECT_TYPE(*operand);
+	type = (*operand)->common.type;
 
 	status = acpi_ex_resolve_to_value(operand, walk_state);
 	if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
index 350e665..f028085 100644
--- a/drivers/acpi/acpica/dswexec.c
+++ b/drivers/acpi/acpica/dswexec.c
@@ -138,11 +138,10 @@
 		goto cleanup;
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
+	if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
 		ACPI_ERROR((AE_INFO,
 			    "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
-			    obj_desc, walk_state,
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc, walk_state, obj_desc->common.type));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index 803edd9..cd55c77 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -183,7 +183,7 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
+ * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
  *
  ******************************************************************************/
 
@@ -200,12 +200,13 @@
 		acpi_gbl_fixed_event_handlers[i].handler = NULL;
 		acpi_gbl_fixed_event_handlers[i].context = NULL;
 
-		/* Enable the fixed event */
+		/* Disable the fixed event */
 
 		if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
 			status =
-			    acpi_set_register(acpi_gbl_fixed_event_info[i].
-					      enable_register_id, 0);
+			    acpi_write_bit_register(acpi_gbl_fixed_event_info
+						    [i].enable_register_id,
+						    ACPI_DISABLE_EVENT);
 			if (ACPI_FAILURE(status)) {
 				return (status);
 			}
@@ -288,16 +289,17 @@
 
 	/* Clear the status bit */
 
-	(void)acpi_set_register(acpi_gbl_fixed_event_info[event].
-				status_register_id, 1);
+	(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				      status_register_id, ACPI_CLEAR_STATUS);
 
 	/*
 	 * Make sure we've got a handler. If not, report an error. The event is
 	 * disabled to prevent further interrupts.
 	 */
 	if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
-		(void)acpi_set_register(acpi_gbl_fixed_event_info[event].
-					enable_register_id, 0);
+		(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+					      enable_register_id,
+					      ACPI_DISABLE_EVENT);
 
 		ACPI_ERROR((AE_INFO,
 			    "No installed handler for fixed event [%08X]",
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f345ced..b9d8ee6 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -88,10 +88,10 @@
 
 	status = acpi_ev_disable_gpe(gpe_event_info);
 
-	/* Type was validated above */
+	/* Clear the type bits and insert the new Type */
 
-	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;	/* Clear type bits */
-	gpe_event_info->flags |= type;	/* Insert type */
+	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;
+	gpe_event_info->flags |= type;
 	return_ACPI_STATUS(status);
 }
 
@@ -122,6 +122,7 @@
 	if (!gpe_register_info) {
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
+
 	register_bit = (u8)
 	    (1 <<
 	     (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 484cc05..7b34636 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -104,9 +104,9 @@
 
 		while (gpe_block) {
 			if ((&gpe_block->event_info[0] <= gpe_event_info) &&
-			    (&gpe_block->
-			     event_info[((acpi_size) gpe_block->
-					 register_count) * 8] >
+			    (&gpe_block->event_info[((acpi_size)
+						     gpe_block->
+						     register_count) * 8] >
 			     gpe_event_info)) {
 				return (TRUE);
 			}
@@ -210,10 +210,9 @@
 		/* Now look at the individual GPEs in this byte register */
 
 		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
-			gpe_event_info =
-			    &gpe_block->
-			    event_info[((acpi_size) i *
-					ACPI_GPE_REGISTER_WIDTH) + j];
+			gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+								 ACPI_GPE_REGISTER_WIDTH)
+								+ j];
 
 			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
 			    ACPI_GPE_DISPATCH_HANDLER) {
@@ -293,8 +292,8 @@
 		/* Unknown method type, just ignore it! */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
-				  "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)",
-				  name));
+				  "Ignoring unknown GPE method type: %s "
+				  "(name not of form _Lxx or _Exx)", name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -306,17 +305,16 @@
 		/* Conversion failed; invalid method, just ignore it */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
-				  "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
-				  name));
+				  "Could not extract GPE number from name: %s "
+				  "(name is not of form _Lxx or _Exx)", name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
 	/* Ensure that we have a valid GPE number for this GPE block */
 
 	if ((gpe_number < gpe_block->block_base_number) ||
-	    (gpe_number >=
-	     (gpe_block->block_base_number +
-	      (gpe_block->register_count * 8)))) {
+	    (gpe_number >= (gpe_block->block_base_number +
+			    (gpe_block->register_count * 8)))) {
 		/*
 		 * Not valid for this GPE block, just ignore it. However, it may be
 		 * valid for a different GPE block, since GPE0 and GPE1 methods both
@@ -408,7 +406,7 @@
 	 */
 	obj_desc = pkg_desc->package.elements[0];
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Use FADT-defined GPE device (from definition of _PRW) */
 
@@ -417,15 +415,15 @@
 		/* Integer is the GPE number in the FADT described GPE blocks */
 
 		gpe_number = (u32) obj_desc->integer.value;
-	} else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	} else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 
 		/* Package contains a GPE reference and GPE number within a GPE block */
 
 		if ((obj_desc->package.count < 2) ||
-		    (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
-		     ACPI_TYPE_LOCAL_REFERENCE)
-		    || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
-			ACPI_TYPE_INTEGER)) {
+		    ((obj_desc->package.elements[0])->common.type !=
+		     ACPI_TYPE_LOCAL_REFERENCE) ||
+		    ((obj_desc->package.elements[1])->common.type !=
+		     ACPI_TYPE_INTEGER)) {
 			goto cleanup;
 		}
 
@@ -450,11 +448,11 @@
 	 */
 	if ((gpe_device == target_gpe_device) &&
 	    (gpe_number >= gpe_block->block_base_number) &&
-	    (gpe_number <
-	     gpe_block->block_base_number + (gpe_block->register_count * 8))) {
-		gpe_event_info =
-		    &gpe_block->event_info[gpe_number -
-					   gpe_block->block_base_number];
+	    (gpe_number < gpe_block->block_base_number +
+	     (gpe_block->register_count * 8))) {
+		gpe_event_info = &gpe_block->event_info[gpe_number -
+							gpe_block->
+							block_base_number];
 
 		/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
 
@@ -1033,8 +1031,8 @@
 	 * 1) are "runtime" or "run/wake" GPEs, and
 	 * 2) have a corresponding _Lxx or _Exx method
 	 *
-	 * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
-	 * external interface.
+	 * Any other GPEs within this block must be enabled via the
+	 * acpi_enable_gpe() external interface.
 	 */
 	wake_gpe_count = 0;
 	gpe_enabled_count = 0;
@@ -1044,14 +1042,13 @@
 
 			/* Get the info block for this particular GPE */
 
-			gpe_event_info =
-			    &gpe_block->
-			    event_info[((acpi_size) i *
-					ACPI_GPE_REGISTER_WIDTH) + j];
+			gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+								 ACPI_GPE_REGISTER_WIDTH)
+								+ j];
 
 			if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
-			     ACPI_GPE_DISPATCH_METHOD)
-			    && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
+			     ACPI_GPE_DISPATCH_METHOD) &&
+			    (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
 				gpe_enabled_count++;
 			}
 
@@ -1105,8 +1102,8 @@
 	/*
 	 * Initialize the GPE Block(s) defined in the FADT
 	 *
-	 * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
-	 * section "General-Purpose Event Registers", we have:
+	 * Why the GPE register block lengths are divided by 2:  From the ACPI
+	 * Spec, section "General-Purpose Event Registers", we have:
 	 *
 	 * "Each register block contains two registers of equal length
 	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
@@ -1163,7 +1160,8 @@
 		if ((register_count0) &&
 		    (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
 			ACPI_ERROR((AE_INFO,
-				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
+				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
+				    "(GPE %d to %d) - Ignoring GPE1",
 				    gpe_number_max, acpi_gbl_FADT.gpe1_base,
 				    acpi_gbl_FADT.gpe1_base +
 				    ((register_count1 *
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index 5f89305..ce224e1 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -163,10 +163,10 @@
 	 * 2) Global device notify handler
 	 * 3) Per-device notify handler
 	 */
-	if ((acpi_gbl_system_notify.handler
-	     && (notify_value <= ACPI_MAX_SYS_NOTIFY))
-	    || (acpi_gbl_device_notify.handler
-		&& (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
+	if ((acpi_gbl_system_notify.handler &&
+	     (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+	    (acpi_gbl_device_notify.handler &&
+	     (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
 		notify_info = acpi_ut_create_generic_state();
 		if (!notify_info) {
 			return (AE_NO_MEMORY);
@@ -174,7 +174,8 @@
 
 		if (!handler_obj) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
+					  "Executing system notify handler for Notify (%4.4s, %X) "
+					  "node %p\n",
 					  acpi_ut_get_node_name(node),
 					  notify_value, node));
 		}
@@ -534,8 +535,9 @@
 		 */
 		if (pending) {
 			status =
-			    acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
-					      1);
+			    acpi_write_bit_register
+			    (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+			     ACPI_ENABLE_EVENT);
 		}
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 665c088..538d632 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -691,7 +691,7 @@
 
 	/* Devices are handled different than regions */
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
+	if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
 
 		/* Check if this Device already has a handler for this address space */
 
@@ -703,7 +703,8 @@
 			if (next_handler_obj->address_space.space_id ==
 			    handler_obj->address_space.space_id) {
 				ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-						  "Found handler for region [%s] in device %p(%p) handler %p\n",
+						  "Found handler for region [%s] in device %p(%p) "
+						  "handler %p\n",
 						  acpi_ut_get_region_name
 						  (handler_obj->address_space.
 						   space_id), obj_desc,
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index f3f1fb4..284a7be 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -241,7 +241,8 @@
 						status = AE_OK;
 					} else {
 						ACPI_EXCEPTION((AE_INFO, status,
-								"Could not install PciConfig handler for Root Bridge %4.4s",
+								"Could not install PciConfig handler "
+								"for Root Bridge %4.4s",
 								acpi_ut_get_node_name
 								(pci_root_node)));
 					}
@@ -293,9 +294,8 @@
 	 * Get the PCI device and function numbers from the _ADR object contained
 	 * in the parent's scope.
 	 */
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
+						 pci_device_node, &pci_value);
 
 	/*
 	 * The default is zero, and since the allocation above zeroed the data,
@@ -308,18 +308,16 @@
 
 	/* The PCI segment number comes from the _SEG method */
 
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
+						 pci_root_node, &pci_value);
 	if (ACPI_SUCCESS(status)) {
 		pci_id->segment = ACPI_LOWORD(pci_value);
 	}
 
 	/* The PCI bus number comes from the _BBN method */
 
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
+						 pci_root_node, &pci_value);
 	if (ACPI_SUCCESS(status)) {
 		pci_id->bus = ACPI_LOWORD(pci_value);
 	}
@@ -632,8 +630,8 @@
 								  acpi_ns_locked);
 
 					/*
-					 * Tell all users that this region is usable by running the _REG
-					 * method
+					 * Tell all users that this region is usable by
+					 * running the _REG method
 					 */
 					if (acpi_ns_locked) {
 						status =
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 3aca901..10b8543 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -631,7 +631,8 @@
 
 	/* Setup up dispatch flags to indicate handler (vs. method) */
 
-	gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);	/* Clear bits */
+	gpe_event_info->flags &=
+	    ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
 	gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
 
 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 35485e4..d0a0807 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -172,8 +172,8 @@
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    enable_register_id, ACPI_ENABLE_EVENT);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -181,8 +181,8 @@
 	/* Make sure that the hardware responded */
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, &value);
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+				   enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -354,15 +354,15 @@
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 0);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    enable_register_id, ACPI_DISABLE_EVENT);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, &value);
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+				   enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -407,8 +407,8 @@
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      status_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    status_register_id, ACPI_CLEAR_STATUS);
 
 	return_ACPI_STATUS(status);
 }
@@ -495,7 +495,7 @@
 	/* Get the status of the requested fixed event */
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 			      enable_register_id, &value);
 	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
@@ -503,7 +503,7 @@
 	*event_status = value;
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 			      status_register_id, &value);
 	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 479e7a3..7c3d2d3 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -193,7 +193,8 @@
 			/* Matched space_id, first dereference this in the Regions */
 
 			ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-					  "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
+					  "Removing address handler %p(%p) for region %s "
+					  "on Device %p(%p)\n",
 					  handler_obj, handler,
 					  acpi_ut_get_region_name(space_id),
 					  node, obj_desc));
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 932bbc2..3deb20a 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -291,7 +291,7 @@
 
 	/* Source Object can be either an op_region or a Buffer/Field */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_REGION:
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -501,7 +501,7 @@
 	 */
 	if ((!ddb_handle) ||
 	    (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
-	    (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+	    (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -520,13 +520,14 @@
 		}
 	}
 
-	/*
-	 * Delete the entire namespace under this table Node
-	 * (Offset contains the table_id)
-	 */
-	acpi_tb_delete_namespace_by_owner(table_index);
-	(void)acpi_tb_release_owner_id(table_index);
+	/* Delete the portion of the namespace owned by this table */
 
+	status = acpi_tb_delete_namespace_by_owner(table_index);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	(void)acpi_tb_release_owner_id(table_index);
 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
 	/* Table unloaded, remove a reference to the ddb_handle object */
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index 0be1018..37d0d39 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -82,7 +82,7 @@
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* No conversion necessary */
@@ -116,7 +116,7 @@
 
 	/* String conversion is different than Buffer conversion */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_STRING:
 
 		/*
@@ -206,7 +206,7 @@
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		/* No conversion necessary */
@@ -409,7 +409,7 @@
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_STRING:
 
 		/* No conversion necessary */
@@ -605,8 +605,7 @@
 		default:
 			/* No conversion allowed for these types */
 
-			if (destination_type !=
-			    ACPI_GET_OBJECT_TYPE(source_desc)) {
+			if (destination_type != source_desc->common.type) {
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 						  "Explicit operator, will store (%s) over existing type (%s)\n",
 						  acpi_ut_get_object_type_name
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index aa31357..89d141f 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -350,6 +350,7 @@
 			break;
 
 		case ACPI_EXD_TYPE:
+
 			acpi_ex_out_string("Type",
 					   acpi_ut_get_object_type_name
 					   (obj_desc));
@@ -422,6 +423,7 @@
 			break;
 
 		default:
+
 			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
 				       info->opcode);
 			return;
@@ -492,7 +494,7 @@
 
 	/* Decode object type */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		acpi_os_printf("Reference: [%s] ",
@@ -527,46 +529,18 @@
 							     type));
 			break;
 
-		case ACPI_REFCLASS_ARG:
-
-			acpi_os_printf("%X", obj_desc->reference.value);
-
-			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
-				/* Value is an Integer */
-
-				acpi_os_printf(" value is [%8.8X%8.8x]",
-					       ACPI_FORMAT_UINT64(obj_desc->
-								  integer.
-								  value));
-			}
-
-			acpi_os_printf("\n");
-			break;
-
-		case ACPI_REFCLASS_LOCAL:
-
-			acpi_os_printf("%X", obj_desc->reference.value);
-
-			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
-				/* Value is an Integer */
-
-				acpi_os_printf(" value is [%8.8X%8.8x]",
-					       ACPI_FORMAT_UINT64(obj_desc->
-								  integer.
-								  value));
-			}
-
-			acpi_os_printf("\n");
-			break;
-
 		case ACPI_REFCLASS_NAME:
 
 			acpi_os_printf("- [%4.4s]\n",
 				       obj_desc->reference.node->name.ascii);
 			break;
 
+		case ACPI_REFCLASS_ARG:
+		case ACPI_REFCLASS_LOCAL:
+
+			acpi_os_printf("%X\n", obj_desc->reference.value);
+			break;
+
 		default:	/* Unknown reference class */
 
 			acpi_os_printf("%2.2X\n", obj_desc->reference.class);
@@ -661,8 +635,8 @@
 	case ACPI_TYPE_LOCAL_REGION_FIELD:
 
 		acpi_os_printf
-		    ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
-		     obj_desc->field.bit_length,
+		    ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
+		     "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
 		     obj_desc->field.access_byte_width,
 		     obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
 		     obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
@@ -686,9 +660,8 @@
 
 		if (!obj_desc->buffer_field.buffer_obj) {
 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
-		} else
-		    if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
-			!= ACPI_TYPE_BUFFER) {
+		} else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
+			   ACPI_TYPE_BUFFER) {
 			acpi_os_printf("*not a Buffer*\n");
 		} else {
 			acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
@@ -737,8 +710,7 @@
 	default:
 		/* Unknown Type */
 
-		acpi_os_printf("Unknown Type %X\n",
-			       ACPI_GET_OBJECT_TYPE(obj_desc));
+		acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
 		break;
 	}
 
@@ -939,7 +911,7 @@
 
 	/* Packages may only contain a few object types */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		acpi_os_printf("[Integer] = %8.8X%8.8X\n",
@@ -990,8 +962,7 @@
 
 	default:
 
-		acpi_os_printf("[Unknown Type] %X\n",
-			       ACPI_GET_OBJECT_TYPE(obj_desc));
+		acpi_os_printf("[Unknown Type] %X\n", obj_desc->common.type);
 		break;
 	}
 }
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index a352d02..546dcdd 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -84,7 +84,7 @@
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -95,9 +95,8 @@
 				return_ACPI_STATUS(status);
 			}
 		}
-	} else
-	    if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
-		&& (obj_desc->field.region_obj->region.space_id ==
+	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+		   (obj_desc->field.region_obj->region.space_id ==
 		    ACPI_ADR_SPACE_SMBUS)) {
 		/*
 		 * This is an SMBus read.  We must create a buffer to hold the data
@@ -163,7 +162,7 @@
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldRead [TO]:   Obj %p, Type %X, Buf %p, ByteLen %X\n",
-			  obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
+			  obj_desc, obj_desc->common.type, buffer,
 			  (u32) length));
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
@@ -222,7 +221,7 @@
 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -233,9 +232,8 @@
 				return_ACPI_STATUS(status);
 			}
 		}
-	} else
-	    if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
-		&& (obj_desc->field.region_obj->region.space_id ==
+	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+		   (obj_desc->field.region_obj->region.space_id ==
 		    ACPI_ADR_SPACE_SMBUS)) {
 		/*
 		 * This is an SMBus write.  We will bypass the entire field mechanism
@@ -243,7 +241,7 @@
 		 *
 		 * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
 		 */
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+		if (source_desc->common.type != ACPI_TYPE_BUFFER) {
 			ACPI_ERROR((AE_INFO,
 				    "SMBus write requires Buffer, found type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
@@ -291,7 +289,7 @@
 
 	/* Get a pointer to the data to be written */
 
-	switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+	switch (source_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 		buffer = &source_desc->integer.value;
 		length = sizeof(source_desc->integer.value);
@@ -314,15 +312,14 @@
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
 			  source_desc,
-			  acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
-						(source_desc)),
-			  ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
+			  acpi_ut_get_type_name(source_desc->common.type),
+			  source_desc->common.type, buffer, length));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldWrite [TO]:   Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
 			  obj_desc,
-			  acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
-			  ACPI_GET_OBJECT_TYPE(obj_desc),
+			  acpi_ut_get_type_name(obj_desc->common.type),
+			  obj_desc->common.type,
 			  obj_desc->common_field.bit_length,
 			  obj_desc->common_field.start_field_bit_offset,
 			  obj_desc->common_field.base_byte_offset));
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index ef58ac4..99cee61 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -94,9 +94,9 @@
 
 	/* We must have a valid region */
 
-	if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
+	if (rgn_desc->common.type != ACPI_TYPE_REGION) {
 		ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
-			    ACPI_GET_OBJECT_TYPE(rgn_desc),
+			    rgn_desc->common.type,
 			    acpi_ut_get_object_type_name(rgn_desc)));
 
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -113,12 +113,6 @@
 		}
 	}
 
-	/* Exit if Address/Length have been disallowed by the host OS */
-
-	if (rgn_desc->common.flags & AOPOBJ_INVALID) {
-		return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
-	}
-
 	/*
 	 * Exit now for SMBus address space, it has a non-linear address space
 	 * and the request cannot be directly validated
@@ -390,7 +384,7 @@
 	 * index_field - Write to an Index Register, then read/write from/to a
 	 *               Data Register
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER_FIELD:
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
@@ -527,7 +521,7 @@
 	default:
 
 		ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc->common.type));
 		status = AE_AML_INTERNAL;
 		break;
 	}
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
index 6b0747ac..998eac3 100644
--- a/drivers/acpi/acpica/exmisc.c
+++ b/drivers/acpi/acpica/exmisc.c
@@ -80,7 +80,7 @@
 	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
 	case ACPI_DESC_TYPE_OPERAND:
 
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+		if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -260,7 +260,7 @@
 	 * guaranteed to be either Integer/String/Buffer by the operand
 	 * resolution mechanism.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -277,7 +277,7 @@
 
 	default:
 		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
-			    ACPI_GET_OBJECT_TYPE(operand0)));
+			    operand0->common.type));
 		status = AE_AML_INTERNAL;
 	}
 
@@ -298,7 +298,7 @@
 	 * 2) Two Strings concatenated to produce a new String
 	 * 3) Two Buffers concatenated to produce a new Buffer
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Result of two Integers is a Buffer */
@@ -379,7 +379,7 @@
 		/* Invalid object type, should not happen here */
 
 		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
-			    ACPI_GET_OBJECT_TYPE(operand0)));
+			    operand0->common.type));
 		status = AE_AML_INTERNAL;
 		goto cleanup;
 	}
@@ -581,7 +581,7 @@
 	 * guaranteed to be either Integer/String/Buffer by the operand
 	 * resolution mechanism.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -608,7 +608,7 @@
 	/*
 	 * Two cases: 1) Both Integers, 2) Both Strings or Buffers
 	 */
-	if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
+	if (operand0->common.type == ACPI_TYPE_INTEGER) {
 		/*
 		 * 1) Both operands are of type integer
 		 *    Note: local_operand1 may have changed above
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index b530480..9635d21 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -807,11 +807,9 @@
 							 acpi_namespace_node *)
 							operand[0]);
 			if (temp_desc
-			    &&
-			    ((ACPI_GET_OBJECT_TYPE(temp_desc) ==
-			      ACPI_TYPE_STRING)
-			     || (ACPI_GET_OBJECT_TYPE(temp_desc) ==
-				 ACPI_TYPE_LOCAL_REFERENCE))) {
+			    && ((temp_desc->common.type == ACPI_TYPE_STRING)
+				|| (temp_desc->common.type ==
+				    ACPI_TYPE_LOCAL_REFERENCE))) {
 				operand[0] = temp_desc;
 				acpi_ut_add_reference(temp_desc);
 			} else {
@@ -819,7 +817,7 @@
 				goto cleanup;
 			}
 		} else {
-			switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+			switch ((operand[0])->common.type) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
 				/*
 				 * This is a deref_of (local_x | arg_x)
@@ -877,8 +875,7 @@
 
 		if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
 		    ACPI_DESC_TYPE_NAMED) {
-			if (ACPI_GET_OBJECT_TYPE(operand[0]) ==
-			    ACPI_TYPE_STRING) {
+			if ((operand[0])->common.type == ACPI_TYPE_STRING) {
 				/*
 				 * This is a deref_of (String). The string is a reference
 				 * to a named ACPI object.
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 0b4f513..85d95c9 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -399,7 +399,7 @@
 		 * At this point, the Source operand is a String, Buffer, or Package.
 		 * Verify that the index is within range.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+		switch ((operand[0])->common.type) {
 		case ACPI_TYPE_STRING:
 
 			if (index >= operand[0]->string.length) {
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
index c6520bb..253f9e1 100644
--- a/drivers/acpi/acpica/exoparg3.c
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -161,9 +161,8 @@
 		 * Create the return object.  The Source operand is guaranteed to be
 		 * either a String or a Buffer, so just use its type.
 		 */
-		return_desc =
-		    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
-						   (operand[0]));
+		return_desc = acpi_ut_create_internal_object((operand[0])->
+							     common.type);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -191,7 +190,7 @@
 
 		/* Strings always have a sub-pointer, not so for buffers */
 
-		switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+		switch ((operand[0])->common.type) {
 		case ACPI_TYPE_STRING:
 
 			/* Always allocate a new buffer for the String */
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index a226f74..52fec07 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -279,7 +279,7 @@
 		return_UINT32(0);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * buffer_field access can be on any byte boundary, so the
 		 * byte_alignment is always 1 byte -- regardless of any byte_alignment
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 76ec8ff..3a54b73 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -294,14 +294,14 @@
 	switch (function) {
 	case ACPI_READ:
 
-		status = acpi_os_read_port((acpi_io_address) address,
+		status = acpi_hw_read_port((acpi_io_address) address,
 					   &value32, bit_width);
 		*value = value32;
 		break;
 
 	case ACPI_WRITE:
 
-		status = acpi_os_write_port((acpi_io_address) address,
+		status = acpi_hw_write_port((acpi_io_address) address,
 					    (u32) * value, bit_width);
 		break;
 
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
index a063a74..607958f 100644
--- a/drivers/acpi/acpica/exresnte.c
+++ b/drivers/acpi/acpica/exresnte.c
@@ -136,7 +136,7 @@
 	switch (entry_type) {
 	case ACPI_TYPE_PACKAGE:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
+		if (source_desc->common.type != ACPI_TYPE_PACKAGE) {
 			ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -154,7 +154,7 @@
 
 	case ACPI_TYPE_BUFFER:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+		if (source_desc->common.type != ACPI_TYPE_BUFFER) {
 			ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -172,7 +172,7 @@
 
 	case ACPI_TYPE_STRING:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
+		if (source_desc->common.type != ACPI_TYPE_STRING) {
 			ACPI_ERROR((AE_INFO, "Object not a String, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -186,7 +186,7 @@
 
 	case ACPI_TYPE_INTEGER:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
+		if (source_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index f6105a6..c93b54c 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -149,7 +149,7 @@
 
 	/* This is a union acpi_operand_object    */
 
-	switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
+	switch (stack_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		ref_type = stack_desc->reference.class;
@@ -297,8 +297,7 @@
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "FieldRead SourceDesc=%p Type=%X\n",
-				  stack_desc,
-				  ACPI_GET_OBJECT_TYPE(stack_desc)));
+				  stack_desc, stack_desc->common.type));
 
 		status =
 		    acpi_ex_read_data_from_field(walk_state, stack_desc,
@@ -386,7 +385,7 @@
 	 * specification of the object_type and size_of operators). This means
 	 * traversing the list of possibly many nested references.
 	 */
-	while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+	while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 		switch (obj_desc->reference.class) {
 		case ACPI_REFCLASS_REFOF:
 		case ACPI_REFCLASS_NAME:
@@ -518,7 +517,7 @@
 	 * Now we are guaranteed to have an object that has not been created
 	 * via the ref_of or Index operators.
 	 */
-	type = ACPI_GET_OBJECT_TYPE(obj_desc);
+	type = obj_desc->common.type;
 
       exit:
 	/* Convert internal types to external types */
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index 3c38027..5c729a9 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -212,7 +212,7 @@
 
 			/* ACPI internal object */
 
-			object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+			object_type = obj_desc->common.type;
 
 			/* Check for bad acpi_object_type */
 
@@ -287,8 +287,7 @@
 
 			if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
 			     ACPI_DESC_TYPE_OPERAND)
-			    && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
-				ACPI_TYPE_STRING)) {
+			    && (obj_desc->common.type == ACPI_TYPE_STRING)) {
 				/*
 				 * String found - the string references a named object and
 				 * must be resolved to a node
@@ -336,7 +335,7 @@
 			 * -- All others must be resolved below.
 			 */
 			if ((opcode == AML_STORE_OP) &&
-			    (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
+			    ((*stack_ptr)->common.type ==
 			     ACPI_TYPE_LOCAL_REFERENCE)
 			    && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
 				goto next_operand;
@@ -490,7 +489,7 @@
 
 			/* Need an operand of type INTEGER, STRING or BUFFER */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_INTEGER:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -512,7 +511,7 @@
 
 			/* Need an operand of type STRING or BUFFER */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
 
@@ -553,7 +552,7 @@
 			 * The only reference allowed here is a direct reference to
 			 * a namespace node.
 			 */
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -576,7 +575,7 @@
 
 			/* Need a buffer or package or (ACPI 2.0) String */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -598,7 +597,7 @@
 
 			/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_BUFFER:
 			case ACPI_TYPE_REGION:
 
@@ -619,7 +618,7 @@
 
 			/* Used by the Store() operator only */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_INTEGER:
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
@@ -677,8 +676,8 @@
 		 * required object type (Simple cases only).
 		 */
 		status = acpi_ex_check_object_type(type_needed,
-						   ACPI_GET_OBJECT_TYPE
-						   (*stack_ptr), *stack_ptr);
+						   (*stack_ptr)->common.type,
+						   *stack_ptr);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index e35e9b4..90d6061 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -129,7 +129,7 @@
 
 	/* source_desc is of type ACPI_DESC_TYPE_OPERAND */
 
-	switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+	switch (source_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Output correct integer width */
@@ -324,7 +324,7 @@
 
 	/* Destination object must be a Reference or a Constant object */
 
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 		break;
 
@@ -460,9 +460,8 @@
 		 */
 		obj_desc = *(index_desc->reference.where);
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) ==
-		    ACPI_TYPE_LOCAL_REFERENCE
-		    && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
+		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
+		    source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 
 			/* This is a DDBHandle, just add a reference to it */
 
@@ -520,8 +519,8 @@
 		 * by the INDEX_OP code.
 		 */
 		obj_desc = index_desc->reference.object;
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
-		    (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
+		if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
+		    (obj_desc->common.type != ACPI_TYPE_STRING)) {
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -529,7 +528,7 @@
 		 * The assignment of the individual elements will be slightly
 		 * different for each source type.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+		switch (source_desc->common.type) {
 		case ACPI_TYPE_INTEGER:
 
 			/* Use the least-significant byte of the integer */
@@ -707,8 +706,7 @@
 		/* No conversions for all other types.  Just attach the source object */
 
 		status = acpi_ns_attach_object(node, source_desc,
-					       ACPI_GET_OBJECT_TYPE
-					       (source_desc));
+					       source_desc->common.type);
 		break;
 	}
 
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index 145d153..608e838 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -96,8 +96,7 @@
 		 * are all essentially the same.  This case handles the
 		 * "interchangeable" types Integer, String, and Buffer.
 		 */
-		if (ACPI_GET_OBJECT_TYPE(source_desc) ==
-		    ACPI_TYPE_LOCAL_REFERENCE) {
+		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 
 			/* Resolve a reference object first */
 
@@ -117,13 +116,11 @@
 
 		/* Must have a Integer, Buffer, or String */
 
-		if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
-		    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
-		    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
-		    !((ACPI_GET_OBJECT_TYPE(source_desc) ==
-		       ACPI_TYPE_LOCAL_REFERENCE)
-		      && (source_desc->reference.class ==
-			  ACPI_REFCLASS_TABLE))) {
+		if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
+		    (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+		    (source_desc->common.type != ACPI_TYPE_STRING) &&
+		    !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+		      (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
 
 			/* Conversion successful but still not a valid type */
 
@@ -218,8 +215,7 @@
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(source_desc) !=
-	    ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	if (source_desc->common.type != dest_desc->common.type) {
 		/*
 		 * The source type does not match the type of the destination.
 		 * Perform the "implicit conversion" of the source to the current type
@@ -229,11 +225,10 @@
 		 * Otherwise, actual_src_desc is a temporary object to hold the
 		 * converted object.
 		 */
-		status =
-		    acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
-						   (dest_desc), source_desc,
-						   &actual_src_desc,
-						   walk_state);
+		status = acpi_ex_convert_to_target_type(dest_desc->common.type,
+							source_desc,
+							&actual_src_desc,
+							walk_state);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -252,7 +247,7 @@
 	 * We now have two objects of identical types, and we can perform a
 	 * copy of the *value* of the source object.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		dest_desc->integer.value = actual_src_desc->integer.value;
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index 32b85d6..87730e9 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -221,7 +221,7 @@
 	 */
 	if ((!obj_desc) ||
 	    (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+	    (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
 		return;
 	}
 
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index a9d4fea..9af361a 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -86,7 +86,8 @@
 	 */
 	if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
 		ACPI_ERROR((AE_INFO,
-			    "No ACPI mode transition supported in this system (enable/disable both zero)"));
+			    "No ACPI mode transition supported in this system "
+			    "(enable/disable both zero)"));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -95,7 +96,7 @@
 
 		/* BIOS should have disabled ALL fixed and GP events */
 
-		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 					    (u32) acpi_gbl_FADT.acpi_enable, 8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Attempting to enable ACPI mode\n"));
@@ -107,7 +108,7 @@
 		 * BIOS should clear all fixed status bits and restore fixed event
 		 * enable bits to default
 		 */
-		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 					    (u32) acpi_gbl_FADT.acpi_disable,
 					    8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -172,7 +173,7 @@
 		return_UINT32(ACPI_SYS_MODE_ACPI);
 	}
 
-	status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
+	status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
 	if (ACPI_FAILURE(status)) {
 		return_UINT32(ACPI_SYS_MODE_LEGACY);
 	}
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 2013b66..d3b7e37 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -89,10 +89,9 @@
 
 	/* Clear just the bit that corresponds to this GPE */
 
-	ACPI_CLEAR_BIT(enable_mask,
-		       ((u32) 1 <<
-			(gpe_event_info->gpe_number -
-			 gpe_register_info->base_gpe_number)));
+	ACPI_CLEAR_BIT(enable_mask, ((u32)1 <<
+				     (gpe_event_info->gpe_number -
+				      gpe_register_info->base_gpe_number)));
 
 	/* Write the updated enable mask */
 
@@ -156,10 +155,9 @@
 
 	ACPI_FUNCTION_ENTRY();
 
-	register_bit = (u8)
-	    (1 <<
-	     (gpe_event_info->gpe_number -
-	      gpe_event_info->register_info->base_gpe_number));
+	register_bit = (u8)(1 <<
+			    (gpe_event_info->gpe_number -
+			     gpe_event_info->register_info->base_gpe_number));
 
 	/*
 	 * Write a one to the appropriate bit in the status register to
@@ -206,10 +204,9 @@
 
 	/* Get the register bitmask for this GPE */
 
-	register_bit = (u8)
-	    (1 <<
-	     (gpe_event_info->gpe_number -
-	      gpe_event_info->register_info->base_gpe_number));
+	register_bit = (u8)(1 <<
+			    (gpe_event_info->gpe_number -
+			     gpe_event_info->register_info->base_gpe_number));
 
 	/* GPE currently enabled? (enabled for runtime?) */
 
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 4dc43b0..7b2fb60 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -51,6 +51,17 @@
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwregs")
 
+/* Local Prototypes */
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+		      struct acpi_generic_address *register_a,
+		      struct acpi_generic_address *register_b);
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+		       struct acpi_generic_address *register_a,
+		       struct acpi_generic_address *register_b);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_hw_clear_acpi_status
@@ -60,9 +71,9 @@
  * RETURN:      Status
  *
  * DESCRIPTION: Clears all fixed and general purpose status bits
- *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
+
 acpi_status acpi_hw_clear_acpi_status(void)
 {
 	acpi_status status;
@@ -70,28 +81,20 @@
 
 	ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
 			  ACPI_BITMASK_ALL_FIXED_STATUS,
-			  (u16) acpi_gbl_FADT.xpm1a_event_block.address));
+			  acpi_gbl_xpm1a_status.address));
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
+	/* Clear the fixed events in PM1 A/B */
+
 	status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
 					ACPI_BITMASK_ALL_FIXED_STATUS);
 	if (ACPI_FAILURE(status)) {
 		goto unlock_and_exit;
 	}
 
-	/* Clear the fixed events */
-
-	if (acpi_gbl_FADT.xpm1b_event_block.address) {
-		status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS,
-				    &acpi_gbl_FADT.xpm1b_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
-		}
-	}
-
 	/* Clear the GPE Bits in all GPE registers in all GPE blocks */
 
 	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
@@ -128,6 +131,42 @@
 
 /******************************************************************************
  *
+ * FUNCTION:    acpi_hw_write_pm1_control
+ *
+ * PARAMETERS:  pm1a_control        - Value to be written to PM1A control
+ *              pm1b_control        - Value to be written to PM1B control
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write the PM1 A/B control registers. These registers are
+ *              different than than the PM1 A/B status and enable registers
+ *              in that different values can be written to the A/B registers.
+ *              Most notably, the SLP_TYP bits can be different, as per the
+ *              values returned from the _Sx predefined methods.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(hw_write_pm1_control);
+
+	status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	if (acpi_gbl_FADT.xpm1b_control_block.address) {
+		status =
+		    acpi_write(pm1b_control,
+			       &acpi_gbl_FADT.xpm1b_control_block);
+	}
+	return_ACPI_STATUS(status);
+}
+
+/******************************************************************************
+ *
  * FUNCTION:    acpi_hw_register_read
  *
  * PARAMETERS:  register_id         - ACPI Register ID
@@ -141,64 +180,56 @@
 acpi_status
 acpi_hw_register_read(u32 register_id, u32 * return_value)
 {
-	u32 value1 = 0;
-	u32 value2 = 0;
+	u32 value = 0;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(hw_register_read);
 
 	switch (register_id) {
-	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block);
-		value1 |= value2;
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_xpm1a_status,
+					       &acpi_gbl_xpm1b_status);
 		break;
 
-	case ACPI_REGISTER_PM1_ENABLE:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value1, &acpi_gbl_xpm1a_enable);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_read(&value2, &acpi_gbl_xpm1b_enable);
-		value1 |= value2;
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_xpm1a_enable,
+					       &acpi_gbl_xpm1b_enable);
 		break;
 
-	case ACPI_REGISTER_PM1_CONTROL:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_FADT.
+					       xpm1a_control_block,
+					       &acpi_gbl_FADT.
+					       xpm1b_control_block);
 
-		status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block);
-		value1 |= value2;
+		/*
+		 * Zero the write-only bits. From the ACPI specification, "Hardware
+		 * Write-Only Bits": "Upon reads to registers with write-only bits,
+		 * software masks out all write-only bits."
+		 */
+		value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
 		break;
 
 	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block);
+		status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block);
 		break;
 
 	case ACPI_REGISTER_PM_TIMER:	/* 32-bit access */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block);
+		status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block);
 		break;
 
 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:	/* 8-bit access */
 
 		status =
-		    acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
+		    acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
 		break;
 
 	default:
@@ -207,10 +238,8 @@
 		break;
 	}
 
-      exit:
-
 	if (ACPI_SUCCESS(status)) {
-		*return_value = value1;
+		*return_value = value;
 	}
 
 	return_ACPI_STATUS(status);
@@ -250,52 +279,42 @@
 	ACPI_FUNCTION_TRACE(hw_register_write);
 
 	switch (register_id) {
-	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
+		/*
+		 * Handle the "ignored" bit in PM1 Status. According to the ACPI
+		 * specification, ignored bits are to be preserved when writing.
+		 * Normally, this would mean a read/modify/write sequence. However,
+		 * preserving a bit in the status register is different. Writing a
+		 * one clears the status, and writing a zero preserves the status.
+		 * Therefore, we must always write zero to the ignored bit.
+		 *
+		 * This behavior is clarified in the ACPI 4.0 specification.
+		 */
+		value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
 
-		/* Perform a read first to preserve certain bits (per ACPI spec) */
-
-		status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
-					       &read_value);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* Insert the bits to be preserved */
-
-		ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
-				 read_value);
-
-		/* Now we can write the data */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_xpm1a_status,
+						&acpi_gbl_xpm1b_status);
 		break;
 
-	case ACPI_REGISTER_PM1_ENABLE:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access */
 
-		status = acpi_write(value, &acpi_gbl_xpm1a_enable);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_write(value, &acpi_gbl_xpm1b_enable);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_xpm1a_enable,
+						&acpi_gbl_xpm1b_enable);
 		break;
 
-	case ACPI_REGISTER_PM1_CONTROL:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
 
 		/*
 		 * Perform a read first to preserve certain bits (per ACPI spec)
+		 * Note: This includes SCI_EN, we never want to change this bit
 		 */
-		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
-					       &read_value);
+		status = acpi_hw_read_multiple(&read_value,
+					       &acpi_gbl_FADT.
+					       xpm1a_control_block,
+					       &acpi_gbl_FADT.
+					       xpm1b_control_block);
 		if (ACPI_FAILURE(status)) {
 			goto exit;
 		}
@@ -307,25 +326,29 @@
 
 		/* Now we can write the data */
 
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_FADT.
+						xpm1a_control_block,
+						&acpi_gbl_FADT.
+						xpm1b_control_block);
+		break;
+
+	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
+
+		/*
+		 * For control registers, all reserved bits must be preserved,
+		 * as per the ACPI spec.
+		 */
+		status =
+		    acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block);
 		if (ACPI_FAILURE(status)) {
 			goto exit;
 		}
 
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
-		break;
+		/* Insert the bits to be preserved */
 
-	case ACPI_REGISTER_PM1A_CONTROL:	/* 16-bit access */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
-		break;
-
-	case ACPI_REGISTER_PM1B_CONTROL:	/* 16-bit access */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
-		break;
-
-	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
+		ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
+				 read_value);
 
 		status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block);
 		break;
@@ -340,10 +363,11 @@
 		/* SMI_CMD is currently always in IO space */
 
 		status =
-		    acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
+		    acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
 		break;
 
 	default:
+		ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -351,3 +375,103 @@
       exit:
 	return_ACPI_STATUS(status);
 }
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_read_multiple
+ *
+ * PARAMETERS:  Value               - Where the register value is returned
+ *              register_a           - First ACPI register (required)
+ *              register_b           - Second ACPI register (optional)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+		      struct acpi_generic_address *register_a,
+		      struct acpi_generic_address *register_b)
+{
+	u32 value_a = 0;
+	u32 value_b = 0;
+	acpi_status status;
+
+	/* The first register is always required */
+
+	status = acpi_read(&value_a, register_a);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Second register is optional */
+
+	if (register_b->address) {
+		status = acpi_read(&value_b, register_b);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+	}
+
+	/*
+	 * OR the two return values together. No shifting or masking is necessary,
+	 * because of how the PM1 registers are defined in the ACPI specification:
+	 *
+	 * "Although the bits can be split between the two register blocks (each
+	 * register block has a unique pointer within the FADT), the bit positions
+	 * are maintained. The register block with unimplemented bits (that is,
+	 * those implemented in the other register block) always returns zeros,
+	 * and writes have no side effects"
+	 */
+	*value = (value_a | value_b);
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_write_multiple
+ *
+ * PARAMETERS:  Value               - The value to write
+ *              register_a           - First ACPI register (required)
+ *              register_b           - Second ACPI register (optional)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+		       struct acpi_generic_address *register_a,
+		       struct acpi_generic_address *register_b)
+{
+	acpi_status status;
+
+	/* The first register is always required */
+
+	status = acpi_write(value, register_a);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/*
+	 * Second register is optional
+	 *
+	 * No bit shifting or clearing is necessary, because of how the PM1
+	 * registers are defined in the ACPI specification:
+	 *
+	 * "Although the bits can be split between the two register blocks (each
+	 * register block has a unique pointer within the FADT), the bit positions
+	 * are maintained. The register block with unimplemented bits (that is,
+	 * those implemented in the other register block) always returns zeros,
+	 * and writes have no side effects"
+	 */
+	if (register_b->address) {
+		status = acpi_write(value, register_b);
+	}
+
+	return (status);
+}
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index a2af2a4..baa5fc0 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -90,6 +90,7 @@
 
 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
 
+#if ACPI_MACHINE_WIDTH == 64
 /*******************************************************************************
  *
  * FUNCTION:    acpi_set_firmware_waking_vector64
@@ -100,7 +101,8 @@
  * RETURN:      Status
  *
  * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
- *              it exists in the table.
+ *              it exists in the table. This function is intended for use with
+ *              64-bit host operating systems.
  *
  ******************************************************************************/
 acpi_status
@@ -124,6 +126,7 @@
 }
 
 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
+#endif
 
 /*******************************************************************************
  *
@@ -147,9 +150,8 @@
 
 	ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
 
-	/*
-	 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
-	 */
+	/* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
+
 	status = acpi_get_sleep_type_data(sleep_state,
 					  &acpi_gbl_sleep_type_a,
 					  &acpi_gbl_sleep_type_b);
@@ -223,8 +225,8 @@
  ******************************************************************************/
 acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 {
-	u32 PM1Acontrol;
-	u32 PM1Bcontrol;
+	u32 pm1a_control;
+	u32 pm1b_control;
 	struct acpi_bit_register_info *sleep_type_reg_info;
 	struct acpi_bit_register_info *sleep_enable_reg_info;
 	u32 in_value;
@@ -242,13 +244,14 @@
 	}
 
 	sleep_type_reg_info =
-	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
 	sleep_enable_reg_info =
 	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
 
 	/* Clear wake status */
 
-	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	status =
+	    acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -289,24 +292,25 @@
 
 	/* Get current value of PM1A control */
 
-	status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+	status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+				       &pm1a_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
 			  "Entering sleep state [S%d]\n", sleep_state));
 
-	/* Clear SLP_EN and SLP_TYP fields */
+	/* Clear the SLP_EN and SLP_TYP fields */
 
-	PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
-			 sleep_enable_reg_info->access_bit_mask);
-	PM1Bcontrol = PM1Acontrol;
+	pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+			  sleep_enable_reg_info->access_bit_mask);
+	pm1b_control = pm1a_control;
 
-	/* Insert SLP_TYP bits */
+	/* Insert the SLP_TYP bits */
 
-	PM1Acontrol |=
+	pm1a_control |=
 	    (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
-	PM1Bcontrol |=
+	pm1b_control |=
 	    (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
 
 	/*
@@ -314,37 +318,25 @@
 	 * poorly implemented hardware.
 	 */
 
-	/* Write #1: fill in SLP_TYP data */
+	/* Write #1: write the SLP_TYP data to the PM1 Control registers */
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
+	status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	/* Insert the sleep enable (SLP_EN) bit */
 
-	/* Insert SLP_ENABLE bit */
+	pm1a_control |= sleep_enable_reg_info->access_bit_mask;
+	pm1b_control |= sleep_enable_reg_info->access_bit_mask;
 
-	PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
-	PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
-
-	/* Write #2: SLP_TYP + SLP_EN */
+	/* Flush caches, as per ACPI specification */
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	/* Write #2: Write both SLP_TYP + SLP_EN */
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
+	status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -357,8 +349,8 @@
 		 * Wait ten seconds, then try again. This is to get S4/S5 to work on
 		 * all machines.
 		 *
-		 * We wait so long to allow chipsets that poll this reg very slowly to
-		 * still read the right value. Ideally, this block would go
+		 * We wait so long to allow chipsets that poll this reg very slowly
+		 * to still read the right value. Ideally, this block would go
 		 * away entirely.
 		 */
 		acpi_os_stall(10000000);
@@ -374,7 +366,7 @@
 	/* Wait until we enter sleep state */
 
 	do {
-		status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+		status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
 						    &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
@@ -408,7 +400,10 @@
 
 	ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
 
-	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	/* Clear the wake status bit (PM1) */
+
+	status =
+	    acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -435,12 +430,13 @@
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+	status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 				    (u32) acpi_gbl_FADT.S4bios_request, 8);
 
 	do {
 		acpi_os_stall(1000);
-		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+		status =
+		    acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -471,8 +467,8 @@
 	acpi_status status;
 	struct acpi_bit_register_info *sleep_type_reg_info;
 	struct acpi_bit_register_info *sleep_enable_reg_info;
-	u32 PM1Acontrol;
-	u32 PM1Bcontrol;
+	u32 pm1a_control;
+	u32 pm1b_control;
 
 	ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
 
@@ -486,38 +482,34 @@
 					  &acpi_gbl_sleep_type_b);
 	if (ACPI_SUCCESS(status)) {
 		sleep_type_reg_info =
-		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
 		sleep_enable_reg_info =
 		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
 
 		/* Get current value of PM1A control */
 
 		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
-					       &PM1Acontrol);
+					       &pm1a_control);
 		if (ACPI_SUCCESS(status)) {
 
-			/* Clear SLP_EN and SLP_TYP fields */
+			/* Clear the SLP_EN and SLP_TYP fields */
 
-			PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
-					 sleep_enable_reg_info->
-					 access_bit_mask);
-			PM1Bcontrol = PM1Acontrol;
+			pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+					  sleep_enable_reg_info->
+					  access_bit_mask);
+			pm1b_control = pm1a_control;
 
-			/* Insert SLP_TYP bits */
+			/* Insert the SLP_TYP bits */
 
-			PM1Acontrol |=
-			    (acpi_gbl_sleep_type_a << sleep_type_reg_info->
-			     bit_position);
-			PM1Bcontrol |=
-			    (acpi_gbl_sleep_type_b << sleep_type_reg_info->
-			     bit_position);
+			pm1a_control |= (acpi_gbl_sleep_type_a <<
+					 sleep_type_reg_info->bit_position);
+			pm1b_control |= (acpi_gbl_sleep_type_b <<
+					 sleep_type_reg_info->bit_position);
 
-			/* Just ignore any errors */
+			/* Write the control registers and ignore any errors */
 
-			(void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-						     PM1Acontrol);
-			(void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-						     PM1Bcontrol);
+			(void)acpi_hw_write_pm1_control(pm1a_control,
+							pm1b_control);
 		}
 	}
 
@@ -603,19 +595,21 @@
 	 * it to determine whether the system is rebooting or resuming. Clear
 	 * it for compatibility.
 	 */
-	acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
 
 	acpi_gbl_system_awake_and_running = TRUE;
 
 	/* Enable power button */
 
 	(void)
-	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info
+			      [ACPI_EVENT_POWER_BUTTON].
+			      enable_register_id, ACPI_ENABLE_EVENT);
 
 	(void)
-	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info
+			      [ACPI_EVENT_POWER_BUTTON].
+			      status_register_id, ACPI_CLEAR_STATUS);
 
 	arg.integer.value = ACPI_SST_WORKING;
 	status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
new file mode 100644
index 0000000..bd3c937
--- /dev/null
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -0,0 +1,258 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwvalid - I/O request validation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, 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 "accommon.h"
+
+#define _COMPONENT          ACPI_HARDWARE
+ACPI_MODULE_NAME("hwvalid")
+
+/* Local prototypes */
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width);
+
+/*
+ * Protected I/O ports. Some ports are always illegal, and some are
+ * conditionally illegal. This table must remain ordered by port address.
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+ * ports are only illegal if the BIOS calls _OSI with a win_xP string or
+ * later (meaning that the BIOS itelf is post-XP.)
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+ *
+ * Description of port entries:
+ *  DMA:   DMA controller
+ *  PIC0:  Programmable Interrupt Controller (8259_a)
+ *  PIT1:  System Timer 1
+ *  PIT2:  System Timer 2 failsafe
+ *  RTC:   Real-time clock
+ *  CMOS:  Extended CMOS
+ *  DMA1:  DMA 1 page registers
+ *  DMA1L: DMA 1 Ch 0 low page
+ *  DMA2:  DMA 2 page registers
+ *  DMA2L: DMA 2 low page refresh
+ *  ARBC:  Arbitration control
+ *  SETUP: Reserved system board setup
+ *  POS:   POS channel select
+ *  PIC1:  Cascaded PIC
+ *  IDMA:  ISA DMA
+ *  ELCR:  PIC edge/level registers
+ *  PCI:   PCI configuration space
+ */
+static const struct acpi_port_info acpi_protected_ports[] = {
+	{"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP},
+	{"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
+	{"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP},
+	{"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
+	{"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
+	{"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+	{"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
+	{"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
+	{"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
+	{"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
+	{"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP},
+	{"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP},
+	{"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP},
+	{"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
+	{"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
+	{"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
+	{"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
+};
+
+#define ACPI_PORT_INFO_ENTRIES  ACPI_ARRAY_LENGTH (acpi_protected_ports)
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_validate_io_request
+ *
+ * PARAMETERS:  Address             Address of I/O port/register
+ *              bit_width           Number of bits (8,16,32)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
+ *              always illegal and some ports are only illegal depending on
+ *              the requests the BIOS AML code makes to the predefined
+ *              _OSI method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
+{
+	u32 i;
+	u32 byte_width;
+	acpi_io_address last_address;
+	const struct acpi_port_info *port_info;
+
+	ACPI_FUNCTION_TRACE(hw_validate_io_request);
+
+	/* Supported widths are 8/16/32 */
+
+	if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) {
+		return AE_BAD_PARAMETER;
+	}
+
+	port_info = acpi_protected_ports;
+	byte_width = ACPI_DIV_8(bit_width);
+	last_address = address + byte_width - 1;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X",
+			  ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void,
+								      last_address),
+			  byte_width));
+
+	/* Maximum 16-bit address in I/O space */
+
+	if (last_address > ACPI_UINT16_MAX) {
+		ACPI_ERROR((AE_INFO,
+			    "Illegal I/O port address/length above 64K: 0x%p/%X",
+			    ACPI_CAST_PTR(void, address), byte_width));
+		return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+	}
+
+	/* Exit if requested address is not within the protected port table */
+
+	if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/* Check request against the list of protected I/O ports */
+
+	for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, port_info++) {
+		/*
+		 * Check if the requested address range will write to a reserved
+		 * port. Four cases to consider:
+		 *
+		 * 1) Address range is contained completely in the port address range
+		 * 2) Address range overlaps port range at the port range start
+		 * 3) Address range overlaps port range at the port range end
+		 * 4) Address range completely encompasses the port range
+		 */
+		if ((address <= port_info->end)
+		    && (last_address >= port_info->start)) {
+
+			/* Port illegality may depend on the _OSI calls made by the BIOS */
+
+			if (acpi_gbl_osi_data >= port_info->osi_dependency) {
+				ACPI_ERROR((AE_INFO,
+					    "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+					    ACPI_CAST_PTR(void, address),
+					    byte_width, port_info->name,
+					    port_info->start, port_info->end));
+
+				return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+			}
+		}
+
+		/* Finished if address range ends before the end of this port */
+
+		if (last_address <= port_info->end) {
+			break;
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_read_port
+ *
+ * PARAMETERS:  Address             Address of I/O port/register to read
+ *              Value               Where value is placed
+ *              Width               Number of bits
+ *
+ * RETURN:      Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register. This is a front-end
+ *              to acpi_os_read_port that performs validation on both the port
+ *              address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+	acpi_status status;
+
+	status = acpi_hw_validate_io_request(address, width);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_os_read_port(address, value, width);
+	return status;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_write_port
+ *
+ * PARAMETERS:  Address             Address of I/O port/register to write
+ *              Value               Value to write
+ *              Width               Number of bits
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Write data to an I/O port or register. This is a front-end
+ *              to acpi_os_write_port that performs validation on both the port
+ *              address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
+{
+	acpi_status status;
+
+	status = acpi_hw_validate_io_request(address, width);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_os_write_port(address, value, width);
+	return status;
+}
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index ae597c0..9829979 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -107,19 +107,18 @@
 	ACPI_FUNCTION_NAME(acpi_read);
 
 	/*
-	 * Must have a valid pointer to a GAS structure, and
-	 * a non-zero address within. However, don't return an error
-	 * because the PM1A/B code must not fail if B isn't present.
+	 * Must have a valid pointer to a GAS structure, and a non-zero address
+	 * within.
 	 */
 	if (!reg) {
-		return (AE_OK);
+		return (AE_BAD_PARAMETER);
 	}
 
 	/* Get a local copy of the address. Handles possible alignment issues */
 
 	ACPI_MOVE_64_TO_64(&address, &reg->address);
 	if (!address) {
-		return (AE_OK);
+		return (AE_BAD_ADDRESS);
 	}
 
 	/* Supported widths are 8/16/32 */
@@ -134,8 +133,8 @@
 	*value = 0;
 
 	/*
-	 * Two address spaces supported: Memory or IO.
-	 * PCI_Config is not supported here because the GAS struct is insufficient
+	 * Two address spaces supported: Memory or IO. PCI_Config is
+	 * not supported here because the GAS structure is insufficient
 	 */
 	switch (reg->space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
@@ -147,7 +146,7 @@
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
 		status =
-		    acpi_os_read_port((acpi_io_address) address, value, width);
+		    acpi_hw_read_port((acpi_io_address) address, value, width);
 		break;
 
 	default:
@@ -187,19 +186,18 @@
 	ACPI_FUNCTION_NAME(acpi_write);
 
 	/*
-	 * Must have a valid pointer to a GAS structure, and
-	 * a non-zero address within. However, don't return an error
-	 * because the PM1A/B code must not fail if B isn't present.
+	 * Must have a valid pointer to a GAS structure, and a non-zero address
+	 * within.
 	 */
 	if (!reg) {
-		return (AE_OK);
+		return (AE_BAD_PARAMETER);
 	}
 
 	/* Get a local copy of the address. Handles possible alignment issues */
 
 	ACPI_MOVE_64_TO_64(&address, &reg->address);
 	if (!address) {
-		return (AE_OK);
+		return (AE_BAD_ADDRESS);
 	}
 
 	/* Supported widths are 8/16/32 */
@@ -222,7 +220,7 @@
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		status = acpi_os_write_port((acpi_io_address) address, value,
+		status = acpi_hw_write_port((acpi_io_address) address, value,
 					    width);
 		break;
 
@@ -244,24 +242,36 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_register_unlocked
+ * FUNCTION:    acpi_read_bit_register
  *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              return_value    - Value that was read from the register
+ * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
+ *              return_value    - Value that was read from the register,
+ *                                normalized to bit position zero.
  *
- * RETURN:      Status and the value read from specified Register. Value
+ * RETURN:      Status and the value read from the specified Register. Value
  *              returned is normalized to bit0 (is shifted all the way right)
  *
  * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
  *
+ * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ *              PM2 Control.
+ *
+ * Note: The hardware lock is not required when reading the ACPI bit registers
+ *       since almost all of them are single bit and it does not matter that
+ *       the parent hardware register can be split across two physical
+ *       registers. The only multi-bit field is SLP_TYP in the PM1 control
+ *       register, but this field does not cross an 8-bit boundary (nor does
+ *       it make much sense to actually read this field.)
+ *
  ******************************************************************************/
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
 {
-	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
+	u32 register_value;
+	u32 value;
 	acpi_status status;
 
-	ACPI_FUNCTION_TRACE(acpi_get_register_unlocked);
+	ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
 
 	/* Get the info structure corresponding to the requested ACPI Register */
 
@@ -270,209 +280,133 @@
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Read from the register */
+	/* Read the entire parent register */
 
 	status = acpi_hw_register_read(bit_reg_info->parent_register,
 				       &register_value);
-
-	if (ACPI_SUCCESS(status)) {
-
-		/* Normalize the value that was read */
-
-		register_value =
-		    ((register_value & bit_reg_info->access_bit_mask)
-		     >> bit_reg_info->bit_position);
-
-		*return_value = register_value;
-
-		ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
-				  register_value,
-				  bit_reg_info->parent_register));
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
 	}
 
-	return_ACPI_STATUS(status);
+	/* Normalize the value that was read, mask off other bits */
+
+	value = ((register_value & bit_reg_info->access_bit_mask)
+		 >> bit_reg_info->bit_position);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_IO,
+			  "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
+			  register_id, bit_reg_info->parent_register,
+			  register_value, value));
+
+	*return_value = value;
+	return_ACPI_STATUS(AE_OK);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked)
+ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_register
+ * FUNCTION:    acpi_write_bit_register
  *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              return_value    - Value that was read from the register
- *
- * RETURN:      Status and the value read from specified Register. Value
- *              returned is normalized to bit0 (is shifted all the way right)
- *
- * DESCRIPTION: ACPI bit_register read function.
- *
- ******************************************************************************/
-acpi_status acpi_get_register(u32 register_id, u32 *return_value)
-{
-	acpi_status status;
-	acpi_cpu_flags flags;
-
-	flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
-	status = acpi_get_register_unlocked(register_id, return_value);
-	acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
-
-	return (status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_get_register)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_set_register
- *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              Value           - (only used on write) value to write to the
- *                                Register, NOT pre-normalized to the bit pos
+ * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
+ *              Value           - Value to write to the register, in bit
+ *                                position zero. The bit is automaticallly
+ *                                shifted to the correct position.
  *
  * RETURN:      Status
  *
- * DESCRIPTION: ACPI Bit Register write function.
+ * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
+ *              since most operations require a read/modify/write sequence.
+ *
+ * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ *              PM2 Control.
+ *
+ * Note that at this level, the fact that there may be actually two
+ * hardware registers (A and B - and B may not exist) is abstracted.
  *
  ******************************************************************************/
-acpi_status acpi_set_register(u32 register_id, u32 value)
+acpi_status acpi_write_bit_register(u32 register_id, u32 value)
 {
-	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
-	acpi_status status;
 	acpi_cpu_flags lock_flags;
+	u32 register_value;
+	acpi_status status = AE_OK;
 
-	ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
+	ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
 
 	/* Get the info structure corresponding to the requested ACPI Register */
 
 	bit_reg_info = acpi_hw_get_bit_register_info(register_id);
 	if (!bit_reg_info) {
-		ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
-			    register_id));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
-	/* Always do a register read first so we can insert the new bits  */
-
-	status = acpi_hw_register_read(bit_reg_info->parent_register,
-				       &register_value);
-	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
-	}
-
 	/*
-	 * Decode the Register ID
-	 * Register ID = [Register block ID] | [bit ID]
-	 *
-	 * Check bit ID to fine locate Register offset.
-	 * Check Mask to determine Register offset, and then read-write.
+	 * At this point, we know that the parent register is one of the
+	 * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
 	 */
-	switch (bit_reg_info->parent_register) {
-	case ACPI_REGISTER_PM1_STATUS:
-
+	if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
 		/*
-		 * Status Registers are different from the rest. Clear by
-		 * writing 1, and writing 0 has no effect. So, the only relevant
-		 * information is the single bit we're interested in, all others should
-		 * be written as 0 so they will be left unchanged.
+		 * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
+		 *
+		 * Perform a register read to preserve the bits that we are not
+		 * interested in
 		 */
-		value = ACPI_REGISTER_PREPARE_BITS(value,
-						   bit_reg_info->bit_position,
-						   bit_reg_info->
-						   access_bit_mask);
-		if (value) {
-			status =
-			    acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
-						   (u16) value);
-			register_value = 0;
-		}
-		break;
-
-	case ACPI_REGISTER_PM1_ENABLE:
-
-		ACPI_REGISTER_INSERT_VALUE(register_value,
-					   bit_reg_info->bit_position,
-					   bit_reg_info->access_bit_mask,
-					   value);
-
-		status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
-						(u16) register_value);
-		break;
-
-	case ACPI_REGISTER_PM1_CONTROL:
-
-		/*
-		 * Write the PM1 Control register.
-		 * Note that at this level, the fact that there are actually TWO
-		 * registers (A and B - and B may not exist) is abstracted.
-		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
-				  register_value));
-
-		ACPI_REGISTER_INSERT_VALUE(register_value,
-					   bit_reg_info->bit_position,
-					   bit_reg_info->access_bit_mask,
-					   value);
-
-		status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
-						(u16) register_value);
-		break;
-
-	case ACPI_REGISTER_PM2_CONTROL:
-
-		status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
+		status = acpi_hw_register_read(bit_reg_info->parent_register,
 					       &register_value);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
 
-		ACPI_DEBUG_PRINT((ACPI_DB_IO,
-				  "PM2 control: Read %X from %8.8X%8.8X\n",
-				  register_value,
-				  ACPI_FORMAT_UINT64(acpi_gbl_FADT.
-						     xpm2_control_block.
-						     address)));
-
+		/*
+		 * Insert the input bit into the value that was just read
+		 * and write the register
+		 */
 		ACPI_REGISTER_INSERT_VALUE(register_value,
 					   bit_reg_info->bit_position,
 					   bit_reg_info->access_bit_mask,
 					   value);
 
-		ACPI_DEBUG_PRINT((ACPI_DB_IO,
-				  "About to write %4.4X to %8.8X%8.8X\n",
-				  register_value,
-				  ACPI_FORMAT_UINT64(acpi_gbl_FADT.
-						     xpm2_control_block.
-						     address)));
+		status = acpi_hw_register_write(bit_reg_info->parent_register,
+						register_value);
+	} else {
+		/*
+		 * 2) Case for PM1 Status
+		 *
+		 * The Status register is different from the rest. Clear an event
+		 * by writing 1, writing 0 has no effect. So, the only relevant
+		 * information is the single bit we're interested in, all others
+		 * should be written as 0 so they will be left unchanged.
+		 */
+		register_value = ACPI_REGISTER_PREPARE_BITS(value,
+							    bit_reg_info->
+							    bit_position,
+							    bit_reg_info->
+							    access_bit_mask);
 
-		status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
-						(u8) (register_value));
-		break;
+		/* No need to write the register if value is all zeros */
 
-	default:
-		break;
+		if (register_value) {
+			status =
+			    acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+						   register_value);
+		}
 	}
 
-      unlock_and_exit:
+	ACPI_DEBUG_PRINT((ACPI_DB_IO,
+			  "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
+			  register_id, bit_reg_info->parent_register, value,
+			  register_value));
+
+unlock_and_exit:
 
 	acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-
-	/* Normalize the value that was read */
-
-	ACPI_DEBUG_EXEC(register_value =
-			((register_value & bit_reg_info->access_bit_mask) >>
-			 bit_reg_info->bit_position));
-
-	ACPI_DEBUG_PRINT((ACPI_DB_IO,
-			  "Set bits: %8.8X actual %8.8X register %X\n", value,
-			  register_value, bit_reg_info->parent_register));
 	return_ACPI_STATUS(status);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_set_register)
+ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
 
 /*******************************************************************************
  *
@@ -534,7 +468,7 @@
 
 	/* It must be of type Package */
 
-	else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
+	else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
 		ACPI_ERROR((AE_INFO,
 			    "Sleep State return object is not a Package"));
 		status = AE_AML_OPERAND_TYPE;
@@ -555,12 +489,13 @@
 
 	/* The first two elements must both be of type Integer */
 
-	else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
+	else if (((info->return_object->package.elements[0])->common.type
 		  != ACPI_TYPE_INTEGER) ||
-		 (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
+		 ((info->return_object->package.elements[1])->common.type
 		  != ACPI_TYPE_INTEGER)) {
 		ACPI_ERROR((AE_INFO,
-			    "Sleep State return package elements are not both Integers (%s, %s)",
+			    "Sleep State return package elements are not both Integers "
+			    "(%s, %s)",
 			    acpi_ut_get_object_type_name(info->return_object->
 							 package.elements[0]),
 			    acpi_ut_get_object_type_name(info->return_object->
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
index 88303eb..9c3cdbe 100644
--- a/drivers/acpi/acpica/nsaccess.c
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -118,9 +118,8 @@
 		}
 
 		/*
-		 * Name entered successfully.
-		 * If entry in pre_defined_names[] specifies an
-		 * initial value, create the initial value.
+		 * Name entered successfully. If entry in pre_defined_names[] specifies
+		 * an initial value, create the initial value.
 		 */
 		if (init_val->val) {
 			status = acpi_os_predefined_override(init_val, &val);
@@ -178,9 +177,8 @@
 
 			case ACPI_TYPE_STRING:
 
-				/*
-				 * Build an object around the static string
-				 */
+				/* Build an object around the static string */
+
 				obj_desc->string.length =
 				    (u32) ACPI_STRLEN(val);
 				obj_desc->string.pointer = val;
@@ -234,8 +232,7 @@
 			/* Store pointer to value descriptor in the Node */
 
 			status = acpi_ns_attach_object(new_node, obj_desc,
-						       ACPI_GET_OBJECT_TYPE
-						       (obj_desc));
+						       obj_desc->common.type);
 
 			/* Remove local reference to the object */
 
@@ -315,10 +312,8 @@
 		return_ACPI_STATUS(AE_NO_NAMESPACE);
 	}
 
-	/*
-	 * Get the prefix scope.
-	 * A null scope means use the root scope
-	 */
+	/* Get the prefix scope. A null scope means use the root scope */
+
 	if ((!scope_info) || (!scope_info->scope.node)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 				  "Null scope prefix, using root node (%p)\n",
@@ -338,8 +333,8 @@
 		if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
 			/*
 			 * This node might not be a actual "scope" node (such as a
-			 * Device/Method, etc.)  It could be a Package or other object node.
-			 * Backup up the tree to find the containing scope node.
+			 * Device/Method, etc.)  It could be a Package or other object
+			 * node. Backup up the tree to find the containing scope node.
 			 */
 			while (!acpi_ns_opens_scope(prefix_node->type) &&
 			       prefix_node->type != ACPI_TYPE_ANY) {
@@ -349,7 +344,7 @@
 		}
 	}
 
-	/* Save type   TBD: may be no longer necessary */
+	/* Save type. TBD: may be no longer necessary */
 
 	type_to_check_for = type;
 
@@ -414,6 +409,7 @@
 				/* Name is fully qualified, no search rules apply */
 
 				search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
 				/*
 				 * Point past this prefix to the name segment
 				 * part or the next Parent Prefix
@@ -429,7 +425,8 @@
 					/* Current scope has no parent scope */
 
 					ACPI_ERROR((AE_INFO,
-						    "ACPI path has too many parent prefixes (^) - reached beyond root node"));
+						    "ACPI path has too many parent prefixes (^) "
+						    "- reached beyond root node"));
 					return_ACPI_STATUS(AE_NOT_FOUND);
 				}
 			}
@@ -531,9 +528,9 @@
 	while (num_segments && current_node) {
 		num_segments--;
 		if (!num_segments) {
-			/*
-			 * This is the last segment, enable typechecking
-			 */
+
+			/* This is the last segment, enable typechecking */
+
 			this_search_type = type;
 
 			/*
@@ -584,9 +581,9 @@
 		if (num_segments > 0) {
 			/*
 			 * If we have an alias to an object that opens a scope (such as a
-			 * device or processor), we need to dereference the alias here so that
-			 * we can access any children of the original node (via the remaining
-			 * segments).
+			 * device or processor), we need to dereference the alias here so
+			 * that we can access any children of the original node (via the
+			 * remaining segments).
 			 */
 			if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
 				if (!this_node->object) {
@@ -594,8 +591,8 @@
 				}
 
 				if (acpi_ns_opens_scope
-				    (((struct acpi_namespace_node *)this_node->
-				      object)->type)) {
+				    (((struct acpi_namespace_node *)
+				      this_node->object)->type)) {
 					this_node =
 					    (struct acpi_namespace_node *)
 					    this_node->object;
@@ -639,8 +636,8 @@
 
 			/*
 			 * If this is the last name segment and we are not looking for a
-			 * specific type, but the type of found object is known, use that type
-			 * to (later) see if it opens a scope.
+			 * specific type, but the type of found object is known, use that
+			 * type to (later) see if it opens a scope.
 			 */
 			if (type == ACPI_TYPE_ANY) {
 				type = this_node->type;
@@ -653,9 +650,8 @@
 		current_node = this_node;
 	}
 
-	/*
-	 * Always check if we need to open a new scope
-	 */
+	/* Always check if we need to open a new scope */
+
 	if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
 		/*
 		 * If entry is a type which opens a scope, push the new scope on the
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index f976d84..aceb931 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -76,8 +76,7 @@
 	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
 
 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
-	temp =
-	    acpi_gbl_ns_node_list->total_allocated -
+	temp = acpi_gbl_ns_node_list->total_allocated -
 	    acpi_gbl_ns_node_list->total_freed;
 	if (temp > acpi_gbl_ns_node_list->max_occupied) {
 		acpi_gbl_ns_node_list->max_occupied = temp;
@@ -145,9 +144,8 @@
 
 	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
 
-	/*
-	 * Detach an object if there is one, then delete the node
-	 */
+	/* Detach an object if there is one, then delete the node */
+
 	acpi_ns_detach_object(node);
 	(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
 	return_VOID;
@@ -183,9 +181,8 @@
 	ACPI_FUNCTION_TRACE(ns_install_node);
 
 	/*
-	 * Get the owner ID from the Walk state
-	 * The owner ID is used to track table deletion and
-	 * deletion of objects created by methods
+	 * Get the owner ID from the Walk state. The owner ID is used to track
+	 * table deletion and deletion of objects created by methods.
 	 */
 	if (walk_state) {
 		owner_id = walk_state->owner_id;
@@ -260,9 +257,8 @@
 		return_VOID;
 	}
 
-	/*
-	 * Deallocate all children at this level
-	 */
+	/* Deallocate all children at this level */
+
 	do {
 
 		/* Get the things we need */
@@ -285,9 +281,8 @@
 				  "Object %p, Remaining %X\n", child_node,
 				  acpi_gbl_current_node_count));
 
-		/*
-		 * Detach an object if there is one, then free the child node
-		 */
+		/* Detach an object if there is one, then free the child node */
+
 		acpi_ns_detach_object(child_node);
 
 		/* Now we can delete the node */
@@ -304,7 +299,6 @@
 	/* Clear the parent's child pointer */
 
 	parent_node->child = NULL;
-
 	return_VOID;
 }
 
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 0da33c8..2bad613 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -181,6 +181,12 @@
 	}
 
 	this_node = acpi_ns_map_handle_to_node(obj_handle);
+	if (!this_node) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
+				  obj_handle));
+		return (AE_OK);
+	}
+
 	type = this_node->type;
 
 	/* Check if the owner matches */
@@ -214,9 +220,8 @@
 		acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
 	}
 
-	/*
-	 * Now we can print out the pertinent information
-	 */
+	/* Now we can print out the pertinent information */
+
 	acpi_os_printf(" %-12s %p %2.2X ",
 		       acpi_ut_get_type_name(type), this_node,
 		       this_node->owner_id);
@@ -509,7 +514,7 @@
 
 		case ACPI_DESC_TYPE_OPERAND:
 
-			obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+			obj_type = obj_desc->common.type;
 
 			if (obj_type > ACPI_TYPE_LOCAL_MAX) {
 				acpi_os_printf
@@ -539,9 +544,8 @@
 			goto cleanup;
 		}
 
-		/*
-		 * Valid object, get the pointer to next level, if any
-		 */
+		/* Valid object, get the pointer to next level, if any */
+
 		switch (obj_type) {
 		case ACPI_TYPE_BUFFER:
 		case ACPI_TYPE_STRING:
@@ -602,14 +606,14 @@
  *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
  *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
  *                                    for an effectively unlimited depth.
- *              owner_id            - Dump only objects owned by this ID.  Use
+ *              owner_id            - Dump only objects owned by this ID. Use
  *                                    ACPI_UINT32_MAX to match all owners.
  *              start_handle        - Where in namespace to start/end search
  *
  * RETURN:      None
  *
- * DESCRIPTION: Dump typed objects within the loaded namespace.
- *              Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
+ * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
+ *              acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index 0f3d5f9..8e7dec1 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -155,7 +155,7 @@
 		}
 
 
-		ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
+		ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
 				   ACPI_LV_INFO, _COMPONENT);
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 13501cb..2adfcf3 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -103,7 +103,8 @@
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
+			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd "
+			      "Buffers %hd/%hd Packages (%hd nodes)\n",
 			      info.op_region_init, info.op_region_count,
 			      info.field_init, info.field_count,
 			      info.buffer_init, info.buffer_count,
@@ -148,7 +149,8 @@
 	info.num_INI = 0;
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "Initializing Device/Processor/Thermal objects by executing _INI methods:"));
+			      "Initializing Device/Processor/Thermal objects "
+			      "by executing _INI methods:"));
 
 	/* Tree analysis: find all subtrees that contain _INI methods */
 
@@ -180,7 +182,8 @@
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",
+			      "\nExecuted %hd _INI methods requiring %hd _STA executions "
+			      "(examined %hd objects)\n",
 			      info.num_INI, info.num_STA, info.device_count));
 
 	return_ACPI_STATUS(status);
@@ -263,16 +266,14 @@
 		return (AE_OK);
 	}
 
-	/*
-	 * If the object is already initialized, nothing else to do
-	 */
+	/* If the object is already initialized, nothing else to do */
+
 	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
 		return (AE_OK);
 	}
 
-	/*
-	 * Must lock the interpreter before executing AML code
-	 */
+	/* Must lock the interpreter before executing AML code */
+
 	acpi_ex_enter_interpreter();
 
 	/*
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index a0ba9e1..dcd7a6a 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -128,12 +128,12 @@
 	 * parse trees.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Begin Table Method Parsing and Object Initialization ****\n"));
+			  "**** Begin Table Method Parsing and Object Initialization\n"));
 
 	status = acpi_ds_initialize_objects(table_index, node);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Completed Table Method Parsing and Object Initialization ****\n"));
+			  "**** Completed Table Method Parsing and Object Initialization\n"));
 
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index 08a97a5..3eb20bf 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -209,8 +209,7 @@
 
 	obj_desc = node->object;
 
-	if (!obj_desc ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+	if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
 		return_VOID;
 	}
 
@@ -220,8 +219,7 @@
 	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
 		node->object = obj_desc->common.next_object;
 		if (node->object &&
-		    (ACPI_GET_OBJECT_TYPE(node->object) !=
-		     ACPI_TYPE_LOCAL_DATA)) {
+		    ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) {
 			node->object = node->object->common.next_object;
 		}
 	}
@@ -267,7 +265,7 @@
 	    ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
 	     && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
 		 ACPI_DESC_TYPE_NAMED))
-	    || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
+	    || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
 		return_PTR(NULL);
 	}
 
@@ -294,9 +292,9 @@
 	ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
 
 	if ((!obj_desc) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
+	    (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
 	    (!obj_desc->common.next_object) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
+	    ((obj_desc->common.next_object)->common.type ==
 	     ACPI_TYPE_LOCAL_DATA)) {
 		return_PTR(NULL);
 	}
@@ -331,7 +329,7 @@
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			return (AE_ALREADY_EXISTS);
 		}
@@ -385,7 +383,7 @@
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			if (prev_obj_desc) {
 				prev_obj_desc->common.next_object =
@@ -428,7 +426,7 @@
 
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			*data = obj_desc->data.pointer;
 			return (AE_OK);
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index b9e8d00..662a4bd 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -176,9 +176,8 @@
 	 * performs another complete parse of the AML.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
-	status =
-	    acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
-				       start_node);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
+					    table_index, start_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -193,9 +192,8 @@
 	 * parse objects are all cached.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
-	status =
-	    acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
-				       start_node);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
+					    table_index, start_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 4527032..d9e8cbc 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -79,7 +79,9 @@
 static acpi_status
 acpi_ns_check_package_elements(char *pathname,
 			       union acpi_operand_object **elements,
-			       u8 type1, u32 count1, u8 type2, u32 count2);
+			       u8 type1,
+			       u32 count1,
+			       u8 type2, u32 count2, u32 start_index);
 
 static acpi_status
 acpi_ns_check_object_type(char *pathname,
@@ -221,7 +223,7 @@
 
 	/* For returned Package objects, check the type of all sub-objects */
 
-	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+	if (return_object->common.type == ACPI_TYPE_PACKAGE) {
 		status =
 		    acpi_ns_check_package(pathname, return_object_ptr,
 					  predefined);
@@ -302,7 +304,8 @@
 		if ((user_param_count != required_params_current) &&
 		    (user_param_count != required_params_old)) {
 			ACPI_WARNING((AE_INFO,
-				      "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
+				      "%s: Parameter count mismatch - "
+				      "caller passed %d, ACPI requires %d",
 				      pathname, user_param_count,
 				      required_params_current));
 		}
@@ -472,7 +475,7 @@
 							package->ret_info.
 							object_type2,
 							package->ret_info.
-							count2);
+							count2, 0);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -623,7 +626,7 @@
 								   object_type2,
 								   package->
 								   ret_info.
-								   count2);
+								   count2, 0);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -672,7 +675,8 @@
 								   object_type1,
 								   sub_package->
 								   package.
-								   count, 0, 0);
+								   count, 0, 0,
+								   0);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -710,7 +714,8 @@
 								   ret_info.
 								   object_type1,
 								   (expected_count
-								    - 1), 0, 0);
+								    - 1), 0, 0,
+								   1);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -758,6 +763,7 @@
  *              Count1          - Count for first group
  *              Type2           - Object type for second group
  *              Count2          - Count for second group
+ *              start_index     - Start of the first group of elements
  *
  * RETURN:      Status
  *
@@ -769,7 +775,9 @@
 static acpi_status
 acpi_ns_check_package_elements(char *pathname,
 			       union acpi_operand_object **elements,
-			       u8 type1, u32 count1, u8 type2, u32 count2)
+			       u8 type1,
+			       u32 count1,
+			       u8 type2, u32 count2, u32 start_index)
 {
 	union acpi_operand_object **this_element = elements;
 	acpi_status status;
@@ -782,7 +790,7 @@
 	 */
 	for (i = 0; i < count1; i++) {
 		status = acpi_ns_check_object_type(pathname, this_element,
-						   type1, i);
+						   type1, i + start_index);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -791,7 +799,8 @@
 
 	for (i = 0; i < count2; i++) {
 		status = acpi_ns_check_object_type(pathname, this_element,
-						   type2, (i + count1));
+						   type2,
+						   (i + count1 + start_index));
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -858,7 +867,7 @@
 	 * from all of the predefined names (including elements of returned
 	 * packages)
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+	switch (return_object->common.type) {
 	case ACPI_TYPE_INTEGER:
 		return_btype = ACPI_RTYPE_INTEGER;
 		break;
@@ -901,7 +910,7 @@
 
 	/* For reference objects, check that the reference type is correct */
 
-	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+	if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 		status = acpi_ns_check_reference(pathname, return_object);
 	}
 
@@ -974,7 +983,8 @@
 	}
 
 	ACPI_WARNING((AE_INFO,
-		      "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+		      "%s: Return type mismatch - "
+		      "unexpected reference object type [%s] %2.2X",
 		      pathname, acpi_ut_get_reference_name(return_object),
 		      return_object->reference.class));
 
@@ -1006,7 +1016,7 @@
 	union acpi_operand_object *new_object;
 	acpi_size length;
 
-	switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+	switch (return_object->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		if (!(expected_btypes & ACPI_RTYPE_STRING)) {
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index 6fea13f..f9b4f51 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -167,7 +167,8 @@
 	/* Searched entire namespace level, not found */
 
 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
+			  "%p first child %p\n",
 			  ACPI_CAST_PTR(char, &target_name),
 			  acpi_ut_get_type_name(type),
 			  acpi_ut_get_node_name(parent_node), parent_node,
@@ -239,9 +240,8 @@
 			  acpi_ut_get_node_name(parent_node),
 			  ACPI_CAST_PTR(char, &target_name)));
 
-	/*
-	 * Search parents until target is found or we have backed up to the root
-	 */
+	/* Search parents until target is found or we have backed up to the root */
+
 	while (parent_node) {
 		/*
 		 * Search parent scope. Use TYPE_ANY because we don't care about the
@@ -395,9 +395,9 @@
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 #ifdef ACPI_ASL_COMPILER
-	/*
-	 * Node is an object defined by an External() statement
-	 */
+
+	/* Node is an object defined by an External() statement */
+
 	if (flags & ACPI_NS_EXTERNAL) {
 		new_node->flags |= ANOBJ_IS_EXTERNAL;
 	}
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
index 3e1149b..78277ed 100644
--- a/drivers/acpi/acpica/nsutils.c
+++ b/drivers/acpi/acpica/nsutils.c
@@ -325,9 +325,8 @@
 			next_external_char++;
 		}
 	} else {
-		/*
-		 * Handle Carat prefixes
-		 */
+		/* Handle Carat prefixes */
+
 		while (*next_external_char == '^') {
 			info->num_carats++;
 			next_external_char++;
@@ -552,9 +551,8 @@
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Check for a prefix (one '\' | one or more '^').
-	 */
+	/* Check for a prefix (one '\' | one or more '^') */
+
 	switch (internal_name[0]) {
 	case '\\':
 		prefix_length = 1;
@@ -580,7 +578,7 @@
 	}
 
 	/*
-	 * Check for object names.  Note that there could be 0-255 of these
+	 * Check for object names. Note that there could be 0-255 of these
 	 * 4-byte elements.
 	 */
 	if (prefix_length < internal_name_length) {
@@ -637,9 +635,8 @@
 		return_ACPI_STATUS(AE_BAD_PATHNAME);
 	}
 
-	/*
-	 * Build converted_name
-	 */
+	/* Build the converted_name */
+
 	*converted_name = ACPI_ALLOCATE_ZEROED(required_length);
 	if (!(*converted_name)) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
@@ -685,6 +682,9 @@
  *       and keep all pointers within this subsystem - however this introduces
  *       more (and perhaps unnecessary) overhead.
  *
+ * The current implemenation is basically a placeholder until such time comes
+ * that it is needed.
+ *
  ******************************************************************************/
 
 struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
@@ -692,9 +692,8 @@
 
 	ACPI_FUNCTION_ENTRY();
 
-	/*
-	 * Simple implementation
-	 */
+	/* Parameter validation */
+
 	if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
 		return (acpi_gbl_root_node);
 	}
@@ -872,7 +871,7 @@
 				(flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
 				return_node);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
 				  pathname, acpi_format_exception(status)));
 	}
 
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 200895f..83e3aa6 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -135,8 +135,8 @@
  *              starting (and ending) at the node specified by start_handle.
  *              The user_function is called whenever a node that matches
  *              the type parameter is found.  If the user function returns
- *              a non-zero value, the search is terminated immediately and this
- *              value is returned to the caller.
+ *              a non-zero value, the search is terminated immediately and
+ *              this value is returned to the caller.
  *
  *              The point of this procedure is to provide a generic namespace
  *              walk routine that can be called from multiple places to
@@ -200,10 +200,10 @@
 			/*
 			 * Ignore all temporary namespace nodes (created during control
 			 * method execution) unless told otherwise. These temporary nodes
-			 * can cause a race condition because they can be deleted during the
-			 * execution of the user function (if the namespace is unlocked before
-			 * invocation of the user function.) Only the debugger namespace dump
-			 * will examine the temporary nodes.
+			 * can cause a race condition because they can be deleted during
+			 * the execution of the user function (if the namespace is
+			 * unlocked before invocation of the user function.) Only the
+			 * debugger namespace dump will examine the temporary nodes.
 			 */
 			if ((child_node->flags & ANOBJ_TEMPORARY) &&
 			    !(flags & ACPI_NS_WALK_TEMP_NODES)) {
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 22a7171..0450540 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -387,8 +387,7 @@
 
 	/* We are interested in reference objects only */
 
-	if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
-	    ACPI_TYPE_LOCAL_REFERENCE) {
+	if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
 		return;
 	}
 
@@ -476,21 +475,40 @@
 	}
 
 	/*
-	 * Lock the namespace around the walk.
-	 * The namespace will be unlocked/locked around each call
-	 * to the user function - since this function
-	 * must be allowed to make Acpi calls itself.
+	 * Need to acquire the namespace reader lock to prevent interference
+	 * with any concurrent table unloads (which causes the deletion of
+	 * namespace objects). We cannot allow the deletion of a namespace node
+	 * while the user function is using it. The exception to this are the
+	 * nodes created and deleted during control method execution -- these
+	 * nodes are marked as temporary nodes and are ignored by the namespace
+	 * walk. Thus, control methods can be executed while holding the
+	 * namespace deletion lock (and the user function can execute control
+	 * methods.)
+	 */
+	status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/*
+	 * Lock the namespace around the walk. The namespace will be
+	 * unlocked/locked around each call to the user function - since the user
+	 * function must be allowed to make ACPICA calls itself (for example, it
+	 * will typically execute control methods during device enumeration.)
 	 */
 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+		goto unlock_and_exit;
 	}
 
 	status = acpi_ns_walk_namespace(type, start_object, max_depth,
-					ACPI_NS_WALK_UNLOCK,
-					user_function, context, return_value);
+					ACPI_NS_WALK_UNLOCK, user_function,
+					context, return_value);
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+      unlock_and_exit:
+	(void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
 	return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 52865ee..b6667ff 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -557,9 +557,9 @@
 		     table_index++) {
 			if (*sub_object_list &&	/* Null object allowed */
 			    ((ACPI_TYPE_STRING ==
-			      ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
+			      (*sub_object_list)->common.type) ||
 			     ((ACPI_TYPE_LOCAL_REFERENCE ==
-			       ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
+			       (*sub_object_list)->common.type) &&
 			      ((*sub_object_list)->reference.class ==
 			       ACPI_REFCLASS_NAME)))) {
 				name_found = TRUE;
@@ -575,8 +575,7 @@
 		/* Was a String type found? */
 
 		if (name_found) {
-			if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
-			    ACPI_TYPE_STRING) {
+			if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
 				/*
 				 * The length String.Length field does not include the
 				 * terminating NULL, add 1
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index 61566b1..663f692 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -212,7 +212,7 @@
 
 		/* Each element of the top-level package must also be a package */
 
-		if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
+		if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X]) Need sub-package, found %s",
 				    index,
@@ -240,7 +240,7 @@
 		/* 1) First subobject: Dereference the PRT.Address */
 
 		obj_desc = sub_object_list[0];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].Address) Need Integer, found %s",
 				    index,
@@ -253,7 +253,7 @@
 		/* 2) Second subobject: Dereference the PRT.Pin */
 
 		obj_desc = sub_object_list[1];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].Pin) Need Integer, found %s",
 				    index,
@@ -265,7 +265,7 @@
 		 * If BIOS erroneously reversed the _PRT source_name and source_index,
 		 * then reverse them back.
 		 */
-		if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
+		if ((sub_object_list[3])->common.type !=
 		    ACPI_TYPE_INTEGER) {
 			if (acpi_gbl_enable_interpreter_slack) {
 				source_name_index = 3;
@@ -291,8 +291,7 @@
 		 * other ACPI implementations.
 		 */
 		obj_desc = sub_object_list[3];
-		if (!obj_desc
-		    || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+		if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
 			sub_object_list[3] = sub_object_list[2];
 			sub_object_list[2] = obj_desc;
 
@@ -307,7 +306,7 @@
 		 */
 		obj_desc = sub_object_list[source_name_index];
 		if (obj_desc) {
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
 
 				if (obj_desc->reference.class !=
@@ -380,7 +379,7 @@
 		/* 4) Fourth subobject: Dereference the PRT.source_index */
 
 		obj_desc = sub_object_list[source_index_index];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].SourceIndex) Need Integer, found %s",
 				    index,
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 3636e4f..71e655d 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -57,6 +57,8 @@
 
 static void acpi_tb_validate_fadt(void);
 
+static void acpi_tb_setup_fadt_registers(void);
+
 /* Table for conversion of FADT to common internal format and FADT validation */
 
 typedef struct acpi_fadt_info {
@@ -130,7 +132,38 @@
 	 ACPI_FADT_SEPARATE_LENGTH}
 };
 
-#define ACPI_FADT_INFO_ENTRIES        (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+#define ACPI_FADT_INFO_ENTRIES \
+			(sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info {
+	struct acpi_generic_address *target;
+	u8 source;
+	u8 register_num;
+
+} acpi_fadt_pm_info;
+
+static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
+	{&acpi_gbl_xpm1a_status,
+	 ACPI_FADT_OFFSET(xpm1a_event_block),
+	 0},
+
+	{&acpi_gbl_xpm1a_enable,
+	 ACPI_FADT_OFFSET(xpm1a_event_block),
+	 1},
+
+	{&acpi_gbl_xpm1b_status,
+	 ACPI_FADT_OFFSET(xpm1b_event_block),
+	 0},
+
+	{&acpi_gbl_xpm1b_enable,
+	 ACPI_FADT_OFFSET(xpm1b_event_block),
+	 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+			(sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
 
 /*******************************************************************************
  *
@@ -172,7 +205,6 @@
  * FUNCTION:    acpi_tb_parse_fadt
  *
  * PARAMETERS:  table_index         - Index for the FADT
- *              Flags               - Flags
  *
  * RETURN:      None
  *
@@ -181,7 +213,7 @@
  *
  ******************************************************************************/
 
-void acpi_tb_parse_fadt(u32 table_index, u8 flags)
+void acpi_tb_parse_fadt(u32 table_index)
 {
 	u32 length;
 	struct acpi_table_header *table;
@@ -208,7 +240,7 @@
 	 */
 	(void)acpi_tb_verify_checksum(table, length);
 
-	/* Obtain a local copy of the FADT in common ACPI 2.0+ format */
+	/* Create a local copy of the FADT in common ACPI 2.0+ format */
 
 	acpi_tb_create_local_fadt(table, length);
 
@@ -219,10 +251,10 @@
 	/* Obtain the DSDT and FACS tables via their addresses within the FADT */
 
 	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
-			      flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+			      ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
 
 	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
-			      flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+			      ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
 }
 
 /*******************************************************************************
@@ -266,11 +298,17 @@
 	ACPI_MEMCPY(&acpi_gbl_FADT, table,
 		    ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
 
-	/*
-	 * 1) Convert the local copy of the FADT to the common internal format
-	 * 2) Validate some of the important values within the FADT
-	 */
+	/* Convert the local copy of the FADT to the common internal format */
+
 	acpi_tb_convert_fadt();
+
+	/* Validate FADT values now, before we make any changes */
+
+	acpi_tb_validate_fadt();
+
+	/* Initialize the global ACPI register structures */
+
+	acpi_tb_setup_fadt_registers();
 }
 
 /*******************************************************************************
@@ -282,31 +320,35 @@
  * RETURN:      None
  *
  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
- *              Expand all 32-bit addresses to 64-bit.
+ *              Expand 32-bit addresses to 64-bit as necessary.
  *
  * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt),
  *              and must contain a copy of the actual FADT.
  *
- * ACPICA will use the "X" fields of the FADT for all addresses.
+ * Notes on 64-bit register addresses:
  *
- * "X" fields are optional extensions to the original V1.0 fields. Even if
- * they are present in the structure, they can be optionally not used by
- * setting them to zero. Therefore, we must selectively expand V1.0 fields
- * if the corresponding X field is zero.
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
  *
- * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
- * "X" fields.
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields if the corresponding X field is zero.
  *
- * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
- * expanding the corresponding ACPI 1.0 field.
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
+ * corresponding "X" fields in the internal FADT.
+ *
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
+ * regardless of whether the host OS is 32-bit or 64-bit.
  *
  ******************************************************************************/
 
 static void acpi_tb_convert_fadt(void)
 {
-	u8 pm1_register_bit_width;
-	u8 pm1_register_byte_width;
-	struct acpi_generic_address *target64;
+	struct acpi_generic_address *address64;
+	u32 address32;
 	u32 i;
 
 	/* Update the local FADT table header length */
@@ -355,35 +397,193 @@
 	 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
 	 * generic address structures as necessary. Later code will always use
 	 * the 64-bit address structures.
+	 *
+	 * March 2009:
+	 * We now always use the 32-bit address if it is valid (non-null). This
+	 * is not in accordance with the ACPI specification which states that
+	 * the 64-bit address supersedes the 32-bit version, but we do this for
+	 * compatibility with other ACPI implementations. Most notably, in the
+	 * case where both the 32 and 64 versions are non-null, we use the 32-bit
+	 * version. This is the only address that is guaranteed to have been
+	 * tested by the BIOS manufacturer.
 	 */
 	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
-		target64 =
-		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
-				 fadt_info_table[i].address64);
+		address32 = *ACPI_ADD_PTR(u32,
+					  &acpi_gbl_FADT,
+					  fadt_info_table[i].address32);
 
-		/* Expand only if the 64-bit X target is null */
+		address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+					 &acpi_gbl_FADT,
+					 fadt_info_table[i].address64);
 
-		if (!target64->address) {
+		/*
+		 * If both 32- and 64-bit addresses are valid (non-zero),
+		 * they must match.
+		 */
+		if (address64->address && address32 &&
+		    (address64->address != (u64) address32)) {
+			ACPI_ERROR((AE_INFO,
+				    "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
+				    fadt_info_table[i].name, address32,
+				    ACPI_FORMAT_UINT64(address64->address)));
+		}
 
-			/* The space_id is always I/O for the 32-bit legacy address fields */
+		/* Always use 32-bit address if it is valid (non-null) */
 
-			acpi_tb_init_generic_address(target64,
+		if (address32) {
+			/*
+			 * Copy the 32-bit address to the 64-bit GAS structure. The
+			 * Space ID is always I/O for 32-bit legacy address fields
+			*/
+			acpi_tb_init_generic_address(address64,
 						     ACPI_ADR_SPACE_SYSTEM_IO,
 						     *ACPI_ADD_PTR(u8,
 								   &acpi_gbl_FADT,
 								   fadt_info_table
 								   [i].length),
-						     (u64) * ACPI_ADD_PTR(u32,
-									  &acpi_gbl_FADT,
-									  fadt_info_table
-									  [i].
-									  address32));
+						     address32);
 		}
 	}
+}
 
-	/* Validate FADT values now, before we make any changes */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_validate_fadt
+ *
+ * PARAMETERS:  Table           - Pointer to the FADT to be validated
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Validate various important fields within the FADT. If a problem
+ *              is found, issue a message, but no status is returned.
+ *              Used by both the table manager and the disassembler.
+ *
+ * Possible additional checks:
+ * (acpi_gbl_FADT.pm1_event_length >= 4)
+ * (acpi_gbl_FADT.pm1_control_length >= 2)
+ * (acpi_gbl_FADT.pm_timer_length >= 4)
+ * Gpe block lengths must be multiple of 2
+ *
+ ******************************************************************************/
 
-	acpi_tb_validate_fadt();
+static void acpi_tb_validate_fadt(void)
+{
+	char *name;
+	u32 *address32;
+	struct acpi_generic_address *address64;
+	u8 length;
+	u32 i;
+
+	/*
+	 * Check for FACS and DSDT address mismatches. An address mismatch between
+	 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
+	 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
+	 */
+	if (acpi_gbl_FADT.facs &&
+	    (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
+		ACPI_WARNING((AE_INFO,
+			      "32/64X FACS address mismatch in FADT - "
+			      "%8.8X/%8.8X%8.8X, using 32",
+			      acpi_gbl_FADT.facs,
+			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
+
+		acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
+	}
+
+	if (acpi_gbl_FADT.dsdt &&
+	    (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
+		ACPI_WARNING((AE_INFO,
+			      "32/64X DSDT address mismatch in FADT - "
+			      "%8.8X/%8.8X%8.8X, using 32",
+			      acpi_gbl_FADT.dsdt,
+			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
+
+		acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
+	}
+
+	/* Examine all of the 64-bit extended address fields (X fields) */
+
+	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+		/*
+		 * Generate pointers to the 32-bit and 64-bit addresses, get the
+		 * register length (width), and the register name
+		 */
+		address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+					 &acpi_gbl_FADT,
+					 fadt_info_table[i].address64);
+		address32 =
+		    ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
+				 fadt_info_table[i].address32);
+		length =
+		    *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
+				  fadt_info_table[i].length);
+		name = fadt_info_table[i].name;
+
+		/*
+		 * For each extended field, check for length mismatch between the
+		 * legacy length field and the corresponding 64-bit X length field.
+		 */
+		if (address64->address &&
+		    (address64->bit_width != ACPI_MUL_8(length))) {
+			ACPI_WARNING((AE_INFO,
+				      "32/64X length mismatch in %s: %d/%d",
+				      name, ACPI_MUL_8(length),
+				      address64->bit_width));
+		}
+
+		if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
+			/*
+			 * Field is required (Pm1a_event, Pm1a_control, pm_timer).
+			 * Both the address and length must be non-zero.
+			 */
+			if (!address64->address || !length) {
+				ACPI_ERROR((AE_INFO,
+					    "Required field %s has zero address and/or length:"
+					    " %8.8X%8.8X/%X",
+					    name,
+					    ACPI_FORMAT_UINT64(address64->
+							       address),
+					    length));
+			}
+		} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
+			/*
+			 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
+			 * length field. If present, both the address and length must
+			 * be valid.
+			 */
+			if ((address64->address && !length) ||
+			    (!address64->address && length)) {
+				ACPI_WARNING((AE_INFO,
+					      "Optional field %s has zero address or length: "
+					      "%8.8X%8.8X/%X",
+					      name,
+					      ACPI_FORMAT_UINT64(address64->
+								 address),
+					      length));
+			}
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_setup_fadt_registers
+ *
+ * PARAMETERS:  None, uses acpi_gbl_FADT.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ *              force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
+
+static void acpi_tb_setup_fadt_registers(void)
+{
+	struct acpi_generic_address *target64;
+	struct acpi_generic_address *source64;
+	u8 pm1_register_byte_width;
+	u32 i;
 
 	/*
 	 * Optionally check all register lengths against the default values and
@@ -421,190 +621,39 @@
 
 	/*
 	 * Get the length of the individual PM1 registers (enable and status).
-	 * Each register is defined to be (event block length / 2).
+	 * Each register is defined to be (event block length / 2). Extra divide
+	 * by 8 converts bits to bytes.
 	 */
-	pm1_register_bit_width =
-	    (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
-	pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
+	pm1_register_byte_width = (u8)
+	    ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
 
 	/*
-	 * Adjust the lengths of the PM1 Event Blocks so that they can be used to
-	 * access the PM1 status register(s). Use (width / 2)
-	 */
-	acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
-	acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
-
-	/*
-	 * Calculate separate GAS structs for the PM1 Enable registers.
-	 * These addresses do not appear (directly) in the FADT, so it is
-	 * useful to calculate them once, here.
+	 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+	 * registers. These addresses do not appear (directly) in the FADT, so it
+	 * is useful to pre-calculate them from the PM1 Event Block definitions.
 	 *
 	 * 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 (xpm1x_event_block.bit_width/2).
+	 * Register block. Each is of length (pm1_event_length/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).
+	 * Note: The PM1A event block is required by the ACPI specification.
+	 * However, the PM1B event block is optional and is rarely, if ever,
+	 * used.
 	 */
-	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);
 
-	/* The PM1A register block is required */
+	for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
+		source64 =
+		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+				 fadt_pm_info_table[i].source);
 
-	acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
-				     acpi_gbl_FADT.xpm1a_event_block.space_id,
-				     pm1_register_byte_width,
-				     (acpi_gbl_FADT.xpm1a_event_block.address +
-				      pm1_register_byte_width));
-	/* Don't forget to copy space_id of the GAS */
-	acpi_gbl_xpm1a_enable.space_id =
-	    acpi_gbl_FADT.xpm1a_event_block.space_id;
-
-	/* 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,
-					     acpi_gbl_FADT.xpm1b_event_block.space_id,
-					     pm1_register_byte_width,
-					     (acpi_gbl_FADT.xpm1b_event_block.
-					      address + pm1_register_byte_width));
-		/* Don't forget to copy space_id of the GAS */
-		acpi_gbl_xpm1b_enable.space_id =
-		    acpi_gbl_FADT.xpm1b_event_block.space_id;
-
-	}
-}
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_tb_validate_fadt
- *
- * PARAMETERS:  Table           - Pointer to the FADT to be validated
- *
- * RETURN:      None
- *
- * DESCRIPTION: Validate various important fields within the FADT. If a problem
- *              is found, issue a message, but no status is returned.
- *              Used by both the table manager and the disassembler.
- *
- * Possible additional checks:
- * (acpi_gbl_FADT.pm1_event_length >= 4)
- * (acpi_gbl_FADT.pm1_control_length >= 2)
- * (acpi_gbl_FADT.pm_timer_length >= 4)
- * Gpe block lengths must be multiple of 2
- *
- ******************************************************************************/
-
-static void acpi_tb_validate_fadt(void)
-{
-	char *name;
-	u32 *address32;
-	struct acpi_generic_address *address64;
-	u8 length;
-	u32 i;
-
-	/*
-	 * Check for FACS and DSDT address mismatches. An address mismatch between
-	 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
-	 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
-	 */
-	if (acpi_gbl_FADT.facs &&
-	    (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
-		ACPI_WARNING((AE_INFO,
-			      "32/64X FACS address mismatch in FADT - "
-			      "two FACS tables! %8.8X/%8.8X%8.8X",
-			      acpi_gbl_FADT.facs,
-			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
-	}
-
-	if (acpi_gbl_FADT.dsdt &&
-	    (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
-		ACPI_WARNING((AE_INFO,
-			      "32/64X DSDT address mismatch in FADT - "
-			      "two DSDT tables! %8.8X/%8.8X%8.8X",
-			      acpi_gbl_FADT.dsdt,
-			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
-	}
-
-	/* Examine all of the 64-bit extended address fields (X fields) */
-
-	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
-		/*
-		 * Generate pointers to the 32-bit and 64-bit addresses, get the
-		 * register length (width), and the register name
-		 */
-		address64 = ACPI_ADD_PTR(struct acpi_generic_address,
-					 &acpi_gbl_FADT,
-					 fadt_info_table[i].address64);
-		address32 =
-		    ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
-				 fadt_info_table[i].address32);
-		length =
-		    *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
-				  fadt_info_table[i].length);
-		name = fadt_info_table[i].name;
-
-		/*
-		 * For each extended field, check for length mismatch between the
-		 * legacy length field and the corresponding 64-bit X length field.
-		 */
-		if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
-			ACPI_WARNING((AE_INFO,
-				      "32/64X length mismatch in %s: %d/%d",
-				      name, ACPI_MUL_8(length),
-				      address64->bit_width));
-		}
-
-		if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
-			/*
-			 * Field is required (Pm1a_event, Pm1a_control, pm_timer).
-			 * Both the address and length must be non-zero.
-			 */
-			if (!address64->address || !length) {
-				ACPI_ERROR((AE_INFO,
-					    "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
-					    name,
-					    ACPI_FORMAT_UINT64(address64->
-							       address),
-					    length));
-			}
-		} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
-			/*
-			 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
-			 * length field. If present, both the address and length must be valid.
-			 */
-			if ((address64->address && !length)
-			    || (!address64->address && length)) {
-				ACPI_WARNING((AE_INFO,
-					      "Optional field %s has zero address or length: %8.8X%8.8X/%X",
-					      name,
-					      ACPI_FORMAT_UINT64(address64->
-								 address),
-					      length));
-			}
-		}
-
-		/* If both 32- and 64-bit addresses are valid (non-zero), they must match */
-
-		if (address64->address && *address32 &&
-		    (address64->address != (u64) * address32)) {
-			ACPI_ERROR((AE_INFO,
-				    "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
-				    name, *address32,
-				    ACPI_FORMAT_UINT64(address64->address)));
+		if (source64->address) {
+			acpi_tb_init_generic_address(fadt_pm_info_table[i].
+						     target, source64->space_id,
+						     pm1_register_byte_width,
+						     source64->address +
+						     (fadt_pm_info_table[i].
+						      register_num *
+						      pm1_register_byte_width));
 		}
 	}
 }
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 37374b2..f865d5a 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -103,7 +103,9 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to add the ACPI table
+ * DESCRIPTION: This function is called to add an ACPI table. It is used to
+ *              dynamically load tables via the Load and load_table AML
+ *              operators.
  *
  ******************************************************************************/
 
@@ -112,6 +114,7 @@
 {
 	u32 i;
 	acpi_status status = AE_OK;
+	struct acpi_table_header *override_table = NULL;
 
 	ACPI_FUNCTION_TRACE(tb_add_table);
 
@@ -201,6 +204,29 @@
 		}
 	}
 
+	/*
+	 * ACPI Table Override:
+	 * Allow the host to override dynamically loaded tables.
+	 */
+	status = acpi_os_table_override(table_desc->pointer, &override_table);
+	if (ACPI_SUCCESS(status) && override_table) {
+		ACPI_INFO((AE_INFO,
+			   "%4.4s @ 0x%p Table override, replaced with:",
+			   table_desc->pointer->signature,
+			   ACPI_CAST_PTR(void, table_desc->address)));
+
+		/* We can delete the table that was passed as a parameter */
+
+		acpi_tb_delete_table(table_desc);
+
+		/* Setup descriptor for the new table */
+
+		table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
+		table_desc->pointer = override_table;
+		table_desc->length = override_table->length;
+		table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+	}
+
 	/* Add the table to the global root table list */
 
 	status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
@@ -247,8 +273,9 @@
 	/* Increase the Table Array size */
 
 	tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
-				       size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
-				      * sizeof(struct acpi_table_desc));
+				       size +
+				       ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+				      sizeof(struct acpi_table_desc));
 	if (!tables) {
 		ACPI_ERROR((AE_INFO,
 			    "Could not allocate new root table array"));
@@ -407,27 +434,56 @@
  *
  * PARAMETERS:  table_index         - Table index
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
  *
  ******************************************************************************/
 
-void acpi_tb_delete_namespace_by_owner(u32 table_index)
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
 {
 	acpi_owner_id owner_id;
+	acpi_status status;
 
-	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
-	if (table_index < acpi_gbl_root_table_list.count) {
-		owner_id =
-		    acpi_gbl_root_table_list.tables[table_index].owner_id;
-	} else {
-		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-		return;
+	ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
 	}
 
+	if (table_index >= acpi_gbl_root_table_list.count) {
+
+		/* The table index does not exist */
+
+		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+
+	/* Get the owner ID for this table, used to delete namespace nodes */
+
+	owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+	/*
+	 * Need to acquire the namespace writer lock to prevent interference
+	 * with any concurrent namespace walks. The interpreter must be
+	 * released during the deletion since the acquisition of the deletion
+	 * lock may block, and also since the execution of a namespace walk
+	 * must be allowed to use the interpreter.
+	 */
+	acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+	status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
+
 	acpi_ns_delete_namespace_by_owner(owner_id);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -535,8 +591,8 @@
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	if (table_index < acpi_gbl_root_table_list.count) {
 		is_loaded = (u8)
-		    (acpi_gbl_root_table_list.tables[table_index].
-		     flags & ACPI_TABLE_IS_LOADED);
+		    (acpi_gbl_root_table_list.tables[table_index].flags &
+		     ACPI_TABLE_IS_LOADED);
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 22ce489..ef7d2c2 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -177,19 +177,23 @@
 			   struct acpi_table_header *header)
 {
 
+	/*
+	 * The reason that the Address is cast to a void pointer is so that we
+	 * can use %p which will work properly on both 32-bit and 64-bit hosts.
+	 */
 	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
 
-		/* FACS only has signature and length fields of common table header */
+		/* FACS only has signature and length fields */
 
-		ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
-			   header->signature, (unsigned long)address,
+		ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+			   header->signature, ACPI_CAST_PTR(void, address),
 			   header->length));
 	} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
 
 		/* RSDP has no common fields */
 
-		ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
-			   (unsigned long)address,
+		ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+			   ACPI_CAST_PTR (void, address),
 			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
 			    revision >
 			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
@@ -202,8 +206,8 @@
 		/* Standard ACPI table with full common header */
 
 		ACPI_INFO((AE_INFO,
-			   "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
-			   header->signature, (unsigned long)address,
+			   "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+			   header->signature, ACPI_CAST_PTR (void, address),
 			   header->length, header->revision, header->oem_id,
 			   header->oem_table_id, header->oem_revision,
 			   header->asl_compiler_id,
@@ -280,22 +284,28 @@
  * FUNCTION:    acpi_tb_install_table
  *
  * PARAMETERS:  Address                 - Physical address of DSDT or FACS
- *              Flags                   - Flags
  *              Signature               - Table signature, NULL if no need to
  *                                        match
  *              table_index             - Index into root table array
  *
  * RETURN:      None
  *
- * DESCRIPTION: Install an ACPI table into the global data structure.
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ *              table override mechanism is implemented here to allow the host
+ *              OS to replace any table before it is installed in the root
+ *              table array.
  *
  ******************************************************************************/
 
 void
 acpi_tb_install_table(acpi_physical_address address,
-		      u8 flags, char *signature, u32 table_index)
+		      char *signature, u32 table_index)
 {
-	struct acpi_table_header *table;
+	u8 flags;
+	acpi_status status;
+	struct acpi_table_header *table_to_install;
+	struct acpi_table_header *mapped_table;
+	struct acpi_table_header *override_table = NULL;
 
 	if (!address) {
 		ACPI_ERROR((AE_INFO,
@@ -306,41 +316,69 @@
 
 	/* Map just the table header */
 
-	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
-	if (!table) {
+	mapped_table =
+	    acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+	if (!mapped_table) {
 		return;
 	}
 
-	/* If a particular signature is expected, signature must match */
+	/* If a particular signature is expected (DSDT/FACS), it must match */
 
-	if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
+	if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
 		ACPI_ERROR((AE_INFO,
-			    "Invalid signature 0x%X for ACPI table [%s]",
-			    *ACPI_CAST_PTR(u32, table->signature), signature));
+			    "Invalid signature 0x%X for ACPI table, expected [%s]",
+			    *ACPI_CAST_PTR(u32, mapped_table->signature),
+			    signature));
 		goto unmap_and_exit;
 	}
 
+	/*
+	 * ACPI Table Override:
+	 *
+	 * Before we install the table, let the host OS override it with a new
+	 * one if desired. Any table within the RSDT/XSDT can be replaced,
+	 * including the DSDT which is pointed to by the FADT.
+	 */
+	status = acpi_os_table_override(mapped_table, &override_table);
+	if (ACPI_SUCCESS(status) && override_table) {
+		ACPI_INFO((AE_INFO,
+			   "%4.4s @ 0x%p Table override, replaced with:",
+			   mapped_table->signature, ACPI_CAST_PTR(void,
+								  address)));
+
+		acpi_gbl_root_table_list.tables[table_index].pointer =
+		    override_table;
+		address = ACPI_PTR_TO_PHYSADDR(override_table);
+
+		table_to_install = override_table;
+		flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+	} else {
+		table_to_install = mapped_table;
+		flags = ACPI_TABLE_ORIGIN_MAPPED;
+	}
+
 	/* Initialize the table entry */
 
 	acpi_gbl_root_table_list.tables[table_index].address = address;
-	acpi_gbl_root_table_list.tables[table_index].length = table->length;
+	acpi_gbl_root_table_list.tables[table_index].length =
+	    table_to_install->length;
 	acpi_gbl_root_table_list.tables[table_index].flags = flags;
 
 	ACPI_MOVE_32_TO_32(&
 			   (acpi_gbl_root_table_list.tables[table_index].
-			    signature), table->signature);
+			    signature), table_to_install->signature);
 
-	acpi_tb_print_table_header(address, table);
+	acpi_tb_print_table_header(address, table_to_install);
 
 	if (table_index == ACPI_TABLE_INDEX_DSDT) {
 
 		/* Global integer width is based upon revision of the DSDT */
 
-		acpi_ut_set_integer_width(table->revision);
+		acpi_ut_set_integer_width(table_to_install->revision);
 	}
 
       unmap_and_exit:
-	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+	acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
 }
 
 /*******************************************************************************
@@ -379,7 +417,8 @@
 	} else {
 		/*
 		 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
-		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
+		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
+		 *  return 64-bit
 		 */
 		ACPI_MOVE_64_TO_64(&address64, table_entry);
 
@@ -389,7 +428,8 @@
 			/* Will truncate 64-bit address to 32 bits, issue warning */
 
 			ACPI_WARNING((AE_INFO,
-				      "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
+				      "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
+				      " truncating",
 				      ACPI_FORMAT_UINT64(address64)));
 		}
 #endif
@@ -402,7 +442,6 @@
  * FUNCTION:    acpi_tb_parse_root_table
  *
  * PARAMETERS:  Rsdp                    - Pointer to the RSDP
- *              Flags                   - Flags
  *
  * RETURN:      Status
  *
@@ -416,7 +455,7 @@
  ******************************************************************************/
 
 acpi_status __init
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
 {
 	struct acpi_table_rsdp *rsdp;
 	u32 table_entry_size;
@@ -513,13 +552,12 @@
 
 	/* Calculate the number of tables described in the root table */
 
-	table_count =
-	    (u32) ((table->length -
-		    sizeof(struct acpi_table_header)) / table_entry_size);
-
+	table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
+			    table_entry_size);
 	/*
-	 * First two entries in the table array are reserved for the DSDT and FACS,
-	 * which are not actually present in the RSDT/XSDT - they come from the FADT
+	 * First two entries in the table array are reserved for the DSDT
+	 * and FACS, which are not actually present in the RSDT/XSDT - they
+	 * come from the FADT
 	 */
 	table_entry =
 	    ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
@@ -567,14 +605,14 @@
 	 */
 	for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
 		acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
-				      address, flags, NULL, i);
+				      address, NULL, i);
 
 		/* Special case for FADT - get the DSDT and FACS */
 
 		if (ACPI_COMPARE_NAME
 		    (&acpi_gbl_root_table_list.tables[i].signature,
 		     ACPI_SIG_FADT)) {
-			acpi_tb_parse_fadt(i, flags);
+			acpi_tb_parse_fadt(i);
 		}
 	}
 
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index c3e841f..dbca226 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -150,8 +150,7 @@
 	 * Root Table Array. This array contains the information of the RSDT/XSDT
 	 * in a common, more useable format.
 	 */
-	status =
-	    acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
+	status = acpi_tb_parse_root_table(rsdp_address);
 	return_ACPI_STATUS(status);
 }
 
@@ -247,7 +246,7 @@
 
 ACPI_EXPORT_SYMBOL(acpi_load_table)
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_get_table_header
  *
@@ -262,7 +261,7 @@
  * NOTE:        Caller is responsible in unmapping the header with
  *              acpi_os_unmap_memory
  *
- *****************************************************************************/
+ ******************************************************************************/
 acpi_status
 acpi_get_table_header(char *signature,
 		      u32 instance, struct acpi_table_header *out_table_header)
@@ -277,9 +276,8 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Walk the root table list
-	 */
+	/* Walk the root table list */
+
 	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
 		if (!ACPI_COMPARE_NAME
 		    (&(acpi_gbl_root_table_list.tables[i].signature),
@@ -292,8 +290,8 @@
 		}
 
 		if (!acpi_gbl_root_table_list.tables[i].pointer) {
-			if ((acpi_gbl_root_table_list.tables[i].
-			     flags & ACPI_TABLE_ORIGIN_MASK) ==
+			if ((acpi_gbl_root_table_list.tables[i].flags &
+			     ACPI_TABLE_ORIGIN_MASK) ==
 			    ACPI_TABLE_ORIGIN_MAPPED) {
 				header =
 				    acpi_os_map_memory(acpi_gbl_root_table_list.
@@ -324,7 +322,7 @@
 
 ACPI_EXPORT_SYMBOL(acpi_get_table_header)
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_unload_table_id
  *
@@ -375,7 +373,7 @@
  *
  * DESCRIPTION: Finds and verifies an ACPI table.
  *
- *****************************************************************************/
+ ******************************************************************************/
 acpi_status
 acpi_get_table(char *signature,
 	       u32 instance, struct acpi_table_header **out_table)
@@ -390,9 +388,8 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Walk the root table list
-	 */
+	/* Walk the root table list */
+
 	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
 		if (!ACPI_COMPARE_NAME
 		    (&(acpi_gbl_root_table_list.tables[i].signature),
@@ -491,7 +488,6 @@
 static acpi_status acpi_tb_load_namespace(void)
 {
 	acpi_status status;
-	struct acpi_table_header *table;
 	u32 i;
 
 	ACPI_FUNCTION_TRACE(tb_load_namespace);
@@ -515,58 +511,28 @@
 		goto unlock_and_exit;
 	}
 
-	/*
-	 * Find DSDT table
-	 */
-	status =
-	    acpi_os_table_override(acpi_gbl_root_table_list.
-				   tables[ACPI_TABLE_INDEX_DSDT].pointer,
-				   &table);
-	if (ACPI_SUCCESS(status) && table) {
-		/*
-		 * DSDT table has been found
-		 */
-		acpi_tb_delete_table(&acpi_gbl_root_table_list.
-				     tables[ACPI_TABLE_INDEX_DSDT]);
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
-		    table;
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
-		    table->length;
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
-		    ACPI_TABLE_ORIGIN_UNKNOWN;
-
-		ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
-		acpi_tb_print_table_header(0, table);
-
-		if (no_auto_ssdt == 0) {
-			printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
-		}
-	}
+	/* A valid DSDT is required */
 
 	status =
 	    acpi_tb_verify_table(&acpi_gbl_root_table_list.
 				 tables[ACPI_TABLE_INDEX_DSDT]);
 	if (ACPI_FAILURE(status)) {
 
-		/* A valid DSDT is required */
-
 		status = AE_NO_ACPI_TABLES;
 		goto unlock_and_exit;
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 
-	/*
-	 * Load and parse tables.
-	 */
+	/* Load and parse tables */
+
 	status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	/*
-	 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
-	 */
+	/* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
 		if ((!ACPI_COMPARE_NAME
@@ -619,9 +585,8 @@
 
 	ACPI_FUNCTION_TRACE(acpi_load_tables);
 
-	/*
-	 * Load the namespace from the tables
-	 */
+	/* Load the namespace from the tables */
+
 	status = acpi_tb_load_namespace();
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index b7fc8dd..85ea834 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -75,8 +75,8 @@
 	 * Note: Sometimes there exists more than one RSDP in memory; the valid
 	 * RSDP has a valid checksum, all others have an invalid checksum.
 	 */
-	if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
-	    != 0) {
+	if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP,
+			 sizeof(ACPI_SIG_RSDP) - 1) != 0) {
 
 		/* Nope, BAD Signature */
 
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index b0dcfd3..919624f 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -135,11 +135,11 @@
 	 * In general, the external object will be the same type as
 	 * the internal object
 	 */
-	external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+	external_object->type = internal_object->common.type;
 
 	/* However, only a limited number of external types are supported */
 
-	switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+	switch (internal_object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		external_object->string.pointer = (char *)data_space;
@@ -222,8 +222,8 @@
 		 */
 		ACPI_ERROR((AE_INFO,
 			    "Unsupported object type, cannot convert to external object: %s",
-			    acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
-						  (internal_object))));
+			    acpi_ut_get_type_name(internal_object->common.
+						  type)));
 
 		return_ACPI_STATUS(AE_SUPPORT);
 	}
@@ -355,7 +355,7 @@
 	info.object_space = 0;
 	info.num_packages = 1;
 
-	external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+	external_object->type = internal_object->common.type;
 	external_object->package.count = internal_object->package.count;
 	external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
 							  info.free_space);
@@ -399,7 +399,7 @@
 
 	ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
 
-	if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
+	if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
 		/*
 		 * Package object:  Copy all subobjects (including
 		 * nested packages)
@@ -496,8 +496,9 @@
 	case ACPI_TYPE_STRING:
 
 		internal_object->string.pointer =
-		    ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.
-					 length + 1);
+		    ACPI_ALLOCATE_ZEROED((acpi_size)
+					 external_object->string.length + 1);
+
 		if (!internal_object->string.pointer) {
 			goto error_exit;
 		}
@@ -697,7 +698,7 @@
 
 	/* Handle the objects with extra data */
 
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 		/*
 		 * Allocate and copy the actual buffer if and only if:
@@ -814,8 +815,8 @@
 			 * This is a simple object, just copy it
 			 */
 			target_object =
-			    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
-							   (source_object));
+			    acpi_ut_create_internal_object(source_object->
+							   common.type);
 			if (!target_object) {
 				return (AE_NO_MEMORY);
 			}
@@ -892,7 +893,7 @@
 
 	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
 
-	dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
+	dest_obj->common.type = source_obj->common.type;
 	dest_obj->common.flags = source_obj->common.flags;
 	dest_obj->package.count = source_obj->package.count;
 
@@ -950,15 +951,14 @@
 
 	/* Create the top level object */
 
-	*dest_desc =
-	    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
+	*dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
 	if (!*dest_desc) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
 	/* Copy the object and possible subobjects */
 
-	if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
+	if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
 		status =
 		    acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
 						      walk_state);
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
index a0be9e3..a5ee23b 100644
--- a/drivers/acpi/acpica/utdelete.c
+++ b/drivers/acpi/acpica/utdelete.c
@@ -86,7 +86,7 @@
 	 * Must delete or free any pointers within the object that are not
 	 * actual ACPI objects (for example, a raw buffer pointer).
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(object)) {
+	switch (object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -382,7 +382,7 @@
 					  object, new_count));
 		}
 
-		if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
+		if (object->common.type == ACPI_TYPE_METHOD) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
 					  "Method Obj %p Refs=%X, [Decremented]\n",
 					  object, new_count));
@@ -469,7 +469,7 @@
 		 * All sub-objects must have their reference count incremented also.
 		 * Different object types have different subobjects.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(object)) {
+		switch (object->common.type) {
 		case ACPI_TYPE_DEVICE:
 		case ACPI_TYPE_PROCESSOR:
 		case ACPI_TYPE_POWER:
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index 9c9897d..006b16c 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -59,26 +59,35 @@
 
 /*
  * Strings supported by the _OSI predefined (internal) method.
+ *
+ * March 2009: Removed "Linux" as this host no longer wants to respond true
+ * for this string. Basically, the only safe OS strings are windows-related
+ * and in many or most cases represent the only test path within the
+ * BIOS-provided ASL code.
+ *
+ * The second element of each entry is used to track the newest version of
+ * Windows that the BIOS has requested.
  */
-static char *acpi_interfaces_supported[] = {
+static struct acpi_interface_info acpi_interfaces_supported[] = {
 	/* Operating System Vendor Strings */
 
-	"Windows 2000",		/* Windows 2000 */
-	"Windows 2001",		/* Windows XP */
-	"Windows 2001 SP1",	/* Windows XP SP1 */
-	"Windows 2001 SP2",	/* Windows XP SP2 */
-	"Windows 2001.1",	/* Windows Server 2003 */
-	"Windows 2001.1 SP1",	/* Windows Server 2003 SP1 - Added 03/2006 */
-	"Windows 2006",		/* Windows Vista - Added 03/2006 */
+	{"Windows 2000", ACPI_OSI_WIN_2000},	/* Windows 2000 */
+	{"Windows 2001", ACPI_OSI_WIN_XP},	/* Windows XP */
+	{"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1},	/* Windows XP SP1 */
+	{"Windows 2001.1", ACPI_OSI_WINSRV_2003},	/* Windows Server 2003 */
+	{"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2},	/* Windows XP SP2 */
+	{"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1},	/* Windows Server 2003 SP1 - Added 03/2006 */
+	{"Windows 2006", ACPI_OSI_WIN_VISTA},	/* Windows Vista - Added 03/2006 */
 
 	/* Feature Group Strings */
 
-	"Extended Address Space Descriptor"
-	    /*
-	     * All "optional" feature group strings (features that are implemented
-	     * by the host) should be implemented in the host version of
-	     * acpi_os_validate_interface and should not be added here.
-	     */
+	{"Extended Address Space Descriptor", 0}
+
+	/*
+	 * All "optional" feature group strings (features that are implemented
+	 * by the host) should be implemented in the host version of
+	 * acpi_os_validate_interface and should not be added here.
+	 */
 };
 
 /*******************************************************************************
@@ -98,6 +107,7 @@
 	acpi_status status;
 	union acpi_operand_object *string_desc;
 	union acpi_operand_object *return_desc;
+	u32 return_value;
 	u32 i;
 
 	ACPI_FUNCTION_TRACE(ut_osi_implementation);
@@ -116,19 +126,28 @@
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	/* Default return value is 0, NOT-SUPPORTED */
+	/* Default return value is 0, NOT SUPPORTED */
 
-	return_desc->integer.value = 0;
-	walk_state->return_desc = return_desc;
+	return_value = 0;
 
 	/* Compare input string to static table of supported interfaces */
 
 	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
-		if (!ACPI_STRCMP
-		    (string_desc->string.pointer,
-		     acpi_interfaces_supported[i])) {
-			return_desc->integer.value = ACPI_UINT32_MAX;
-			goto done;
+		if (!ACPI_STRCMP(string_desc->string.pointer,
+				 acpi_interfaces_supported[i].name)) {
+			/*
+			 * The interface is supported.
+			 * Update the osi_data if necessary. We keep track of the latest
+			 * version of Windows that has been requested by the BIOS.
+			 */
+			if (acpi_interfaces_supported[i].value >
+			    acpi_gbl_osi_data) {
+				acpi_gbl_osi_data =
+				    acpi_interfaces_supported[i].value;
+			}
+
+			return_value = ACPI_UINT32_MAX;
+			goto exit;
 		}
 	}
 
@@ -139,15 +158,22 @@
 	 */
 	status = acpi_os_validate_interface(string_desc->string.pointer);
 	if (ACPI_SUCCESS(status)) {
-		return_desc->integer.value = ACPI_UINT32_MAX;
+
+		/* The interface is supported */
+
+		return_value = ACPI_UINT32_MAX;
 	}
 
-done:
-	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
-		string_desc->string.pointer,
-		return_desc->integer.value == 0 ? "not-" : ""));
+exit:
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+		"ACPI: BIOS _OSI(%s) is %ssupported\n",
+		string_desc->string.pointer, return_value == 0 ? "not " : ""));
 
-	return_ACPI_STATUS(AE_OK);
+	/* Complete the return value */
+
+	return_desc->integer.value = return_value;
+	walk_state->return_desc = return_desc;
+	return_ACPI_STATUS (AE_OK);
 }
 
 /*******************************************************************************
@@ -167,8 +193,8 @@
 	int i;
 
 	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
-		if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
-			*acpi_interfaces_supported[i] = '\0';
+		if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
+			*acpi_interfaces_supported[i].name = '\0';
 			return AE_OK;
 		}
 	}
@@ -248,7 +274,7 @@
 
 	/* Map the return object type to the bitmapped type */
 
-	switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
+	switch ((info->return_object)->common.type) {
 	case ACPI_TYPE_INTEGER:
 		return_btype = ACPI_BTYPE_INTEGER;
 		break;
@@ -418,7 +444,7 @@
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Convert the Numeric HID to string */
 
@@ -459,7 +485,7 @@
 			  struct acpi_compatible_id *one_cid)
 {
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Convert the Numeric CID to string */
@@ -527,7 +553,7 @@
 	/* Get the number of _CIDs returned */
 
 	count = 1;
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 		count = obj_desc->package.count;
 	}
 
@@ -555,7 +581,7 @@
 
 	/* The _CID object can be either a single CID or a package (list) of CIDs */
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 
 		/* Translate each package element */
 
@@ -620,7 +646,7 @@
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Convert the Numeric UID to string */
 
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index a3ab9d9..59e46f2 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -294,12 +294,9 @@
 	/* ACPI_BITREG_GLOBAL_LOCK_RELEASE  */ {ACPI_REGISTER_PM1_CONTROL,
 						ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
 						ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
-	/* ACPI_BITREG_SLEEP_TYPE_A         */ {ACPI_REGISTER_PM1_CONTROL,
-						ACPI_BITPOSITION_SLEEP_TYPE_X,
-						ACPI_BITMASK_SLEEP_TYPE_X},
-	/* ACPI_BITREG_SLEEP_TYPE_B         */ {ACPI_REGISTER_PM1_CONTROL,
-						ACPI_BITPOSITION_SLEEP_TYPE_X,
-						ACPI_BITMASK_SLEEP_TYPE_X},
+	/* ACPI_BITREG_SLEEP_TYPE           */ {ACPI_REGISTER_PM1_CONTROL,
+						ACPI_BITPOSITION_SLEEP_TYPE,
+						ACPI_BITMASK_SLEEP_TYPE},
 	/* ACPI_BITREG_SLEEP_ENABLE         */ {ACPI_REGISTER_PM1_CONTROL,
 						ACPI_BITPOSITION_SLEEP_ENABLE,
 						ACPI_BITMASK_SLEEP_ENABLE},
@@ -476,7 +473,7 @@
 		return ("[NULL Object Descriptor]");
 	}
 
-	return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
+	return (acpi_ut_get_type_name(obj_desc->common.type));
 }
 
 /*******************************************************************************
@@ -749,7 +746,10 @@
 	for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
 		acpi_gbl_owner_id_mask[i] = 0;
 	}
-	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;	/* Last ID is never valid */
+
+	/* Last owner_iD is never valid */
+
+	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
 
 	/* GPE support */
 
@@ -789,6 +789,7 @@
 	acpi_gbl_trace_dbg_layer = 0;
 	acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
 	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+	acpi_gbl_osi_data = 0;
 
 	/* Hardware oriented */
 
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c
new file mode 100644
index 0000000..25e0312
--- /dev/null
+++ b/drivers/acpi/acpica/utlock.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Module Name: utlock - Reader/Writer lock interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, 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 "accommon.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utlock")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_rw_lock
+ *              acpi_ut_delete_rw_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	lock->num_readers = 0;
+	status = acpi_os_create_mutex(&lock->reader_mutex);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_os_create_mutex(&lock->writer_mutex);
+	return status;
+}
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
+{
+
+	acpi_os_delete_mutex(lock->reader_mutex);
+	acpi_os_delete_mutex(lock->writer_mutex);
+
+	lock->num_readers = 0;
+	lock->reader_mutex = NULL;
+	lock->writer_mutex = NULL;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_read_lock
+ *              acpi_ut_release_read_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
+ *              only the first reader acquires the write mutex. On release,
+ *              only the last reader releases the write mutex. Although this
+ *              algorithm can in theory starve writers, this should not be a
+ *              problem with ACPICA since the subsystem is infrequently used
+ *              in comparison to (for example) an I/O system.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/* Acquire the write lock only for the first reader */
+
+	lock->num_readers++;
+	if (lock->num_readers == 1) {
+		status =
+		    acpi_os_acquire_mutex(lock->writer_mutex,
+					  ACPI_WAIT_FOREVER);
+	}
+
+	acpi_os_release_mutex(lock->reader_mutex);
+	return status;
+}
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/* Release the write lock only for the very last reader */
+
+	lock->num_readers--;
+	if (lock->num_readers == 0) {
+		acpi_os_release_mutex(lock->writer_mutex);
+	}
+
+	acpi_os_release_mutex(lock->reader_mutex);
+	return status;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_write_lock
+ *              acpi_ut_release_write_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
+ *              release the writer mutex associated with the lock. Acquisition
+ *              of the lock is fully exclusive and will block all readers and
+ *              writers until it is released.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
+	return status;
+}
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
+{
+
+	acpi_os_release_mutex(lock->writer_mutex);
+}
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index c1f7f4e..1c9e250 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -938,8 +938,7 @@
 		if ((!this_source_obj) ||
 		    (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
 		     ACPI_DESC_TYPE_OPERAND)
-		    || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
-			ACPI_TYPE_PACKAGE)) {
+		    || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
 			status =
 			    walk_callback(ACPI_COPY_TYPE_SIMPLE,
 					  this_source_obj, state, context);
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 14eb52c..26c93a7 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -60,7 +60,8 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Create the system mutex objects.
+ * DESCRIPTION: Create the system mutex objects. This includes mutexes,
+ *              spin locks, and reader/writer locks.
  *
  ******************************************************************************/
 
@@ -71,9 +72,8 @@
 
 	ACPI_FUNCTION_TRACE(ut_mutex_initialize);
 
-	/*
-	 * Create each of the predefined mutex objects
-	 */
+	/* Create each of the predefined mutex objects */
+
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
 		status = acpi_ut_create_mutex(i);
 		if (ACPI_FAILURE(status)) {
@@ -86,6 +86,9 @@
 	spin_lock_init(acpi_gbl_gpe_lock);
 	spin_lock_init(acpi_gbl_hardware_lock);
 
+	/* Create the reader/writer lock for namespace access */
+
+	status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
 	return_ACPI_STATUS(status);
 }
 
@@ -97,7 +100,8 @@
  *
  * RETURN:      None.
  *
- * DESCRIPTION: Delete all of the system mutex objects.
+ * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
+ *              spin locks, and reader/writer locks.
  *
  ******************************************************************************/
 
@@ -107,9 +111,8 @@
 
 	ACPI_FUNCTION_TRACE(ut_mutex_terminate);
 
-	/*
-	 * Delete each predefined mutex object
-	 */
+	/* Delete each predefined mutex object */
+
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
 		(void)acpi_ut_delete_mutex(i);
 	}
@@ -118,6 +121,10 @@
 
 	acpi_os_delete_lock(acpi_gbl_gpe_lock);
 	acpi_os_delete_lock(acpi_gbl_hardware_lock);
+
+	/* Delete the reader/writer lock */
+
+	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
 	return_VOID;
 }
 
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index fd5ea75..0207b62 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -310,7 +310,7 @@
 	/* Check for a null pointer */
 
 	if (!object) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
 		return (FALSE);
 	}
 
@@ -324,7 +324,7 @@
 		return (TRUE);
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "%p is not not an ACPI operand obj [%s]\n",
 				  object, acpi_ut_get_descriptor_name(object)));
 		break;
@@ -457,7 +457,7 @@
 	 * must be accessed bytewise or there may be alignment problems on
 	 * certain processors
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+	switch (internal_object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		length += (acpi_size) internal_object->string.length + 1;
@@ -518,8 +518,7 @@
 		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));
+			    internal_object->common.type, internal_object));
 		status = AE_TYPE;
 		break;
 	}
@@ -664,7 +663,7 @@
 
 	if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
 	     ACPI_DESC_TYPE_OPERAND)
-	    && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
+	    && (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
 		status =
 		    acpi_ut_get_package_object_size(internal_object,
 						    obj_length);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 69cbc57..09a2240 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -92,7 +92,7 @@
 #endif
 	struct acpi_device *device;
 	unsigned long update_time;
-	int current_now;
+	int rate_now;
 	int capacity_now;
 	int voltage_now;
 	int design_capacity;
@@ -196,7 +196,8 @@
 		val->intval = battery->voltage_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = battery->current_now * 1000;
+	case POWER_SUPPLY_PROP_POWER_NOW:
+		val->intval = battery->rate_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@ -247,6 +248,7 @@
 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_POWER_NOW,
 	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 	POWER_SUPPLY_PROP_ENERGY_FULL,
 	POWER_SUPPLY_PROP_ENERGY_NOW,
@@ -273,7 +275,7 @@
 
 static struct acpi_offsets state_offsets[] = {
 	{offsetof(struct acpi_battery, state), 0},
-	{offsetof(struct acpi_battery, current_now), 0},
+	{offsetof(struct acpi_battery, rate_now), 0},
 	{offsetof(struct acpi_battery, capacity_now), 0},
 	{offsetof(struct acpi_battery, voltage_now), 0},
 };
@@ -605,11 +607,11 @@
 	else
 		seq_printf(seq, "charging state:          charged\n");
 
-	if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present rate:            unknown\n");
 	else
 		seq_printf(seq, "present rate:            %d %s\n",
-			   battery->current_now, acpi_battery_units(battery));
+			   battery->rate_now, acpi_battery_units(battery));
 
 	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "remaining capacity:      unknown\n");
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index bee64b7..e8f7b64 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,6 +39,8 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#include "internal.h"
+
 #define _COMPONENT		ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("bus");
 
@@ -846,6 +848,7 @@
 		acpi_kobj = NULL;
 	}
 
+	init_acpi_device_notify();
 	result = acpi_bus_init();
 
 	if (!result) {
@@ -860,11 +863,23 @@
 		}
 	} else
 		disable_acpi();
+
+	if (acpi_disabled)
+		return result;
+
 	/*
 	 * 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);
+
+	acpi_scan_init();
+	acpi_ec_init();
+	acpi_power_init();
+	acpi_system_init();
+	acpi_debug_init();
+	acpi_sleep_proc_init();
+	acpi_wakeup_device_init();
 	return result;
 }
 
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 20223cb..9cb189f 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -297,17 +297,15 @@
 
 	return count;
 }
+#endif
 
-static int __init acpi_debug_init(void)
+int __init acpi_debug_init(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *entry;
 	int error = 0;
 	char *name;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	/* 'debug_layer' [R/W] */
 	name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
 	entry =
@@ -338,7 +336,7 @@
 	remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
 	error = -ENODEV;
 	goto Done;
-}
-
-subsys_initcall(acpi_debug_init);
+#else
+	return 0;
 #endif
+}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 2fe1506..bf88f18 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1069,13 +1069,10 @@
 		},
 };
 
-static int __init acpi_ec_init(void)
+int __init acpi_ec_init(void)
 {
 	int result = 0;
 
-	if (acpi_disabled)
-		return 0;
-
 	acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
 	if (!acpi_ec_dir)
 		return -ENODEV;
@@ -1090,8 +1087,6 @@
 	return result;
 }
 
-subsys_initcall(acpi_ec_init);
-
 /* EC driver currently not unloadable */
 #if 0
 static void __exit acpi_ec_exit(void)
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index eaaee16..ae41cf3 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -68,31 +68,35 @@
 };
 
 /* thermal cooling device callbacks */
-static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
+			     *state)
 {
 	/* ACPI fan device only support two states: ON/OFF */
-	return sprintf(buf, "1\n");
+	*state = 1;
+	return 0;
 }
 
-static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
+			     *state)
 {
 	struct acpi_device *device = cdev->devdata;
-	int state;
 	int result;
+	int acpi_state;
 
 	if (!device)
 		return -EINVAL;
 
-	result = acpi_bus_get_power(device->handle, &state);
+	result = acpi_bus_get_power(device->handle, &acpi_state);
 	if (result)
 		return result;
 
-	return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" :
-			 (state == ACPI_STATE_D0 ? "1" : "unknown"));
+	*state = (acpi_state == ACPI_STATE_D3 ? 0 :
+		 (acpi_state == ACPI_STATE_D0 ? 1 : -1));
+	return 0;
 }
 
 static int
-fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	int result;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5479b9f..8bd2c2a 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -286,10 +286,8 @@
 	return 0;
 }
 
-static int __init init_acpi_device_notify(void)
+int __init init_acpi_device_notify(void)
 {
-	if (acpi_disabled)
-		return 0;
 	if (platform_notify || platform_notify_remove) {
 		printk(KERN_ERR PREFIX "Can't use platform_notify\n");
 		return 0;
@@ -298,5 +296,3 @@
 	platform_notify_remove = acpi_platform_notify_remove;
 	return 0;
 }
-
-arch_initcall(init_acpi_device_notify);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
new file mode 100644
index 0000000..11a69b5
--- /dev/null
+++ b/drivers/acpi/internal.h
@@ -0,0 +1,43 @@
+/* For use by Linux/ACPI infrastructure, not drivers */
+
+int init_acpi_device_notify(void);
+int acpi_scan_init(void);
+int acpi_system_init(void);
+
+#ifdef CONFIG_ACPI_DEBUG
+int acpi_debug_init(void);
+#else
+static inline int acpi_debug_init(void) { return 0; }
+#endif
+
+/* --------------------------------------------------------------------------
+                                  Power Resource
+   -------------------------------------------------------------------------- */
+int acpi_power_init(void);
+int acpi_device_sleep_wake(struct acpi_device *dev,
+                           int enable, int sleep_state, int dev_state);
+int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
+
+int acpi_wakeup_device_init(void);
+
+/* --------------------------------------------------------------------------
+                                  Embedded Controller
+   -------------------------------------------------------------------------- */
+int acpi_ec_init(void);
+int acpi_ec_ecdt_probe(void);
+int acpi_boot_ec_enable(void);
+
+/*--------------------------------------------------------------------------
+                                  Suspend/Resume
+  -------------------------------------------------------------------------- */
+extern int acpi_sleep_init(void);
+
+#ifdef CONFIG_ACPI_SLEEP
+int acpi_sleep_proc_init(void);
+#else
+static inline int acpi_sleep_proc_init(void) { return 0; }
+#endif
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 891bdf6..be6b909 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -319,7 +319,7 @@
 	 */
 	bridge = dev->bus->self;
 	while (bridge) {
-		pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+		pin = pci_swizzle_interrupt_pin(dev, pin);
 
 		if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
 			/* PC card has the same IRQ as its cardbridge */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 6c772ca..16e0f9d 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -43,13 +43,14 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define _COMPONENT		ACPI_PCI_COMPONENT
+#define _COMPONENT			ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_CLASS		"pci_irq_routing"
 #define ACPI_PCI_LINK_DEVICE_NAME	"PCI Interrupt Link"
 #define ACPI_PCI_LINK_FILE_INFO		"info"
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
-#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+#define ACPI_PCI_LINK_MAX_POSSIBLE	16
+
 static int acpi_pci_link_add(struct acpi_device *device);
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
@@ -66,7 +67,7 @@
 	.ops = {
 		.add = acpi_pci_link_add,
 		.remove = acpi_pci_link_remove,
-		},
+	},
 };
 
 /*
@@ -76,7 +77,7 @@
 struct acpi_pci_link_irq {
 	u8 active;		/* Current IRQ */
 	u8 triggering;		/* All IRQs */
-	u8 polarity;	/* All IRQs */
+	u8 polarity;		/* All IRQs */
 	u8 resource_type;
 	u8 possible_count;
 	u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -85,16 +86,13 @@
 };
 
 struct acpi_pci_link {
-	struct list_head node;
-	struct acpi_device *device;
-	struct acpi_pci_link_irq irq;
-	int refcnt;
+	struct list_head		list;
+	struct acpi_device		*device;
+	struct acpi_pci_link_irq	irq;
+	int				refcnt;
 };
 
-static struct {
-	int count;
-	struct list_head entries;
-} acpi_link;
+static LIST_HEAD(acpi_link_list);
 static DEFINE_MUTEX(acpi_link_lock);
 
 /* --------------------------------------------------------------------------
@@ -104,12 +102,11 @@
 /*
  * set context (link) possible list from resource list
  */
-static acpi_status
-acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
+						void *context)
 {
 	struct acpi_pci_link *link = context;
-	u32 i = 0;
-
+	u32 i;
 
 	switch (resource->type) {
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -179,10 +176,6 @@
 {
 	acpi_status status;
 
-
-	if (!link)
-		return -EINVAL;
-
 	status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
 				     acpi_pci_link_check_possible, link);
 	if (ACPI_FAILURE(status)) {
@@ -197,11 +190,10 @@
 	return 0;
 }
 
-static acpi_status
-acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
+					       void *context)
 {
-	int *irq = (int *)context;
-
+	int *irq = context;
 
 	switch (resource->type) {
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -258,12 +250,9 @@
 static int acpi_pci_link_get_current(struct acpi_pci_link *link)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
+	acpi_status status;
 	int irq = 0;
 
-	if (!link)
-		return -EINVAL;
-
 	link->irq.active = 0;
 
 	/* in practice, status disabled is meaningless, ignore it */
@@ -308,16 +297,15 @@
 
 static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
 {
-	int result = 0;
-	acpi_status status = AE_OK;
+	int result;
+	acpi_status status;
 	struct {
 		struct acpi_resource res;
 		struct acpi_resource end;
 	} *resource;
 	struct acpi_buffer buffer = { 0, NULL };
 
-
-	if (!link || !irq)
+	if (!irq)
 		return -EINVAL;
 
 	resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
@@ -479,30 +467,22 @@
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ9  PCI, often acpi */
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ10 PCI */
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ11 PCI */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ12 mouse */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ13 fpe, sometimes */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ14 ide0 */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ15 ide1 */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ12 mouse */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ13 fpe, sometimes */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ14 ide0 */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ15 ide1 */
 	/* >IRQ15 */
 };
 
 int __init acpi_irq_penalty_init(void)
 {
-	struct list_head *node = NULL;
-	struct acpi_pci_link *link = NULL;
-	int i = 0;
-
+	struct acpi_pci_link *link;
+	int i;
 
 	/*
 	 * Update penalties to facilitate IRQ balancing.
 	 */
-	list_for_each(node, &acpi_link.entries) {
-
-		link = list_entry(node, struct acpi_pci_link, node);
-		if (!link) {
-			printk(KERN_ERR PREFIX "Invalid link context\n");
-			continue;
-		}
+	list_for_each_entry(link, &acpi_link_list, list) {
 
 		/*
 		 * reflect the possible and active irqs in the penalty table --
@@ -527,7 +507,6 @@
 	}
 	/* Add a penalty for the SCI */
 	acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
-
 	return 0;
 }
 
@@ -538,7 +517,6 @@
 	int irq;
 	int i;
 
-
 	if (link->irq.initialized) {
 		if (link->refcnt == 0)
 			/* This means the link is disabled but initialized */
@@ -566,11 +544,10 @@
 	/*
 	 * if active found, use it; else pick entry from end of possible list.
 	 */
-	if (link->irq.active) {
+	if (link->irq.active)
 		irq = link->irq.active;
-	} else {
+	else
 		irq = link->irq.possible[link->irq.possible_count - 1];
-	}
 
 	if (acpi_irq_balance || !link->irq.active) {
 		/*
@@ -599,7 +576,6 @@
 	}
 
 	link->irq.initialized = 1;
-
 	return 0;
 }
 
@@ -608,16 +584,12 @@
  * success: return IRQ >= 0
  * failure: return -1
  */
-
-int
-acpi_pci_link_allocate_irq(acpi_handle handle,
-			   int index,
-			   int *triggering, int *polarity, char **name)
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
+			       int *polarity, char **name)
 {
-	int result = 0;
-	struct acpi_device *device = NULL;
-	struct acpi_pci_link *link = NULL;
-
+	int result;
+	struct acpi_device *device;
+	struct acpi_pci_link *link;
 
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
@@ -669,11 +641,10 @@
  */
 int acpi_pci_link_free_irq(acpi_handle handle)
 {
-	struct acpi_device *device = NULL;
-	struct acpi_pci_link *link = NULL;
+	struct acpi_device *device;
+	struct acpi_pci_link *link;
 	acpi_status result;
 
-
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
 		printk(KERN_ERR PREFIX "Invalid link device\n");
@@ -708,9 +679,9 @@
 			  "Link %s is dereferenced\n",
 			  acpi_device_bid(link->device)));
 
-	if (link->refcnt == 0) {
+	if (link->refcnt == 0)
 		acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
-	}
+
 	mutex_unlock(&acpi_link_lock);
 	return (link->irq.active);
 }
@@ -721,15 +692,11 @@
 
 static int acpi_pci_link_add(struct acpi_device *device)
 {
-	int result = 0;
-	struct acpi_pci_link *link = NULL;
-	int i = 0;
+	int result;
+	struct acpi_pci_link *link;
+	int i;
 	int found = 0;
 
-
-	if (!device)
-		return -EINVAL;
-
 	link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
 	if (!link)
 		return -ENOMEM;
@@ -767,9 +734,7 @@
 
 	printk("\n");
 
-	/* TBD: Acquire/release lock */
-	list_add_tail(&link->node, &acpi_link.entries);
-	acpi_link.count++;
+	list_add_tail(&link->list, &acpi_link_list);
 
       end:
 	/* disable all links -- to be activated on use */
@@ -784,24 +749,17 @@
 
 static int acpi_pci_link_resume(struct acpi_pci_link *link)
 {
-
 	if (link->refcnt && link->irq.active && link->irq.initialized)
 		return (acpi_pci_link_set(link, link->irq.active));
-	else
-		return 0;
+
+	return 0;
 }
 
 static int irqrouter_resume(struct sys_device *dev)
 {
-	struct list_head *node = NULL;
-	struct acpi_pci_link *link = NULL;
+	struct acpi_pci_link *link;
 
-	list_for_each(node, &acpi_link.entries) {
-		link = list_entry(node, struct acpi_pci_link, node);
-		if (!link) {
-			printk(KERN_ERR PREFIX "Invalid link context\n");
-			continue;
-		}
+	list_for_each_entry(link, &acpi_link_list, list) {
 		acpi_pci_link_resume(link);
 	}
 	return 0;
@@ -809,20 +767,15 @@
 
 static int acpi_pci_link_remove(struct acpi_device *device, int type)
 {
-	struct acpi_pci_link *link = NULL;
-
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
+	struct acpi_pci_link *link;
 
 	link = acpi_driver_data(device);
 
 	mutex_lock(&acpi_link_lock);
-	list_del(&link->node);
+	list_del(&link->list);
 	mutex_unlock(&acpi_link_lock);
 
 	kfree(link);
-
 	return 0;
 }
 
@@ -931,7 +884,6 @@
 {
 	int error;
 
-
 	if (acpi_disabled || acpi_noirq)
 		return 0;
 
@@ -957,9 +909,6 @@
 			acpi_irq_balance = 0;
 	}
 
-	acpi_link.count = 0;
-	INIT_LIST_HEAD(&acpi_link.entries);
-
 	if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
 		return -ENODEV;
 
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index c926e7d..11968ba2 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -773,14 +773,10 @@
 	return 0;
 }
 
-static int __init acpi_power_init(void)
+int __init acpi_power_init(void)
 {
 	int result = 0;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	INIT_LIST_HEAD(&acpi_power_resource_list);
 
 	acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
@@ -795,5 +791,3 @@
 
 	return 0;
 }
-
-subsys_initcall(acpi_power_init);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 428c911d..05dfdc9 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -496,11 +496,8 @@
 }
 #endif				/* HAVE_ACPI_LEGACY_ALARM */
 
-static int __init acpi_sleep_proc_init(void)
+int __init acpi_sleep_proc_init(void)
 {
-	if (acpi_disabled)
-		return 0;
-
 #ifdef	CONFIG_ACPI_PROCFS
 	/* 'sleep' [R/W] */
 	proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
@@ -527,5 +524,3 @@
 
 	return 0;
 }
-
-late_initcall(acpi_sleep_proc_init);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7bc22a4..4e6e758 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -64,7 +64,6 @@
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_idle");
 #define ACPI_PROCESSOR_FILE_POWER	"power"
-#define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define PM_TIMER_TICK_NS		(1000000000ULL/PM_TIMER_FREQUENCY)
 #define C2_OVERHEAD			1	/* 1us */
 #define C3_OVERHEAD			1	/* 1us */
@@ -78,6 +77,10 @@
 static unsigned int latency_factor __read_mostly = 2;
 module_param(latency_factor, uint, 0644);
 
+static s64 us_to_pm_timer_ticks(s64 t)
+{
+	return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
+}
 /*
  * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
  * For now disable this. Probably a bug somewhere else.
@@ -101,57 +104,6 @@
 /* Actually this shouldn't be __cpuinitdata, would be better to fix the
    callers to only run once -AK */
 static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
-	{ set_max_cstate, "Medion 41700", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
 	{ set_max_cstate, "Clevo 5600D", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -159,25 +111,6 @@
 	{},
 };
 
-static inline u32 ticks_elapsed(u32 t1, u32 t2)
-{
-	if (t2 >= t1)
-		return (t2 - t1);
-	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-	else
-		return ((0xFFFFFFFF - t1) + t2);
-}
-
-static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
-{
-	if (t2 >= t1)
-		return PM_TIMER_TICKS_TO_US(t2 - t1);
-	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-		return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-	else
-		return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
-}
 
 /*
  * Callers should disable interrupts before the call and enable
@@ -630,7 +563,7 @@
 	 * In either case, the proper way to
 	 * handle BM_RLD is to set it and leave it set.
 	 */
-	acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+	acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
 
 	return;
 }
@@ -800,9 +733,9 @@
 {
 	u32 bm_status = 0;
 
-	acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+	acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
 	if (bm_status)
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+		acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
 	/*
 	 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
 	 * the true state of bus mastering activity; forcing us to
@@ -853,7 +786,8 @@
 static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 			      struct cpuidle_state *state)
 {
-	u32 t1, t2;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
 
@@ -871,14 +805,15 @@
 		return 0;
 	}
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt1 = ktime_get_real();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 	local_irq_enable();
 	cx->usage++;
 
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 /**
@@ -891,8 +826,9 @@
 {
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-	u32 t1, t2;
-	int sleep_ticks = 0;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
+	s64 sleep_ticks = 0;
 
 	pr = __get_cpu_var(processors);
 
@@ -925,18 +861,19 @@
 	if (cx->type == ACPI_STATE_C3)
 		ACPI_FLUSH_CPU_CACHE();
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt1 = ktime_get_real();
 	/* Tell the scheduler that we are going deep-idle: */
 	sched_clock_idle_sleep_event();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
 	/* TSC could halt in idle, so notify users */
 	if (tsc_halts_in_c(cx->type))
 		mark_tsc_unstable("TSC halts in idle");;
 #endif
-	sleep_ticks = ticks_elapsed(t1, t2);
+	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +885,7 @@
 
 	acpi_state_timer_broadcast(pr, cx, 0);
 	cx->time += sleep_ticks;
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 static int c3_cpu_count;
@@ -966,8 +903,10 @@
 {
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-	u32 t1, t2;
-	int sleep_ticks = 0;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
+	s64 sleep_ticks = 0;
+
 
 	pr = __get_cpu_var(processors);
 
@@ -1028,20 +967,21 @@
 		c3_cpu_count++;
 		/* Disable bus master arbitration when all CPUs are in C3 */
 		if (c3_cpu_count == num_online_cpus())
-			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+			acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
 		spin_unlock(&c3_lock);
 	} else if (!pr->flags.bm_check) {
 		ACPI_FLUSH_CPU_CACHE();
 	}
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt1 = ktime_get_real();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 	/* Re-enable bus master arbitration */
 	if (pr->flags.bm_check && pr->flags.bm_control) {
 		spin_lock(&c3_lock);
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
 		c3_cpu_count--;
 		spin_unlock(&c3_lock);
 	}
@@ -1051,7 +991,7 @@
 	if (tsc_halts_in_c(ACPI_STATE_C3))
 		mark_tsc_unstable("TSC halts in idle");
 #endif
-	sleep_ticks = ticks_elapsed(t1, t2);
+	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
 
@@ -1062,7 +1002,7 @@
 
 	acpi_state_timer_broadcast(pr, cx, 0);
 	cx->time += sleep_ticks;
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 struct cpuidle_driver acpi_idle_driver = {
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 9cc769b..215f1bf7 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -479,6 +479,13 @@
 		goto end;
 	}
 
+	if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+		printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
+		result = -EFAULT;
+		goto end;
+	}
 end:
 	kfree(buffer.pointer);
 	return result;
@@ -501,9 +508,10 @@
 
 	mutex_lock(&performance_mutex);
 
-	retval = 0;
-
-	/* Call _PSD for all CPUs */
+	/*
+	 * Check if another driver has already registered, and abort before
+	 * changing pr->performance if it has. Check input data as well.
+	 */
 	for_each_possible_cpu(i) {
 		pr = per_cpu(processors, i);
 		if (!pr) {
@@ -513,13 +521,20 @@
 
 		if (pr->performance) {
 			retval = -EBUSY;
-			continue;
+			goto err_out;
 		}
 
 		if (!performance || !percpu_ptr(performance, i)) {
 			retval = -EINVAL;
-			continue;
+			goto err_out;
 		}
+	}
+
+	/* Call _PSD for all CPUs */
+	for_each_possible_cpu(i) {
+		pr = per_cpu(processors, i);
+		if (!pr)
+			continue;
 
 		pr->performance = percpu_ptr(performance, i);
 		cpumask_set_cpu(i, pr->performance->shared_cpu_map);
@@ -535,26 +550,6 @@
 	 * Now that we have _PSD data from all CPUs, lets setup P-state 
 	 * domain info.
 	 */
-	for_each_possible_cpu(i) {
-		pr = per_cpu(processors, i);
-		if (!pr)
-			continue;
-
-		/* Basic validity check for domain info */
-		pdomain = &(pr->performance->domain_info);
-		if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
-		    (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
-			retval = -EINVAL;
-			goto err_ret;
-		}
-		if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
-		    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
-		    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
-			retval = -EINVAL;
-			goto err_ret;
-		}
-	}
-
 	cpumask_clear(covered_cpus);
 	for_each_possible_cpu(i) {
 		pr = per_cpu(processors, i);
@@ -643,6 +638,7 @@
 		pr->performance = NULL; /* Will be set for real in register */
 	}
 
+err_out:
 	mutex_unlock(&performance_mutex);
 	free_cpumask_var(covered_cpus);
 	return retval;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index b1eb376..0e47e29 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -373,7 +373,8 @@
 	return max_state;
 }
 static int
-processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_max_state(struct thermal_cooling_device *cdev,
+			unsigned long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
@@ -381,28 +382,29 @@
 	if (!device || !pr)
 		return -EINVAL;
 
-	return sprintf(buf, "%d\n", acpi_processor_max_state(pr));
+	*state = acpi_processor_max_state(pr);
+	return 0;
 }
 
 static int
-processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_cur_state(struct thermal_cooling_device *cdev,
+			unsigned long *cur_state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
-	int cur_state;
 
 	if (!device || !pr)
 		return -EINVAL;
 
-	cur_state = cpufreq_get_cur_state(pr->id);
+	*cur_state = cpufreq_get_cur_state(pr->id);
 	if (pr->flags.throttling)
-		cur_state += pr->throttling.state;
-
-	return sprintf(buf, "%d\n", cur_state);
+		*cur_state += pr->throttling.state;
+	return 0;
 }
 
 static int
-processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+processor_set_cur_state(struct thermal_cooling_device *cdev,
+			unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 6050ce4..3963cb6e 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -102,8 +102,8 @@
 	u16 cycle_count;
 	u16 temp_now;
 	u16 voltage_now;
-	s16 current_now;
-	s16 current_avg;
+	s16 rate_now;
+	s16 rate_avg;
 	u16 capacity_now;
 	u16 state_of_charge;
 	u16 state;
@@ -202,9 +202,9 @@
 		return -ENODEV;
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
-		if (battery->current_now < 0)
+		if (battery->rate_now < 0)
 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
-		else if (battery->current_now > 0)
+		else if (battery->rate_now > 0)
 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
 		else
 			val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -224,11 +224,13 @@
 				acpi_battery_vscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = abs(battery->current_now) *
+	case POWER_SUPPLY_PROP_POWER_NOW:
+		val->intval = abs(battery->rate_now) *
 				acpi_battery_ipscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_AVG:
-		val->intval = abs(battery->current_avg) *
+	case POWER_SUPPLY_PROP_POWER_AVG:
+		val->intval = abs(battery->rate_avg) *
 				acpi_battery_ipscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
@@ -293,6 +295,8 @@
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_POWER_NOW,
+	POWER_SUPPLY_PROP_POWER_AVG,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 	POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -301,6 +305,7 @@
 	POWER_SUPPLY_PROP_MODEL_NAME,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
+
 #endif
 
 /* --------------------------------------------------------------------------
@@ -330,8 +335,8 @@
 static struct acpi_battery_reader state_readers[] = {
 	{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
 	{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
-	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
-	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
+	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
 	{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
 	{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
 	{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@ -589,9 +594,9 @@
 	seq_printf(seq, "capacity state:          %s\n",
 		   (battery->state & 0x0010) ? "critical" : "ok");
 	seq_printf(seq, "charging state:          %s\n",
-		   (battery->current_now < 0) ? "discharging" :
-		   ((battery->current_now > 0) ? "charging" : "charged"));
-	rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
+		   (battery->rate_now < 0) ? "discharging" :
+		   ((battery->rate_now > 0) ? "charging" : "charged"));
+	rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
 	rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
 			acpi_battery_vscale(battery)/1000):1;
 	seq_printf(seq, "present rate:            %d%s\n", rate,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c54d7b6..b7308ef 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,6 +11,8 @@
 
 #include <acpi/acpi_drivers.h>
 
+#include "internal.h"
+
 #define _COMPONENT		ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("scan");
 #define STRUCT_TO_INT(s)	(*((int*)&s))
@@ -395,22 +397,10 @@
 	return 0;
 }
 
-static void acpi_device_shutdown(struct device *dev)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_driver *acpi_drv = acpi_dev->driver;
-
-	if (acpi_drv && acpi_drv->ops.shutdown)
-		acpi_drv->ops.shutdown(acpi_dev);
-
-	return ;
-}
-
 struct bus_type acpi_bus_type = {
 	.name		= "acpi",
 	.suspend	= acpi_device_suspend,
 	.resume		= acpi_device_resume,
-	.shutdown	= acpi_device_shutdown,
 	.match		= acpi_bus_match,
 	.probe		= acpi_device_probe,
 	.remove		= acpi_device_remove,
@@ -1524,16 +1514,11 @@
 	return result;
 }
 
-
-static int __init acpi_scan_init(void)
+int __init acpi_scan_init(void)
 {
 	int result;
 	struct acpi_bus_ops ops;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 	ops.acpi_op_start = 1;
@@ -1566,5 +1551,3 @@
       Done:
 	return result;
 }
-
-subsys_initcall(acpi_scan_init);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 00456fc..91a284b 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -21,6 +21,8 @@
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+
+#include "internal.h"
 #include "sleep.h"
 
 u8 sleep_states[ACPI_S_STATE_COUNT];
@@ -248,7 +250,7 @@
 
 	/* If ACPI is not enabled by the BIOS, we need to enable it here. */
 	if (set_sci_en_on_resume)
-		acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
+		acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
 	else
 		acpi_enable();
 
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 391d035..44be75e 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -62,6 +62,7 @@
    -------------------------------------------------------------------------- */
 static LIST_HEAD(acpi_table_attr_list);
 static struct kobject *tables_kobj;
+static struct kobject *dynamic_tables_kobj;
 
 struct acpi_table_attr {
 	struct bin_attribute attr;
@@ -128,6 +129,40 @@
 	return;
 }
 
+static acpi_status
+acpi_sysfs_table_handler(u32 event, void *table, void *context)
+{
+	struct acpi_table_attr *table_attr;
+
+	switch (event) {
+	case ACPI_TABLE_EVENT_LOAD:
+		table_attr =
+			kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+		if (!table_attr)
+			return AE_NO_MEMORY;
+
+		acpi_table_attr_init(table_attr, table);
+		if (sysfs_create_bin_file(dynamic_tables_kobj,
+					&table_attr->attr)) {
+			kfree(table_attr);
+			return AE_ERROR;
+		} else
+			list_add_tail(&table_attr->node,
+					&acpi_table_attr_list);
+		break;
+	case ACPI_TABLE_EVENT_UNLOAD:
+		/*
+		 * we do not need to do anything right now
+		 * because the table is not deleted from the
+		 * global table list when unloading it.
+		 */
+		break;
+	default:
+		return AE_BAD_PARAMETER;
+	}
+	return AE_OK;
+}
+
 static int acpi_system_sysfs_init(void)
 {
 	struct acpi_table_attr *table_attr;
@@ -137,7 +172,11 @@
 
 	tables_kobj = kobject_create_and_add("tables", acpi_kobj);
 	if (!tables_kobj)
-		return -ENOMEM;
+		goto err;
+
+	dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
+	if (!dynamic_tables_kobj)
+		goto err_dynamic_tables;
 
 	do {
 		result = acpi_get_table_by_index(table_index, &table_header);
@@ -162,8 +201,14 @@
 		}
 	} while (!result);
 	kobject_uevent(tables_kobj, KOBJ_ADD);
+	kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
+	result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
 
-	return 0;
+	return result == AE_OK ? 0 : -EINVAL;
+err_dynamic_tables:
+	kobject_put(tables_kobj);
+err:
+	return -ENOMEM;
 }
 
 /*
@@ -571,12 +616,9 @@
 }
 #endif
 
-static int __init acpi_system_init(void)
+int __init acpi_system_init(void)
 {
-	int result = 0;
-
-	if (acpi_disabled)
-		return 0;
+	int result;
 
 	result = acpi_system_procfs_init();
 	if (result)
@@ -586,5 +628,3 @@
 
 	return result;
 }
-
-subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 99e6f1f..6b95997 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,11 +37,11 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/kmod.h>
 #include <linux/seq_file.h>
 #include <linux/reboot.h>
+#include <linux/device.h>
 #include <asm/uaccess.h>
 #include <linux/thermal.h>
 #include <acpi/acpi_bus.h>
@@ -190,7 +190,6 @@
 	struct acpi_thermal_state state;
 	struct acpi_thermal_trips trips;
 	struct acpi_handle_list devices;
-	struct timer_list timer;
 	struct thermal_zone_device *thermal_zone;
 	int tz_enabled;
 	struct mutex lock;
@@ -290,6 +289,11 @@
 
 	tz->polling_frequency = seconds * 10;	/* Convert value to deci-seconds */
 
+	tz->thermal_zone->polling_delay = seconds * 1000;
+
+	if (tz->tz_enabled)
+		thermal_zone_device_update(tz->thermal_zone);
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "Polling frequency set to %lu seconds\n",
 			  tz->polling_frequency/10));
@@ -569,392 +573,18 @@
 	return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
 }
 
-static int acpi_thermal_critical(struct acpi_thermal *tz)
-{
-	if (!tz || !tz->trips.critical.flags.valid)
-		return -EINVAL;
-
-	if (tz->temperature >= tz->trips.critical.temperature) {
-		printk(KERN_WARNING PREFIX "Critical trip point\n");
-		tz->trips.critical.flags.enabled = 1;
-	} else if (tz->trips.critical.flags.enabled)
-		tz->trips.critical.flags.enabled = 0;
-
-	acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
-				tz->trips.critical.flags.enabled);
-	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
-					  dev_name(&tz->device->dev),
-					  ACPI_THERMAL_NOTIFY_CRITICAL,
-					  tz->trips.critical.flags.enabled);
-
-	/* take no action if nocrt is set */
-	if(!nocrt) {
-		printk(KERN_EMERG
-			"Critical temperature reached (%ld C), shutting down.\n",
-			KELVIN_TO_CELSIUS(tz->temperature));
-		orderly_poweroff(true);
-	}
-
-	return 0;
-}
-
-static int acpi_thermal_hot(struct acpi_thermal *tz)
-{
-	if (!tz || !tz->trips.hot.flags.valid)
-		return -EINVAL;
-
-	if (tz->temperature >= tz->trips.hot.temperature) {
-		printk(KERN_WARNING PREFIX "Hot trip point\n");
-		tz->trips.hot.flags.enabled = 1;
-	} else if (tz->trips.hot.flags.enabled)
-		tz->trips.hot.flags.enabled = 0;
-
-	acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
-				tz->trips.hot.flags.enabled);
-	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
-					  dev_name(&tz->device->dev),
-					  ACPI_THERMAL_NOTIFY_HOT,
-					  tz->trips.hot.flags.enabled);
-
-	/* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
-
-	return 0;
-}
-
-static void acpi_thermal_passive(struct acpi_thermal *tz)
-{
-	int result = 1;
-	struct acpi_thermal_passive *passive = NULL;
-	int trend = 0;
-	int i = 0;
-
-
-	if (!tz || !tz->trips.passive.flags.valid)
-		return;
-
-	passive = &(tz->trips.passive);
-
-	/*
-	 * Above Trip?
-	 * -----------
-	 * Calculate the thermal trend (using the passive cooling equation)
-	 * and modify the performance limit for all passive cooling devices
-	 * accordingly.  Note that we assume symmetry.
-	 */
-	if (tz->temperature >= passive->temperature) {
-		trend =
-		    (passive->tc1 * (tz->temperature - tz->last_temperature)) +
-		    (passive->tc2 * (tz->temperature - passive->temperature));
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
-				  trend, passive->tc1, tz->temperature,
-				  tz->last_temperature, passive->tc2,
-				  tz->temperature, passive->temperature));
-		passive->flags.enabled = 1;
-		/* Heating up? */
-		if (trend > 0)
-			for (i = 0; i < passive->devices.count; i++)
-				acpi_processor_set_thermal_limit(passive->
-								 devices.
-								 handles[i],
-								 ACPI_PROCESSOR_LIMIT_INCREMENT);
-		/* Cooling off? */
-		else if (trend < 0) {
-			for (i = 0; i < passive->devices.count; i++)
-				/*
-				 * assume that we are on highest
-				 * freq/lowest thrott and can leave
-				 * passive mode, even in error case
-				 */
-				if (!acpi_processor_set_thermal_limit
-				    (passive->devices.handles[i],
-				     ACPI_PROCESSOR_LIMIT_DECREMENT))
-					result = 0;
-			/*
-			 * Leave cooling mode, even if the temp might
-			 * higher than trip point This is because some
-			 * machines might have long thermal polling
-			 * frequencies (tsp) defined. We will fall back
-			 * into passive mode in next cycle (probably quicker)
-			 */
-			if (result) {
-				passive->flags.enabled = 0;
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-						  "Disabling passive cooling, still above threshold,"
-						  " but we are cooling down\n"));
-			}
-		}
-		return;
-	}
-
-	/*
-	 * Below Trip?
-	 * -----------
-	 * Implement passive cooling hysteresis to slowly increase performance
-	 * and avoid thrashing around the passive trip point.  Note that we
-	 * assume symmetry.
-	 */
-	if (!passive->flags.enabled)
-		return;
-	for (i = 0; i < passive->devices.count; i++)
-		if (!acpi_processor_set_thermal_limit
-		    (passive->devices.handles[i],
-		     ACPI_PROCESSOR_LIMIT_DECREMENT))
-			result = 0;
-	if (result) {
-		passive->flags.enabled = 0;
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Disabling passive cooling (zone is cool)\n"));
-	}
-}
-
-static void acpi_thermal_active(struct acpi_thermal *tz)
-{
-	int result = 0;
-	struct acpi_thermal_active *active = NULL;
-	int i = 0;
-	int j = 0;
-	unsigned long maxtemp = 0;
-
-
-	if (!tz)
-		return;
-
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		active = &(tz->trips.active[i]);
-		if (!active || !active->flags.valid)
-			break;
-		if (tz->temperature >= active->temperature) {
-			/*
-			 * Above Threshold?
-			 * ----------------
-			 * If not already enabled, turn ON all cooling devices
-			 * associated with this active threshold.
-			 */
-			if (active->temperature > maxtemp)
-				tz->state.active_index = i;
-			maxtemp = active->temperature;
-			if (active->flags.enabled)
-				continue;
-			for (j = 0; j < active->devices.count; j++) {
-				result =
-				    acpi_bus_set_power(active->devices.
-						       handles[j],
-						       ACPI_STATE_D0);
-				if (result) {
-					printk(KERN_WARNING PREFIX
-						      "Unable to turn cooling device [%p] 'on'\n",
-						      active->devices.
-						      handles[j]);
-					continue;
-				}
-				active->flags.enabled = 1;
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-						  "Cooling device [%p] now 'on'\n",
-						  active->devices.handles[j]));
-			}
-			continue;
-		}
-		if (!active->flags.enabled)
-			continue;
-		/*
-		 * Below Threshold?
-		 * ----------------
-		 * Turn OFF all cooling devices associated with this
-		 * threshold.
-		 */
-		for (j = 0; j < active->devices.count; j++) {
-			result = acpi_bus_set_power(active->devices.handles[j],
-						    ACPI_STATE_D3);
-			if (result) {
-				printk(KERN_WARNING PREFIX
-					      "Unable to turn cooling device [%p] 'off'\n",
-					      active->devices.handles[j]);
-				continue;
-			}
-			active->flags.enabled = 0;
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Cooling device [%p] now 'off'\n",
-					  active->devices.handles[j]));
-		}
-	}
-}
-
-static void acpi_thermal_check(void *context);
-
-static void acpi_thermal_run(unsigned long data)
-{
-	struct acpi_thermal *tz = (struct acpi_thermal *)data;
-	if (!tz->zombie)
-		acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
-}
-
-static void acpi_thermal_active_off(void *data)
-{
-	int result = 0;
-	struct acpi_thermal *tz = data;
-	int i = 0;
-	int j = 0;
-	struct acpi_thermal_active *active = NULL;
-
-	if (!tz) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
-
-	result = acpi_thermal_get_temperature(tz);
-	if (result)
-		return;
-
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		active = &(tz->trips.active[i]);
-		if (!active || !active->flags.valid)
-			break;
-		if (tz->temperature >= active->temperature) {
-			/*
-			 * If the thermal temperature is greater than the
-			 * active threshod, unnecessary to turn off the
-			 * the active cooling device.
-			 */
-			continue;
-		}
-		/*
-		 * Below Threshold?
-		 * ----------------
-		 * Turn OFF all cooling devices associated with this
-		 * threshold.
-		 */
-		for (j = 0; j < active->devices.count; j++)
-			result = acpi_bus_set_power(active->devices.handles[j],
-						    ACPI_STATE_D3);
-	}
-}
-
 static void acpi_thermal_check(void *data)
 {
-	int result = 0;
 	struct acpi_thermal *tz = data;
-	unsigned long sleep_time = 0;
-	unsigned long timeout_jiffies = 0;
-	int i = 0;
-	struct acpi_thermal_state state;
 
-
-	if (!tz) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
-
-	/* Check if someone else is already running */
-	if (!mutex_trylock(&tz->lock))
-		return;
-
-	state = tz->state;
-
-	result = acpi_thermal_get_temperature(tz);
-	if (result)
-		goto unlock;
-
-	if (!tz->tz_enabled)
-		goto unlock;
-
-	memset(&tz->state, 0, sizeof(tz->state));
-
-	/*
-	 * Check Trip Points
-	 * -----------------
-	 * Compare the current temperature to the trip point values to see
-	 * if we've entered one of the thermal policy states.  Note that
-	 * this function determines when a state is entered, but the 
-	 * individual policy decides when it is exited (e.g. hysteresis).
-	 */
-	if (tz->trips.critical.flags.valid)
-		state.critical |=
-		    (tz->temperature >= tz->trips.critical.temperature);
-	if (tz->trips.hot.flags.valid)
-		state.hot |= (tz->temperature >= tz->trips.hot.temperature);
-	if (tz->trips.passive.flags.valid)
-		state.passive |=
-		    (tz->temperature >= tz->trips.passive.temperature);
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
-		if (tz->trips.active[i].flags.valid)
-			state.active |=
-			    (tz->temperature >=
-			     tz->trips.active[i].temperature);
-
-	/*
-	 * Invoke Policy
-	 * -------------
-	 * Separated from the above check to allow individual policy to 
-	 * determine when to exit a given state.
-	 */
-	if (state.critical)
-		acpi_thermal_critical(tz);
-	if (state.hot)
-		acpi_thermal_hot(tz);
-	if (state.passive)
-		acpi_thermal_passive(tz);
-	if (state.active)
-		acpi_thermal_active(tz);
-
-	/*
-	 * Calculate State
-	 * ---------------
-	 * Again, separated from the above two to allow independent policy
-	 * decisions.
-	 */
-	tz->state.critical = tz->trips.critical.flags.enabled;
-	tz->state.hot = tz->trips.hot.flags.enabled;
-	tz->state.passive = tz->trips.passive.flags.enabled;
-	tz->state.active = 0;
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
-		tz->state.active |= tz->trips.active[i].flags.enabled;
-
-	/*
-	 * Calculate Sleep Time
-	 * --------------------
-	 * If we're in the passive state, use _TSP's value.  Otherwise
-	 * use the default polling frequency (e.g. _TZP).  If no polling
-	 * frequency is specified then we'll wait forever (at least until
-	 * a thermal event occurs).  Note that _TSP and _TZD values are
-	 * given in 1/10th seconds (we must covert to milliseconds).
-	 */
-	if (tz->state.passive) {
-		sleep_time = tz->trips.passive.tsp * 100;
-		timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
-	} else if (tz->polling_frequency > 0) {
-		sleep_time = tz->polling_frequency * 100;
-		timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
-			  tz->name, tz->temperature, sleep_time));
-
-	/*
-	 * Schedule Next Poll
-	 * ------------------
-	 */
-	if (!sleep_time) {
-		if (timer_pending(&(tz->timer)))
-			del_timer(&(tz->timer));
-	} else {
-		if (timer_pending(&(tz->timer)))
-			mod_timer(&(tz->timer), timeout_jiffies);
-		else {
-			tz->timer.data = (unsigned long)tz;
-			tz->timer.function = acpi_thermal_run;
-			tz->timer.expires = timeout_jiffies;
-			add_timer(&(tz->timer));
-		}
-	}
-      unlock:
-	mutex_unlock(&tz->lock);
+	thermal_zone_device_update(tz->thermal_zone);
 }
 
 /* sys I/F for generic thermal sysfs support */
 #define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
 
-static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
+static int thermal_get_temp(struct thermal_zone_device *thermal,
+			    unsigned long *temp)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int result;
@@ -966,25 +596,28 @@
 	if (result)
 		return result;
 
-	return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
+	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
+	return 0;
 }
 
 static const char enabled[] = "kernel";
 static const char disabled[] = "user";
 static int thermal_get_mode(struct thermal_zone_device *thermal,
-				char *buf)
+				enum thermal_device_mode *mode)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 
 	if (!tz)
 		return -EINVAL;
 
-	return sprintf(buf, "%s\n", tz->tz_enabled ?
-			enabled : disabled);
+	*mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
+		THERMAL_DEVICE_DISABLED;
+
+	return 0;
 }
 
 static int thermal_set_mode(struct thermal_zone_device *thermal,
-				const char *buf)
+				enum thermal_device_mode mode)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int enable;
@@ -995,9 +628,9 @@
 	/*
 	 * enable/disable thermal management from ACPI thermal driver
 	 */
-	if (!strncmp(buf, enabled, sizeof enabled - 1))
+	if (mode == THERMAL_DEVICE_ENABLED)
 		enable = 1;
-	else if (!strncmp(buf, disabled, sizeof disabled - 1))
+	else if (mode == THERMAL_DEVICE_DISABLED)
 		enable = 0;
 	else
 		return -EINVAL;
@@ -1013,7 +646,7 @@
 }
 
 static int thermal_get_trip_type(struct thermal_zone_device *thermal,
-				 int trip, char *buf)
+				 int trip, enum thermal_trip_type *type)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int i;
@@ -1022,27 +655,35 @@
 		return -EINVAL;
 
 	if (tz->trips.critical.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "critical\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_CRITICAL;
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.hot.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "hot\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_HOT;
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.passive.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "passive\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_PASSIVE;
+			return 0;
+		}
 		trip--;
 	}
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 		tz->trips.active[i].flags.valid; i++) {
-		if (!trip)
-			return sprintf(buf, "active%d\n", i);
+		if (!trip) {
+			*type = THERMAL_TRIP_ACTIVE;
+			return 0;
+		}
 		trip--;
 	}
 
@@ -1050,7 +691,7 @@
 }
 
 static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
-				 int trip, char *buf)
+				 int trip, unsigned long *temp)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int i;
@@ -1059,31 +700,39 @@
 		return -EINVAL;
 
 	if (tz->trips.critical.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-				tz->trips.critical.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.critical.temperature);
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.hot.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.hot.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.hot.temperature);
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.passive.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.passive.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.passive.temperature);
+			return 0;
+		}
 		trip--;
 	}
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 		tz->trips.active[i].flags.valid; i++) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.active[i].temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.active[i].temperature);
+			return 0;
+		}
 		trip--;
 	}
 
@@ -1102,6 +751,29 @@
 		return -EINVAL;
 }
 
+static int thermal_notify(struct thermal_zone_device *thermal, int trip,
+			   enum thermal_trip_type trip_type)
+{
+	u8 type = 0;
+	struct acpi_thermal *tz = thermal->devdata;
+
+	if (trip_type == THERMAL_TRIP_CRITICAL)
+		type = ACPI_THERMAL_NOTIFY_CRITICAL;
+	else if (trip_type == THERMAL_TRIP_HOT)
+		type = ACPI_THERMAL_NOTIFY_HOT;
+	else
+		return 0;
+
+	acpi_bus_generate_proc_event(tz->device, type, 1);
+	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+					dev_name(&tz->device->dev), type, 1);
+
+	if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
+		return 1;
+
+	return 0;
+}
+
 typedef int (*cb)(struct thermal_zone_device *, int,
 		  struct thermal_cooling_device *);
 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1194,6 +866,7 @@
 	.get_trip_type = thermal_get_trip_type,
 	.get_trip_temp = thermal_get_trip_temp,
 	.get_crit_temp = thermal_get_crit_temp,
+	.notify = thermal_notify,
 };
 
 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1214,8 +887,21 @@
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 			tz->trips.active[i].flags.valid; i++, trips++);
-	tz->thermal_zone = thermal_zone_device_register("acpitz",
-					trips, tz, &acpi_thermal_zone_ops);
+
+	if (tz->trips.passive.flags.valid)
+		tz->thermal_zone =
+			thermal_zone_device_register("acpitz", trips, tz,
+						     &acpi_thermal_zone_ops,
+						     tz->trips.passive.tc1,
+						     tz->trips.passive.tc2,
+						     tz->trips.passive.tsp*100,
+						     tz->polling_frequency*100);
+	else
+		tz->thermal_zone =
+			thermal_zone_device_register("acpitz", trips, tz,
+						     &acpi_thermal_zone_ops,
+						     0, 0, 0,
+						     tz->polling_frequency);
 	if (IS_ERR(tz->thermal_zone))
 		return -ENODEV;
 
@@ -1447,13 +1133,13 @@
 	if (!tz)
 		goto end;
 
-	if (!tz->polling_frequency) {
+	if (!tz->thermal_zone->polling_delay) {
 		seq_puts(seq, "<polling disabled>\n");
 		goto end;
 	}
 
-	seq_printf(seq, "polling frequency:       %lu seconds\n",
-		   (tz->polling_frequency / 10));
+	seq_printf(seq, "polling frequency:       %d seconds\n",
+		   (tz->thermal_zone->polling_delay / 1000));
 
       end:
 	return 0;
@@ -1683,12 +1369,6 @@
 	if (result)
 		goto unregister_thermal_zone;
 
-	init_timer(&tz->timer);
-
-	acpi_thermal_active_off(tz);
-
-	acpi_thermal_check(tz);
-
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_DEVICE_NOTIFY,
 					     acpi_thermal_notify, tz);
@@ -1717,36 +1397,15 @@
 	acpi_status status = AE_OK;
 	struct acpi_thermal *tz = NULL;
 
-
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
 	tz = acpi_driver_data(device);
 
-	/* avoid timer adding new defer task */
-	tz->zombie = 1;
-	/* wait for running timer (on other CPUs) finish */
-	del_timer_sync(&(tz->timer));
-	/* synchronize deferred task */
-	acpi_os_wait_events_complete(NULL);
-	/* deferred task may reinsert timer */
-	del_timer_sync(&(tz->timer));
-
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_DEVICE_NOTIFY,
 					    acpi_thermal_notify);
 
-	/* Terminate policy */
-	if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
-		tz->trips.passive.flags.enabled = 0;
-		acpi_thermal_passive(tz);
-	}
-	if (tz->trips.active[0].flags.valid
-	    && tz->trips.active[0].flags.enabled) {
-		tz->trips.active[0].flags.enabled = 0;
-		acpi_thermal_active(tz);
-	}
-
 	acpi_thermal_remove_fs(device);
 	acpi_thermal_unregister_thermal_zone(tz);
 	mutex_destroy(&tz->lock);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bb5ed05..100c8ee 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -37,6 +37,8 @@
 #include <linux/thermal.h>
 #include <linux/video_output.h>
 #include <linux/sort.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <asm/uaccess.h>
 
 #include <acpi/acpi_bus.h>
@@ -162,16 +164,26 @@
 	u8 _BCL:1;		/*Query list of brightness control levels supported */
 	u8 _BCM:1;		/*Set the brightness level */
 	u8 _BQC:1;		/* Get current brightness level */
+	u8 _BCQ:1;		/* Some buggy BIOS uses _BCQ instead of _BQC */
 	u8 _DDC:1;		/*Return the EDID for this device */
 	u8 _DCS:1;		/*Return status of output device */
 	u8 _DGS:1;		/*Query graphics state */
 	u8 _DSS:1;		/*Device state set */
 };
 
+struct acpi_video_brightness_flags {
+	u8 _BCL_no_ac_battery_levels:1;	/* no AC/Battery levels in _BCL */
+	u8 _BCL_reversed:1;		/* _BCL package is in a reversed order*/
+	u8 _BCL_use_index:1;		/* levels in _BCL are index values */
+	u8 _BCM_use_index:1;		/* input of _BCM is an index value */
+	u8 _BQC_use_index:1;		/* _BQC returns an index value */
+};
+
 struct acpi_video_device_brightness {
 	int curr;
 	int count;
 	int *levels;
+	struct acpi_video_brightness_flags flags;
 };
 
 struct acpi_video_device {
@@ -294,7 +306,7 @@
 			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,
+static int 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 long *state);
@@ -308,7 +320,9 @@
 	int i;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
-	acpi_video_device_lcd_get_level_current(vd, &cur_level);
+
+	if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+		return -EINVAL;
 	for (i = 2; i < vd->brightness->count; i++) {
 		if (vd->brightness->levels[i] == cur_level)
 			/* The first two entries are special - see page 575
@@ -320,12 +334,12 @@
 
 static int acpi_video_set_brightness(struct backlight_device *bd)
 {
-	int request_level = bd->props.brightness+2;
+	int request_level = bd->props.brightness + 2;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
-	acpi_video_device_lcd_set_level(vd,
-					vd->brightness->levels[request_level]);
-	return 0;
+
+	return acpi_video_device_lcd_set_level(vd,
+				vd->brightness->levels[request_level]);
 }
 
 static struct backlight_ops acpi_backlight_ops = {
@@ -358,32 +372,37 @@
 
 
 /* thermal cooling device callbacks */
-static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
+			       long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
 
-	return sprintf(buf, "%d\n", video->brightness->count - 3);
+	*state = video->brightness->count - 3;
+	return 0;
 }
 
-static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
+			       long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
 	unsigned long long level;
-	int state;
+	int offset;
 
-	acpi_video_device_lcd_get_level_current(video, &level);
-	for (state = 2; state < video->brightness->count; state++)
-		if (level == video->brightness->levels[state])
-			return sprintf(buf, "%d\n",
-				       video->brightness->count - state - 1);
+	if (acpi_video_device_lcd_get_level_current(video, &level))
+		return -EINVAL;
+	for (offset = 2; offset < video->brightness->count; offset++)
+		if (level == video->brightness->levels[offset]) {
+			*state = video->brightness->count - offset - 1;
+			return 0;
+		}
 
 	return -EINVAL;
 }
 
 static int
-video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
@@ -479,34 +498,68 @@
 static int
 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 {
-	int status = AE_OK;
+	int status;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 	int state;
 
-
 	arg0.integer.value = level;
 
-	if (device->cap._BCM)
-		status = acpi_evaluate_object(device->dev->handle, "_BCM",
-					      &args, NULL);
+	status = acpi_evaluate_object(device->dev->handle, "_BCM",
+				      &args, NULL);
+	if (ACPI_FAILURE(status)) {
+		ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
+		return -EIO;
+	}
+
 	device->brightness->curr = level;
 	for (state = 2; state < device->brightness->count; state++)
-		if (level == device->brightness->levels[state])
-			device->backlight->props.brightness = state - 2;
+		if (level == device->brightness->levels[state]) {
+			if (device->backlight)
+				device->backlight->props.brightness = state - 2;
+			return 0;
+		}
 
-	return status;
+	ACPI_ERROR((AE_INFO, "Current brightness invalid"));
+	return -EINVAL;
 }
 
 static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
 					unsigned long long *level)
 {
-	if (device->cap._BQC)
-		return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
-					     level);
+	acpi_status status = AE_OK;
+
+	if (device->cap._BQC || device->cap._BCQ) {
+		char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
+
+		status = acpi_evaluate_integer(device->dev->handle, buf,
+						NULL, level);
+		if (ACPI_SUCCESS(status)) {
+			if (device->brightness->flags._BQC_use_index) {
+				if (device->brightness->flags._BCL_reversed)
+					*level = device->brightness->count
+								 - 3 - (*level);
+				*level = device->brightness->levels[*level + 2];
+
+			}
+			device->brightness->curr = *level;
+			return 0;
+		} else {
+			/* Fixme:
+			 * should we return an error or ignore this failure?
+			 * dev->brightness->curr is a cached value which stores
+			 * the correct current backlight level in most cases.
+			 * ACPI video backlight still works w/ buggy _BQC.
+			 * http://bugzilla.kernel.org/show_bug.cgi?id=12233
+			 */
+			ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
+			device->cap._BQC = device->cap._BCQ = 0;
+		}
+	}
+
 	*level = device->brightness->curr;
-	return AE_OK;
+	return 0;
 }
 
 static int
@@ -655,9 +708,11 @@
 acpi_video_init_brightness(struct acpi_video_device *device)
 {
 	union acpi_object *obj = NULL;
-	int i, max_level = 0, count = 0;
+	int i, max_level = 0, count = 0, level_ac_battery = 0;
+	unsigned long long level, level_old;
 	union acpi_object *o;
 	struct acpi_video_device_brightness *br = NULL;
+	int result = -EINVAL;
 
 	if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -671,13 +726,16 @@
 	br = kzalloc(sizeof(*br), GFP_KERNEL);
 	if (!br) {
 		printk(KERN_ERR "can't allocate memory\n");
+		result = -ENOMEM;
 		goto out;
 	}
 
-	br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
+	br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
 				GFP_KERNEL);
-	if (!br->levels)
+	if (!br->levels) {
+		result = -ENOMEM;
 		goto out_free;
+	}
 
 	for (i = 0; i < obj->package.count; i++) {
 		o = (union acpi_object *)&obj->package.elements[i];
@@ -692,18 +750,86 @@
 		count++;
 	}
 
-	/* don't sort the first two brightness levels */
-	sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
-		acpi_video_cmp_level, NULL);
+	/*
+	 * some buggy BIOS don't export the levels
+	 * when machine is on AC/Battery in _BCL package.
+	 * In this case, the first two elements in _BCL packages
+	 * are also supported brightness levels that OS should take care of.
+	 */
+	for (i = 2; i < count; i++)
+		if (br->levels[i] == br->levels[0] ||
+		    br->levels[i] == br->levels[1])
+			level_ac_battery++;
 
-	if (count < 2)
-		goto out_free_levels;
+	if (level_ac_battery < 2) {
+		level_ac_battery = 2 - level_ac_battery;
+		br->flags._BCL_no_ac_battery_levels = 1;
+		for (i = (count - 1 + level_ac_battery); i >= 2; i--)
+			br->levels[i] = br->levels[i - level_ac_battery];
+		count += level_ac_battery;
+	} else if (level_ac_battery > 2)
+		ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
+
+	/* Check if the _BCL package is in a reversed order */
+	if (max_level == br->levels[2]) {
+		br->flags._BCL_reversed = 1;
+		sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
+			acpi_video_cmp_level, NULL);
+	} else if (max_level != br->levels[count - 1])
+		ACPI_ERROR((AE_INFO,
+			    "Found unordered _BCL package\n"));
 
 	br->count = count;
 	device->brightness = br;
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+
+	/* Check the input/output of _BQC/_BCL/_BCM */
+	if ((max_level < 100) && (max_level <= (count - 2)))
+		br->flags._BCL_use_index = 1;
+
+	/*
+	 * _BCM is always consistent with _BCL,
+	 * at least for all the laptops we have ever seen.
+	 */
+	br->flags._BCM_use_index = br->flags._BCL_use_index;
+
+	/* _BQC uses INDEX while _BCL uses VALUE in some laptops */
+	br->curr = max_level;
+	result = acpi_video_device_lcd_get_level_current(device, &level_old);
+	if (result)
+		goto out_free_levels;
+
+	result = acpi_video_device_lcd_set_level(device, br->curr);
+	if (result)
+		goto out_free_levels;
+
+	result = acpi_video_device_lcd_get_level_current(device, &level);
+	if (result)
+		goto out_free_levels;
+
+	if ((level != level_old) && !br->flags._BCM_use_index) {
+		/* Note:
+		 * This piece of code does not work correctly if the current
+		 * brightness levels is 0.
+		 * But I guess boxes that boot with such a dark screen are rare
+		 * and no more code is needed to cover this specifial case.
+		 */
+
+		if (level_ac_battery != 2) {
+			/*
+			 * For now, we don't support the _BCL like this:
+			 * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
+			 * because we may mess up the index returned by _BQC.
+			 * Plus: we have not got a box like this.
+			 */
+			ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
+		}
+		br->flags._BQC_use_index = 1;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "found %d brightness levels\n", count - 2));
 	kfree(obj);
-	return max_level;
+	return result;
 
 out_free_levels:
 	kfree(br->levels);
@@ -712,7 +838,7 @@
 out:
 	device->brightness = NULL;
 	kfree(obj);
-	return 0;
+	return result;
 }
 
 /*
@@ -729,7 +855,6 @@
 static void acpi_video_device_find_cap(struct acpi_video_device *device)
 {
 	acpi_handle h_dummy1;
-	u32 max_level = 0;
 
 
 	memset(&device->cap, 0, sizeof(device->cap));
@@ -745,6 +870,12 @@
 	}
 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
 		device->cap._BQC = 1;
+	else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
+				&h_dummy1))) {
+		printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
+		device->cap._BCQ = 1;
+	}
+
 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
 		device->cap._DDC = 1;
 	}
@@ -758,13 +889,14 @@
 		device->cap._DSS = 1;
 	}
 
-	if (acpi_video_backlight_support())
-		max_level = acpi_video_init_brightness(device);
-
-	if (device->cap._BCL && device->cap._BCM && max_level > 0) {
+	if (acpi_video_backlight_support()) {
 		int result;
 		static int count = 0;
 		char *name;
+
+		result = acpi_video_init_brightness(device);
+		if (result)
+			return;
 		name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
 		if (!name)
 			return;
@@ -773,18 +905,6 @@
 		device->backlight = backlight_device_register(name,
 			NULL, device, &acpi_backlight_ops);
 		device->backlight->props.max_brightness = device->brightness->count-3;
-		/*
-		 * If there exists the _BQC object, the _BQC object will be
-		 * called to get the current backlight brightness. Otherwise
-		 * the brightness will be set to the maximum.
-		 */
-		if (device->cap._BQC)
-			device->backlight->props.brightness =
-				acpi_video_get_brightness(device->backlight);
-		else
-			device->backlight->props.brightness =
-				device->backlight->props.max_brightness;
-		backlight_update_status(device->backlight);
 		kfree(name);
 
 		device->cdev = thermal_cooling_device_register("LCD",
@@ -1061,13 +1181,12 @@
 	/* validate through the list of available levels */
 	for (i = 2; i < dev->brightness->count; i++)
 		if (level == dev->brightness->levels[i]) {
-			if (ACPI_SUCCESS
-			    (acpi_video_device_lcd_set_level(dev, level)))
-				dev->brightness->curr = level;
+			if (!acpi_video_device_lcd_set_level(dev, level))
+				return count;
 			break;
 		}
 
-	return count;
+	return -EINVAL;
 }
 
 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@ -1749,15 +1868,29 @@
 	}
 }
 
-static void
+static int
 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
 {
 	unsigned long long level_current, level_next;
+	int result = -EINVAL;
+
 	if (!device->brightness)
-		return;
-	acpi_video_device_lcd_get_level_current(device, &level_current);
+		goto out;
+
+	result = acpi_video_device_lcd_get_level_current(device,
+							 &level_current);
+	if (result)
+		goto out;
+
 	level_next = acpi_video_get_next_level(device, level_current, event);
-	acpi_video_device_lcd_set_level(device, level_next);
+
+	result = acpi_video_device_lcd_set_level(device, level_next);
+
+out:
+	if (result)
+		printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
+
+	return result;
 }
 
 static int
@@ -2124,7 +2257,27 @@
 	return 0;
 }
 
-static int __init acpi_video_init(void)
+static int __init intel_opregion_present(void)
+{
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+	struct pci_dev *dev = NULL;
+	u32 address;
+
+	for_each_pci_dev(dev) {
+		if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+			continue;
+		if (dev->vendor != PCI_VENDOR_ID_INTEL)
+			continue;
+		pci_read_config_dword(dev, 0xfc, &address);
+		if (!address)
+			continue;
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+int acpi_video_register(void)
 {
 	int result = 0;
 
@@ -2141,6 +2294,22 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(acpi_video_register);
+
+/*
+ * This is kind of nasty. Hardware using Intel chipsets may require
+ * the video opregion code to be run first in order to initialise
+ * state before any ACPI video calls are made. To handle this we defer
+ * registration of the video class until the opregion code has run.
+ */
+
+static int __init acpi_video_init(void)
+{
+	if (intel_opregion_present())
+		return 0;
+
+	return acpi_video_register();
+}
 
 static void __exit acpi_video_exit(void)
 {
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 50e3d2d..0973727 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -55,6 +55,9 @@
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
 				  "support\n"));
 		*cap |= ACPI_VIDEO_BACKLIGHT;
+		if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
+			printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
+					"control misses _BQC function\n");
 		/* We have backlight support, no need to scan further */
 		return AE_CTRL_TERMINATE;
 	}
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 2d34806..5aee8c2 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -8,6 +8,8 @@
 #include <acpi/acpi_drivers.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+
+#include "internal.h"
 #include "sleep.h"
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
@@ -136,13 +138,10 @@
 	spin_unlock(&acpi_device_lock);
 }
 
-static int __init acpi_wakeup_device_init(void)
+int __init acpi_wakeup_device_init(void)
 {
 	struct list_head *node, *next;
 
-	if (acpi_disabled)
-		return 0;
-
 	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev = container_of(node,
@@ -163,5 +162,3 @@
 	spin_unlock(&acpi_device_lock);
 	return 0;
 }
-
-late_initcall(acpi_wakeup_device_init);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 6d21b9e..6386869 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1144,8 +1144,6 @@
 	if (!IS_I945G(dev) && !IS_I945GM(dev))
 		pci_enable_msi(dev->pdev);
 
-	intel_opregion_init(dev);
-
 	spin_lock_init(&dev_priv->user_irq_lock);
 	dev_priv->user_irq_refcount = 0;
 
@@ -1164,6 +1162,9 @@
 		}
 	}
 
+	/* Must be done after probing outputs */
+	intel_opregion_init(dev, 0);
+
 	return 0;
 
 out_iomapfree:
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b293ef0..209592f 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -99,7 +99,7 @@
 
 	i915_restore_state(dev);
 
-	intel_opregion_init(dev);
+	intel_opregion_init(dev, 1);
 
 	/* KMS EnterVT equivalent */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d6cc986..b9a92c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -659,12 +659,12 @@
 
 #ifdef CONFIG_ACPI
 /* i915_opregion.c */
-extern int intel_opregion_init(struct drm_device *dev);
+extern int intel_opregion_init(struct drm_device *dev, int resume);
 extern void intel_opregion_free(struct drm_device *dev);
 extern void opregion_asle_intr(struct drm_device *dev);
 extern void opregion_enable_asle(struct drm_device *dev);
 #else
-static inline int intel_opregion_init(struct drm_device *dev) { return 0; }
+static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
 static inline void intel_opregion_free(struct drm_device *dev) { return; }
 static inline void opregion_asle_intr(struct drm_device *dev) { return; }
 static inline void opregion_enable_asle(struct drm_device *dev) { return; }
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index ff01283..6942772 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -26,6 +26,7 @@
  */
 
 #include <linux/acpi.h>
+#include <acpi/video.h>
 
 #include "drmP.h"
 #include "i915_drm.h"
@@ -136,6 +137,12 @@
 
 #define ASLE_CBLV_VALID         (1<<31)
 
+#define ACPI_OTHER_OUTPUT (0<<8)
+#define ACPI_VGA_OUTPUT (1<<8)
+#define ACPI_TV_OUTPUT (2<<8)
+#define ACPI_DIGITAL_OUTPUT (3<<8)
+#define ACPI_LVDS_OUTPUT (4<<8)
+
 static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -282,7 +289,58 @@
 	.notifier_call = intel_opregion_video_event,
 };
 
-int intel_opregion_init(struct drm_device *dev)
+/*
+ * Initialise the DIDL field in opregion. This passes a list of devices to
+ * the firmware. Values are defined by section B.4.2 of the ACPI specification
+ * (version 3)
+ */
+
+static void intel_didl_outputs(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+	struct drm_connector *connector;
+	int i = 0;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		int output_type = ACPI_OTHER_OUTPUT;
+		if (i >= 8) {
+			dev_printk (KERN_ERR, &dev->pdev->dev,
+				    "More than 8 outputs detected\n");
+			return;
+		}
+		switch (connector->connector_type) {
+		case DRM_MODE_CONNECTOR_VGA:
+		case DRM_MODE_CONNECTOR_DVIA:
+			output_type = ACPI_VGA_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_Composite:
+		case DRM_MODE_CONNECTOR_SVIDEO:
+		case DRM_MODE_CONNECTOR_Component:
+		case DRM_MODE_CONNECTOR_9PinDIN:
+			output_type = ACPI_TV_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_DVII:
+		case DRM_MODE_CONNECTOR_DVID:
+		case DRM_MODE_CONNECTOR_DisplayPort:
+		case DRM_MODE_CONNECTOR_HDMIA:
+		case DRM_MODE_CONNECTOR_HDMIB:
+			output_type = ACPI_DIGITAL_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_LVDS:
+			output_type = ACPI_LVDS_OUTPUT;
+			break;
+		}
+		opregion->acpi->didl[i] |= (1<<31) | output_type | i;
+		i++;
+	}
+
+	/* If fewer than 8 outputs, the list must be null terminated */
+	if (i < 8)
+		opregion->acpi->didl[i] = 0;
+}
+
+int intel_opregion_init(struct drm_device *dev, int resume)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_opregion *opregion = &dev_priv->opregion;
@@ -312,6 +370,11 @@
 	if (mboxes & MBOX_ACPI) {
 		DRM_DEBUG("Public ACPI methods supported\n");
 		opregion->acpi = base + OPREGION_ACPI_OFFSET;
+		if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+			intel_didl_outputs(dev);
+			if (!resume)
+				acpi_video_register();
+		}
 	} else {
 		DRM_DEBUG("Public ACPI methods not supported\n");
 		err = -ENOTSUPP;
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index deea8a1..368ca72 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -386,12 +386,12 @@
 {
 	int ret;
 
-	if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
+	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
 		printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
 		pci_no_msi();
 	}
 
-	if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
+	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
 		printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
 		pcie_no_aspm();
 	}
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index a6a42e8..0f6e43b 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1,7 +1,7 @@
 /*
  *  Acer WMI Laptop Extras
  *
- *  Copyright (C) 2007-2008	Carlos Corbacho <carlos@strangeworlds.co.uk>
+ *  Copyright (C) 2007-2009	Carlos Corbacho <carlos@strangeworlds.co.uk>
  *
  *  Based on acer_acpi:
  *    Copyright (C) 2005-2007	E.M. Smith
@@ -225,6 +225,25 @@
 	.wireless = 2,
 };
 
+/* The Aspire One has a dummy ACPI-WMI interface - disable it */
+static struct dmi_system_id __devinitdata acer_blacklist[] = {
+	{
+		.ident = "Acer Aspire One (SSD)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+		},
+	},
+	{
+		.ident = "Acer Aspire One (HDD)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+		},
+	},
+	{}
+};
+
 static struct dmi_system_id acer_quirks[] = {
 	{
 		.callback = dmi_matched,
@@ -1117,11 +1136,17 @@
 	}
 
 	err = acer_rfkill_init(&device->dev);
+	if (err)
+		goto error_rfkill;
 
 	return err;
 
+error_rfkill:
+	if (has_cap(ACER_CAP_BRIGHTNESS))
+		acer_backlight_exit();
 error_brightness:
-	acer_led_exit();
+	if (has_cap(ACER_CAP_MAILLED))
+		acer_led_exit();
 error_mailled:
 	return err;
 }
@@ -1254,6 +1279,12 @@
 
 	printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
 
+	if (dmi_check_system(acer_blacklist)) {
+		printk(ACER_INFO "Blacklisted hardware detected - "
+				"not loading\n");
+		return -ENODEV;
+	}
+
 	find_quirks();
 
 	/*
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index f41135f..50d9019 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,6 +53,7 @@
 
 static int __init hp_wmi_bios_setup(struct platform_device *device);
 static int __exit hp_wmi_bios_remove(struct platform_device *device);
+static int hp_wmi_resume_handler(struct platform_device *device);
 
 struct bios_args {
 	u32 signature;
@@ -101,6 +102,7 @@
 	},
 	.probe = hp_wmi_bios_setup,
 	.remove = hp_wmi_bios_remove,
+	.resume = hp_wmi_resume_handler,
 };
 
 static int hp_wmi_perform_query(int query, int write, int value)
@@ -487,6 +489,29 @@
 	return 0;
 }
 
+static int hp_wmi_resume_handler(struct platform_device *device)
+{
+	struct key_entry *key;
+
+	/*
+	 * Docking state may have changed while suspended, so trigger
+	 * an input event for the current state. As this is a switch,
+	 * the input layer will only actually pass it on if the state
+	 * changed.
+	 */
+	for (key = hp_wmi_keymap; key->type != KE_END; key++) {
+		switch (key->type) {
+		case KE_SW:
+			input_report_switch(hp_wmi_input_dev, key->keycode,
+					    hp_wmi_dock_state());
+			input_sync(hp_wmi_input_dev);
+			break;
+		}
+	}
+
+	return 0;
+}
+
 static int __init hp_wmi_init(void)
 {
 	int err;
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 27b7662..29432a5 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -57,8 +57,8 @@
  * In that case max_cstate would be n-1
  * GTHS returning '0' would mean that no bandwidth control states are supported
  */
-static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
-					unsigned long *max_state)
+static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
+				    unsigned long *max_state)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
@@ -83,22 +83,12 @@
 	return 0;
 }
 
-static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
-				    char *buf)
-{
-	unsigned long value;
-	if (memory_get_int_max_bandwidth(cdev, &value))
-		return -EINVAL;
-
-	return sprintf(buf, "%ld\n", value);
-}
-
 static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
-				    char *buf)
+				    unsigned long *value)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
-	unsigned long long value;
+	unsigned long long result;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 	acpi_status status = AE_OK;
@@ -108,15 +98,16 @@
 	arg.type = ACPI_TYPE_INTEGER;
 	arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
 	status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
-				       &arg_list, &value);
+				       &arg_list, &result);
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
-	return sprintf(buf, "%llu\n", value);
+	*value = result;
+	return 0;
 }
 
 static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
-				    unsigned int state)
+				    unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
@@ -126,7 +117,7 @@
 	unsigned long long temp;
 	unsigned long max_state;
 
-	if (memory_get_int_max_bandwidth(cdev, &max_state))
+	if (memory_get_max_bandwidth(cdev, &max_state))
 		return -EFAULT;
 
 	if (state > max_state)
@@ -142,7 +133,7 @@
 				  &temp);
 
 	printk(KERN_INFO
-	       "Bandwidth value was %d: status is %d\n", state, status);
+	       "Bandwidth value was %ld: status is %d\n", state, status);
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index ac01e06..da73591 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -93,6 +93,8 @@
 	POWER_SUPPLY_ATTR(voltage_avg),
 	POWER_SUPPLY_ATTR(current_now),
 	POWER_SUPPLY_ATTR(current_avg),
+	POWER_SUPPLY_ATTR(power_now),
+	POWER_SUPPLY_ATTR(power_avg),
 	POWER_SUPPLY_ATTR(charge_full_design),
 	POWER_SUPPLY_ATTR(charge_empty_design),
 	POWER_SUPPLY_ATTR(charge_full),
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 8171ca1..d0b093b 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -30,6 +30,7 @@
 #include <linux/idr.h>
 #include <linux/thermal.h>
 #include <linux/spinlock.h>
+#include <linux/reboot.h>
 
 MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Generic thermal management sysfs support");
@@ -104,22 +105,36 @@
 temp_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	long temperature;
+	int ret;
 
 	if (!tz->ops->get_temp)
 		return -EPERM;
 
-	return tz->ops->get_temp(tz, buf);
+	ret = tz->ops->get_temp(tz, &temperature);
+
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
 }
 
 static ssize_t
 mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	enum thermal_device_mode mode;
+	int result;
 
 	if (!tz->ops->get_mode)
 		return -EPERM;
 
-	return tz->ops->get_mode(tz, buf);
+	result = tz->ops->get_mode(tz, &mode);
+	if (result)
+		return result;
+
+	return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
+		       : "disabled");
 }
 
 static ssize_t
@@ -132,7 +147,13 @@
 	if (!tz->ops->set_mode)
 		return -EPERM;
 
-	result = tz->ops->set_mode(tz, buf);
+	if (!strncmp(buf, "enabled", sizeof("enabled")))
+		result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
+	else if (!strncmp(buf, "disabled", sizeof("disabled")))
+		result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
+	else
+		result = -EINVAL;
+
 	if (result)
 		return result;
 
@@ -144,7 +165,8 @@
 		     char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
-	int trip;
+	enum thermal_trip_type type;
+	int trip, result;
 
 	if (!tz->ops->get_trip_type)
 		return -EPERM;
@@ -152,7 +174,22 @@
 	if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
 		return -EINVAL;
 
-	return tz->ops->get_trip_type(tz, trip, buf);
+	result = tz->ops->get_trip_type(tz, trip, &type);
+	if (result)
+		return result;
+
+	switch (type) {
+	case THERMAL_TRIP_CRITICAL:
+		return sprintf(buf, "critical");
+	case THERMAL_TRIP_HOT:
+		return sprintf(buf, "hot");
+	case THERMAL_TRIP_PASSIVE:
+		return sprintf(buf, "passive");
+	case THERMAL_TRIP_ACTIVE:
+		return sprintf(buf, "active");
+	default:
+		return sprintf(buf, "unknown");
+	}
 }
 
 static ssize_t
@@ -160,7 +197,8 @@
 		     char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
-	int trip;
+	int trip, ret;
+	long temperature;
 
 	if (!tz->ops->get_trip_temp)
 		return -EPERM;
@@ -168,12 +206,77 @@
 	if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
 		return -EINVAL;
 
-	return tz->ops->get_trip_temp(tz, trip, buf);
+	ret = tz->ops->get_trip_temp(tz, trip, &temperature);
+
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
+}
+
+static ssize_t
+passive_store(struct device *dev, struct device_attribute *attr,
+		    const char *buf, size_t count)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	struct thermal_cooling_device *cdev = NULL;
+	int state;
+
+	if (!sscanf(buf, "%d\n", &state))
+		return -EINVAL;
+
+	if (state && !tz->forced_passive) {
+		mutex_lock(&thermal_list_lock);
+		list_for_each_entry(cdev, &thermal_cdev_list, node) {
+			if (!strncmp("Processor", cdev->type,
+				     sizeof("Processor")))
+				thermal_zone_bind_cooling_device(tz,
+								 THERMAL_TRIPS_NONE,
+								 cdev);
+		}
+		mutex_unlock(&thermal_list_lock);
+	} else if (!state && tz->forced_passive) {
+		mutex_lock(&thermal_list_lock);
+		list_for_each_entry(cdev, &thermal_cdev_list, node) {
+			if (!strncmp("Processor", cdev->type,
+				     sizeof("Processor")))
+				thermal_zone_unbind_cooling_device(tz,
+								   THERMAL_TRIPS_NONE,
+								   cdev);
+		}
+		mutex_unlock(&thermal_list_lock);
+	}
+
+	tz->tc1 = 1;
+	tz->tc2 = 1;
+
+	if (!tz->passive_delay)
+		tz->passive_delay = 1000;
+
+	if (!tz->polling_delay)
+		tz->polling_delay = 10000;
+
+	tz->forced_passive = state;
+
+	thermal_zone_device_update(tz);
+
+	return count;
+}
+
+static ssize_t
+passive_show(struct device *dev, struct device_attribute *attr,
+		   char *buf)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+
+	return sprintf(buf, "%d\n", tz->forced_passive);
 }
 
 static DEVICE_ATTR(type, 0444, type_show, NULL);
 static DEVICE_ATTR(temp, 0444, temp_show, NULL);
 static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
+static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \
+		   passive_store);
 
 static struct device_attribute trip_point_attrs[] = {
 	__ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
@@ -236,8 +339,13 @@
 				      struct device_attribute *attr, char *buf)
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
+	unsigned long state;
+	int ret;
 
-	return cdev->ops->get_max_state(cdev, buf);
+	ret = cdev->ops->get_max_state(cdev, &state);
+	if (ret)
+		return ret;
+	return sprintf(buf, "%ld\n", state);
 }
 
 static ssize_t
@@ -245,8 +353,13 @@
 				      struct device_attribute *attr, char *buf)
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
+	unsigned long state;
+	int ret;
 
-	return cdev->ops->get_cur_state(cdev, buf);
+	ret = cdev->ops->get_cur_state(cdev, &state);
+	if (ret)
+		return ret;
+	return sprintf(buf, "%ld\n", state);
 }
 
 static ssize_t
@@ -255,10 +368,10 @@
 				       const char *buf, size_t count)
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
-	int state;
+	unsigned long state;
 	int result;
 
-	if (!sscanf(buf, "%d\n", &state))
+	if (!sscanf(buf, "%ld\n", &state))
 		return -EINVAL;
 
 	if (state < 0)
@@ -312,13 +425,20 @@
 static ssize_t
 temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
+	long temperature;
+	int ret;
 	struct thermal_hwmon_attr *hwmon_attr
 			= container_of(attr, struct thermal_hwmon_attr, attr);
 	struct thermal_zone_device *tz
 			= container_of(hwmon_attr, struct thermal_zone_device,
 				       temp_input);
 
-	return tz->ops->get_temp(tz, buf);
+	ret = tz->ops->get_temp(tz, &temperature);
+
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
 }
 
 static ssize_t
@@ -330,8 +450,14 @@
 	struct thermal_zone_device *tz
 			= container_of(hwmon_attr, struct thermal_zone_device,
 				       temp_crit);
+	long temperature;
+	int ret;
 
-	return tz->ops->get_trip_temp(tz, 0, buf);
+	ret = tz->ops->get_trip_temp(tz, 0, &temperature);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
 }
 
 
@@ -452,6 +578,97 @@
 }
 #endif
 
+static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
+					    int delay)
+{
+	cancel_delayed_work(&(tz->poll_queue));
+
+	if (!delay)
+		return;
+
+	if (delay > 1000)
+		schedule_delayed_work(&(tz->poll_queue),
+				      round_jiffies(msecs_to_jiffies(delay)));
+	else
+		schedule_delayed_work(&(tz->poll_queue),
+				      msecs_to_jiffies(delay));
+}
+
+static void thermal_zone_device_passive(struct thermal_zone_device *tz,
+					int temp, int trip_temp, int trip)
+{
+	int trend = 0;
+	struct thermal_cooling_device_instance *instance;
+	struct thermal_cooling_device *cdev;
+	long state, max_state;
+
+	/*
+	 * Above Trip?
+	 * -----------
+	 * Calculate the thermal trend (using the passive cooling equation)
+	 * and modify the performance limit for all passive cooling devices
+	 * accordingly.  Note that we assume symmetry.
+	 */
+	if (temp >= trip_temp) {
+		tz->passive = true;
+
+		trend = (tz->tc1 * (temp - tz->last_temperature)) +
+			(tz->tc2 * (temp - trip_temp));
+
+		/* Heating up? */
+		if (trend > 0) {
+			list_for_each_entry(instance, &tz->cooling_devices,
+					    node) {
+				if (instance->trip != trip)
+					continue;
+				cdev = instance->cdev;
+				cdev->ops->get_cur_state(cdev, &state);
+				cdev->ops->get_max_state(cdev, &max_state);
+				if (state++ < max_state)
+					cdev->ops->set_cur_state(cdev, state);
+			}
+		} else if (trend < 0) { /* Cooling off? */
+			list_for_each_entry(instance, &tz->cooling_devices,
+					    node) {
+				if (instance->trip != trip)
+					continue;
+				cdev = instance->cdev;
+				cdev->ops->get_cur_state(cdev, &state);
+				cdev->ops->get_max_state(cdev, &max_state);
+				if (state > 0)
+					cdev->ops->set_cur_state(cdev, --state);
+			}
+		}
+		return;
+	}
+
+	/*
+	 * Below Trip?
+	 * -----------
+	 * Implement passive cooling hysteresis to slowly increase performance
+	 * and avoid thrashing around the passive trip point.  Note that we
+	 * assume symmetry.
+	 */
+	list_for_each_entry(instance, &tz->cooling_devices, node) {
+		if (instance->trip != trip)
+			continue;
+		cdev = instance->cdev;
+		cdev->ops->get_cur_state(cdev, &state);
+		cdev->ops->get_max_state(cdev, &max_state);
+		if (state > 0)
+			cdev->ops->set_cur_state(cdev, --state);
+		if (state == 0)
+			tz->passive = false;
+	}
+}
+
+static void thermal_zone_device_check(struct work_struct *work)
+{
+	struct thermal_zone_device *tz = container_of(work, struct
+						      thermal_zone_device,
+						      poll_queue.work);
+	thermal_zone_device_update(tz);
+}
 
 /**
  * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
@@ -722,25 +939,113 @@
 EXPORT_SYMBOL(thermal_cooling_device_unregister);
 
 /**
+ * thermal_zone_device_update - force an update of a thermal zone's state
+ * @ttz:	the thermal zone to update
+ */
+
+void thermal_zone_device_update(struct thermal_zone_device *tz)
+{
+	int count, ret = 0;
+	long temp, trip_temp;
+	enum thermal_trip_type trip_type;
+	struct thermal_cooling_device_instance *instance;
+	struct thermal_cooling_device *cdev;
+
+	mutex_lock(&tz->lock);
+
+	tz->ops->get_temp(tz, &temp);
+
+	for (count = 0; count < tz->trips; count++) {
+		tz->ops->get_trip_type(tz, count, &trip_type);
+		tz->ops->get_trip_temp(tz, count, &trip_temp);
+
+		switch (trip_type) {
+		case THERMAL_TRIP_CRITICAL:
+			if (temp > trip_temp) {
+				if (tz->ops->notify)
+					ret = tz->ops->notify(tz, count,
+							      trip_type);
+				if (!ret) {
+					printk(KERN_EMERG
+					       "Critical temperature reached (%ld C), shutting down.\n",
+					       temp/1000);
+					orderly_poweroff(true);
+				}
+			}
+			break;
+		case THERMAL_TRIP_HOT:
+			if (temp > trip_temp)
+				if (tz->ops->notify)
+					tz->ops->notify(tz, count, trip_type);
+			break;
+		case THERMAL_TRIP_ACTIVE:
+			list_for_each_entry(instance, &tz->cooling_devices,
+					    node) {
+				if (instance->trip != count)
+					continue;
+
+				cdev = instance->cdev;
+
+				if (temp > trip_temp)
+					cdev->ops->set_cur_state(cdev, 1);
+				else
+					cdev->ops->set_cur_state(cdev, 0);
+			}
+			break;
+		case THERMAL_TRIP_PASSIVE:
+			if (temp > trip_temp || tz->passive)
+				thermal_zone_device_passive(tz, temp,
+							    trip_temp, count);
+			break;
+		}
+	}
+
+	if (tz->forced_passive)
+		thermal_zone_device_passive(tz, temp, tz->forced_passive,
+					    THERMAL_TRIPS_NONE);
+
+	tz->last_temperature = temp;
+	if (tz->passive)
+		thermal_zone_device_set_polling(tz, tz->passive_delay);
+	else if (tz->polling_delay)
+		thermal_zone_device_set_polling(tz, tz->polling_delay);
+	mutex_unlock(&tz->lock);
+}
+EXPORT_SYMBOL(thermal_zone_device_update);
+
+/**
  * thermal_zone_device_register - register a new thermal zone device
  * @type:	the thermal zone device type
  * @trips:	the number of trip points the thermal zone support
  * @devdata:	private device data
  * @ops:	standard thermal zone device callbacks
+ * @tc1:	thermal coefficient 1 for passive calculations
+ * @tc2:	thermal coefficient 2 for passive calculations
+ * @passive_delay: number of milliseconds to wait between polls when
+ *		   performing passive cooling
+ * @polling_delay: number of milliseconds to wait between polls when checking
+ *		   whether trip points have been crossed (0 for interrupt
+ *		   driven systems)
  *
  * thermal_zone_device_unregister() must be called when the device is no
- * longer needed.
+ * longer needed. The passive cooling formula uses tc1 and tc2 as described in
+ * section 11.1.5.1 of the ACPI specification 3.0.
  */
 struct thermal_zone_device *thermal_zone_device_register(char *type,
 							 int trips,
 							 void *devdata, struct
 							 thermal_zone_device_ops
-							 *ops)
+							 *ops, int tc1, int
+							 tc2,
+							 int passive_delay,
+							 int polling_delay)
 {
 	struct thermal_zone_device *tz;
 	struct thermal_cooling_device *pos;
+	enum thermal_trip_type trip_type;
 	int result;
 	int count;
+	int passive = 0;
 
 	if (strlen(type) >= THERMAL_NAME_LENGTH)
 		return ERR_PTR(-EINVAL);
@@ -769,6 +1074,11 @@
 	tz->device.class = &thermal_class;
 	tz->devdata = devdata;
 	tz->trips = trips;
+	tz->tc1 = tc1;
+	tz->tc2 = tc2;
+	tz->passive_delay = passive_delay;
+	tz->polling_delay = polling_delay;
+
 	dev_set_name(&tz->device, "thermal_zone%d", tz->id);
 	result = device_register(&tz->device);
 	if (result) {
@@ -798,8 +1108,18 @@
 		TRIP_POINT_ATTR_ADD(&tz->device, count, result);
 		if (result)
 			goto unregister;
+		tz->ops->get_trip_type(tz, count, &trip_type);
+		if (trip_type == THERMAL_TRIP_PASSIVE)
+			passive = 1;
 	}
 
+	if (!passive)
+		result = device_create_file(&tz->device,
+					    &dev_attr_passive);
+
+	if (result)
+		goto unregister;
+
 	result = thermal_add_hwmon_sysfs(tz);
 	if (result)
 		goto unregister;
@@ -814,6 +1134,10 @@
 		}
 	mutex_unlock(&thermal_list_lock);
 
+	INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
+
+	thermal_zone_device_update(tz);
+
 	if (!result)
 		return tz;
 
@@ -853,6 +1177,8 @@
 		    tz->ops->unbind(tz, cdev);
 	mutex_unlock(&thermal_list_lock);
 
+	thermal_zone_device_set_polling(tz, 0);
+
 	if (tz->type[0])
 		device_remove_file(&tz->device, &dev_attr_type);
 	device_remove_file(&tz->device, &dev_attr_temp);
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index eda0454..473d584 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -103,8 +103,9 @@
 #define AE_BAD_OCTAL_CONSTANT           (acpi_status) (0x0006 | AE_CODE_PROGRAMMER)
 #define AE_BAD_DECIMAL_CONSTANT         (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
 #define AE_MISSING_ARGUMENTS            (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
+#define AE_BAD_ADDRESS                  (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
 
-#define AE_CODE_PGM_MAX                 0x0008
+#define AE_CODE_PGM_MAX                 0x0009
 
 /*
  * Acpi table exceptions
@@ -224,7 +225,8 @@
 	"AE_BAD_HEX_CONSTANT",
 	"AE_BAD_OCTAL_CONSTANT",
 	"AE_BAD_DECIMAL_CONSTANT",
-	"AE_MISSING_ARGUMENTS"
+	"AE_MISSING_ARGUMENTS",
+	"AE_BAD_ADDRESS"
 };
 
 char const *acpi_gbl_exception_names_tbl[] = {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index e9f6574..08ec60c 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -88,44 +88,28 @@
 
 typedef int (*acpi_op_add) (struct acpi_device * device);
 typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
-typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
 typedef int (*acpi_op_start) (struct acpi_device * device);
 typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
 typedef int (*acpi_op_suspend) (struct acpi_device * device,
 				pm_message_t state);
 typedef int (*acpi_op_resume) (struct acpi_device * device);
-typedef int (*acpi_op_scan) (struct acpi_device * device);
 typedef int (*acpi_op_bind) (struct acpi_device * device);
 typedef int (*acpi_op_unbind) (struct acpi_device * device);
-typedef int (*acpi_op_shutdown) (struct acpi_device * device);
 
 struct acpi_bus_ops {
 	u32 acpi_op_add:1;
-	u32 acpi_op_remove:1;
-	u32 acpi_op_lock:1;
 	u32 acpi_op_start:1;
-	u32 acpi_op_stop:1;
-	u32 acpi_op_suspend:1;
-	u32 acpi_op_resume:1;
-	u32 acpi_op_scan:1;
-	u32 acpi_op_bind:1;
-	u32 acpi_op_unbind:1;
-	u32 acpi_op_shutdown:1;
-	u32 reserved:21;
 };
 
 struct acpi_device_ops {
 	acpi_op_add add;
 	acpi_op_remove remove;
-	acpi_op_lock lock;
 	acpi_op_start start;
 	acpi_op_stop stop;
 	acpi_op_suspend suspend;
 	acpi_op_resume resume;
-	acpi_op_scan scan;
 	acpi_op_bind bind;
 	acpi_op_unbind unbind;
-	acpi_op_shutdown shutdown;
 };
 
 struct acpi_driver {
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 5fc1bb0..241d227 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -99,24 +99,6 @@
 				   int bus);
 
 /* --------------------------------------------------------------------------
-                                  Power Resource
-   -------------------------------------------------------------------------- */
-
-int acpi_device_sleep_wake(struct acpi_device *dev,
-                           int enable, int sleep_state, int dev_state);
-int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
-int acpi_disable_wakeup_device_power(struct acpi_device *dev);
-int acpi_power_get_inferred_state(struct acpi_device *device);
-int acpi_power_transition(struct acpi_device *device, int state);
-extern int acpi_power_nocheck;
-
-/* --------------------------------------------------------------------------
-                                  Embedded Controller
-   -------------------------------------------------------------------------- */
-int acpi_ec_ecdt_probe(void);
-int acpi_boot_ec_enable(void);
-
-/* --------------------------------------------------------------------------
                                     Processor
    -------------------------------------------------------------------------- */
 
@@ -165,9 +147,4 @@
 }
 #endif
 
-/*--------------------------------------------------------------------------
-                                  Suspend/Resume
-  -------------------------------------------------------------------------- */
-extern int acpi_sleep_init(void);
-
 #endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index a62720a..178adfb 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -241,10 +241,6 @@
 acpi_status acpi_os_validate_interface(char *interface);
 acpi_status acpi_osi_invalidate(char* interface);
 
-acpi_status
-acpi_os_validate_address(u8 space_id, acpi_physical_address address,
-			 acpi_size length, char *name);
-
 u64 acpi_os_get_timer(void);
 
 acpi_status acpi_os_signal(u32 function, void *info);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index c8e8cf4..16826f1 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,7 +47,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20081204
+#define ACPI_CA_VERSION                 0x20090320
 
 #include "actypes.h"
 #include "actbl.h"
@@ -345,17 +345,15 @@
  */
 acpi_status acpi_reset(void);
 
-acpi_status acpi_get_register(u32 register_id, u32 * return_value);
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value);
 
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
+acpi_status acpi_write_bit_register(u32 register_id, u32 value);
 
-acpi_status acpi_set_register(u32 register_id, u32 value);
+acpi_status acpi_set_firmware_waking_vector(u32 physical_address);
 
-acpi_status
-acpi_set_firmware_waking_vector(u32 physical_address);
-
-acpi_status
-acpi_set_firmware_waking_vector64(u64 physical_address);
+#if ACPI_MACHINE_WIDTH == 64
+acpi_status acpi_set_firmware_waking_vector64(u64 physical_address);
+#endif
 
 acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg);
 
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index bf8d4cf..222733d 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -214,11 +214,11 @@
 	u16 flush_size;		/* Processor's memory cache line width, in bytes */
 	u16 flush_stride;	/* Number of flush strides that need to be read */
 	u8 duty_offset;		/* Processor duty cycle index in processor's P_CNT reg */
-	u8 duty_width;		/* Processor duty cycle value bit width in P_CNT register. */
+	u8 duty_width;		/* Processor duty cycle value bit width in P_CNT register */
 	u8 day_alarm;		/* Index to day-of-month alarm in RTC CMOS RAM */
 	u8 month_alarm;		/* Index to month-of-year alarm in RTC CMOS RAM */
 	u8 century;		/* Index to century in RTC CMOS RAM */
-	u16 boot_flags;		/* IA-PC Boot Architecture Flags. See Table 5-10 for description */
+	u16 boot_flags;		/* IA-PC Boot Architecture Flags (see below for individual flags) */
 	u8 reserved;		/* Reserved, must be zero */
 	u32 flags;		/* Miscellaneous flag bits (see below for individual flags) */
 	struct acpi_generic_address reset_register;	/* 64-bit address of the Reset register */
@@ -236,32 +236,41 @@
 	struct acpi_generic_address xgpe1_block;	/* 64-bit Extended General Purpose Event 1 Reg Blk address */
 };
 
+/* FADT Boot Architecture Flags (boot_flags) */
+
+#define ACPI_FADT_LEGACY_DEVICES    (1)  	/* 00: [V2] System has LPC or ISA bus devices */
+#define ACPI_FADT_8042              (1<<1)	/* 01: [V3] System has an 8042 controller on port 60/64 */
+#define ACPI_FADT_NO_VGA            (1<<2)	/* 02: [V4] It is not safe to probe for VGA hardware */
+#define ACPI_FADT_NO_MSI            (1<<3)	/* 03: [V4] Message Signaled Interrupts (MSI) must not be enabled */
+#define ACPI_FADT_NO_ASPM           (1<<4)	/* 04: [V4] PCIe ASPM control must not be enabled */
+
+#define FADT2_REVISION_ID               3
+
 /* FADT flags */
 
-#define ACPI_FADT_WBINVD            (1)	/* 00: The wbinvd instruction works properly */
-#define ACPI_FADT_WBINVD_FLUSH      (1<<1)	/* 01: The wbinvd flushes but does not invalidate */
-#define ACPI_FADT_C1_SUPPORTED      (1<<2)	/* 02: All processors support C1 state */
-#define ACPI_FADT_C2_MP_SUPPORTED   (1<<3)	/* 03: C2 state works on MP system */
-#define ACPI_FADT_POWER_BUTTON      (1<<4)	/* 04: Power button is handled as a generic feature */
-#define ACPI_FADT_SLEEP_BUTTON      (1<<5)	/* 05: Sleep button is handled as a generic feature, or  not present */
-#define ACPI_FADT_FIXED_RTC         (1<<6)	/* 06: RTC wakeup stat not in fixed register space */
-#define ACPI_FADT_S4_RTC_WAKE       (1<<7)	/* 07: RTC wakeup possible from S4 */
-#define ACPI_FADT_32BIT_TIMER       (1<<8)	/* 08: tmr_val is 32 bits 0=24-bits */
-#define ACPI_FADT_DOCKING_SUPPORTED (1<<9)	/* 09: Docking supported */
-#define ACPI_FADT_RESET_REGISTER    (1<<10)	/* 10: System reset via the FADT RESET_REG supported */
-#define ACPI_FADT_SEALED_CASE       (1<<11)	/* 11: No internal expansion capabilities and case is sealed */
-#define ACPI_FADT_HEADLESS          (1<<12)	/* 12: No local video capabilities or local input devices */
-#define ACPI_FADT_SLEEP_TYPE        (1<<13)	/* 13: Must execute native instruction after writing  SLP_TYPx register */
-#define ACPI_FADT_PCI_EXPRESS_WAKE  (1<<14)	/* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
-#define ACPI_FADT_PLATFORM_CLOCK    (1<<15)	/* 15: OSPM should use platform-provided timer (ACPI 3.0) */
-#define ACPI_FADT_S4_RTC_VALID      (1<<16)	/* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
-#define ACPI_FADT_REMOTE_POWER_ON   (1<<17)	/* 17: System is compatible with remote power on (ACPI 3.0) */
-#define ACPI_FADT_APIC_CLUSTER      (1<<18)	/* 18: All local APICs must use cluster model (ACPI 3.0) */
-#define ACPI_FADT_APIC_PHYSICAL     (1<<19)	/* 19: All local x_aPICs must use physical dest mode (ACPI 3.0) */
+#define ACPI_FADT_WBINVD            (1)	/* 00: [V1] The wbinvd instruction works properly */
+#define ACPI_FADT_WBINVD_FLUSH      (1<<1)	/* 01: [V1] wbinvd flushes but does not invalidate caches */
+#define ACPI_FADT_C1_SUPPORTED      (1<<2)	/* 02: [V1] All processors support C1 state */
+#define ACPI_FADT_C2_MP_SUPPORTED   (1<<3)	/* 03: [V1] C2 state works on MP system */
+#define ACPI_FADT_POWER_BUTTON      (1<<4)	/* 04: [V1] Power button is handled as a control method device */
+#define ACPI_FADT_SLEEP_BUTTON      (1<<5)	/* 05: [V1] Sleep button is handled as a control method device */
+#define ACPI_FADT_FIXED_RTC         (1<<6)	/* 06: [V1] RTC wakeup status not in fixed register space */
+#define ACPI_FADT_S4_RTC_WAKE       (1<<7)	/* 07: [V1] RTC alarm can wake system from S4 */
+#define ACPI_FADT_32BIT_TIMER       (1<<8)	/* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
+#define ACPI_FADT_DOCKING_SUPPORTED (1<<9)	/* 09: [V1] Docking supported */
+#define ACPI_FADT_RESET_REGISTER    (1<<10)	/* 10: [V2] System reset via the FADT RESET_REG supported */
+#define ACPI_FADT_SEALED_CASE       (1<<11)	/* 11: [V3] No internal expansion capabilities and case is sealed */
+#define ACPI_FADT_HEADLESS          (1<<12)	/* 12: [V3] No local video capabilities or local input devices */
+#define ACPI_FADT_SLEEP_TYPE        (1<<13)	/* 13: [V3] Must execute native instruction after writing  SLP_TYPx register */
+#define ACPI_FADT_PCI_EXPRESS_WAKE  (1<<14)	/* 14: [V4] System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
+#define ACPI_FADT_PLATFORM_CLOCK    (1<<15)	/* 15: [V4] OSPM should use platform-provided timer (ACPI 3.0) */
+#define ACPI_FADT_S4_RTC_VALID      (1<<16)	/* 16: [V4] Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
+#define ACPI_FADT_REMOTE_POWER_ON   (1<<17)	/* 17: [V4] System is compatible with remote power on (ACPI 3.0) */
+#define ACPI_FADT_APIC_CLUSTER      (1<<18)	/* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */
+#define ACPI_FADT_APIC_PHYSICAL     (1<<19)	/* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */
 
-/*
- * FADT Prefered Power Management Profiles
- */
+/* FADT Prefered Power Management Profiles */
+
 enum acpi_prefered_pm_profiles {
 	PM_UNSPECIFIED = 0,
 	PM_DESKTOP = 1,
@@ -272,16 +281,6 @@
 	PM_APPLIANCE_PC = 6
 };
 
-/* FADT Boot Arch Flags */
-
-#define BAF_LEGACY_DEVICES              0x0001
-#define BAF_8042_KEYBOARD_CONTROLLER    0x0002
-#define BAF_MSI_NOT_SUPPORTED           0x0008
-#define BAF_PCIE_ASPM_CONTROL           0x0010
-
-#define FADT2_REVISION_ID               3
-#define FADT2_MINUS_REVISION_ID         2
-
 /* Reset to default packing */
 
 #pragma pack()
@@ -310,8 +309,9 @@
 #define ACPI_TABLE_ORIGIN_UNKNOWN       (0)
 #define ACPI_TABLE_ORIGIN_MAPPED        (1)
 #define ACPI_TABLE_ORIGIN_ALLOCATED     (2)
-#define ACPI_TABLE_ORIGIN_MASK          (3)
-#define ACPI_TABLE_IS_LOADED            (4)
+#define ACPI_TABLE_ORIGIN_OVERRIDE      (4)
+#define ACPI_TABLE_ORIGIN_MASK          (7)
+#define ACPI_TABLE_IS_LOADED            (8)
 
 /*
  * Get the remaining ACPI tables
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index a20aab5..f555d927 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -777,17 +777,25 @@
 #define ACPI_BITREG_SCI_ENABLE                  0x0E
 #define ACPI_BITREG_BUS_MASTER_RLD              0x0F
 #define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x10
-#define ACPI_BITREG_SLEEP_TYPE_A                0x11
-#define ACPI_BITREG_SLEEP_TYPE_B                0x12
-#define ACPI_BITREG_SLEEP_ENABLE                0x13
+#define ACPI_BITREG_SLEEP_TYPE                  0x11
+#define ACPI_BITREG_SLEEP_ENABLE                0x12
 
 /* PM2 Control register */
 
-#define ACPI_BITREG_ARB_DISABLE                 0x14
+#define ACPI_BITREG_ARB_DISABLE                 0x13
 
-#define ACPI_BITREG_MAX                         0x14
+#define ACPI_BITREG_MAX                         0x13
 #define ACPI_NUM_BITREG                         ACPI_BITREG_MAX + 1
 
+/* Status register values. A 1 clears a status bit. 0 = no effect */
+
+#define ACPI_CLEAR_STATUS                       1
+
+/* Enable and Control register values */
+
+#define ACPI_ENABLE_EVENT                       1
+#define ACPI_DISABLE_EVENT                      0
+
 /*
  * External ACPI object definition
  */
diff --git a/include/acpi/video.h b/include/acpi/video.h
new file mode 100644
index 0000000..f0275bb
--- /dev/null
+++ b/include/acpi/video.h
@@ -0,0 +1,11 @@
+#ifndef __ACPI_VIDEO_H
+#define __ACPI_VIDEO_H
+
+#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE)
+extern int acpi_video_register(void);
+#else
+static inline int acpi_video_register(void) { return 0; }
+#endif
+
+#endif
+
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 8ff25e0..594c494 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -73,6 +73,8 @@
 	POWER_SUPPLY_PROP_VOLTAGE_AVG,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_POWER_NOW,
+	POWER_SUPPLY_PROP_POWER_AVG,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 	POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
 	POWER_SUPPLY_PROP_CHARGE_FULL,
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 917707e..1de8b9eb 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -27,27 +27,46 @@
 
 #include <linux/idr.h>
 #include <linux/device.h>
+#include <linux/workqueue.h>
 
 struct thermal_zone_device;
 struct thermal_cooling_device;
 
+enum thermal_device_mode {
+	THERMAL_DEVICE_DISABLED = 0,
+	THERMAL_DEVICE_ENABLED,
+};
+
+enum thermal_trip_type {
+	THERMAL_TRIP_ACTIVE = 0,
+	THERMAL_TRIP_PASSIVE,
+	THERMAL_TRIP_HOT,
+	THERMAL_TRIP_CRITICAL,
+};
+
 struct thermal_zone_device_ops {
 	int (*bind) (struct thermal_zone_device *,
 		     struct thermal_cooling_device *);
 	int (*unbind) (struct thermal_zone_device *,
 		       struct thermal_cooling_device *);
-	int (*get_temp) (struct thermal_zone_device *, char *);
-	int (*get_mode) (struct thermal_zone_device *, char *);
-	int (*set_mode) (struct thermal_zone_device *, const char *);
-	int (*get_trip_type) (struct thermal_zone_device *, int, char *);
-	int (*get_trip_temp) (struct thermal_zone_device *, int, char *);
+	int (*get_temp) (struct thermal_zone_device *, unsigned long *);
+	int (*get_mode) (struct thermal_zone_device *,
+			 enum thermal_device_mode *);
+	int (*set_mode) (struct thermal_zone_device *,
+		enum thermal_device_mode);
+	int (*get_trip_type) (struct thermal_zone_device *, int,
+		enum thermal_trip_type *);
+	int (*get_trip_temp) (struct thermal_zone_device *, int,
+			      unsigned long *);
 	int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
+	int (*notify) (struct thermal_zone_device *, int,
+		       enum thermal_trip_type);
 };
 
 struct thermal_cooling_device_ops {
-	int (*get_max_state) (struct thermal_cooling_device *, char *);
-	int (*get_cur_state) (struct thermal_cooling_device *, char *);
-	int (*set_cur_state) (struct thermal_cooling_device *, unsigned int);
+	int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
+	int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
+	int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
 };
 
 #define THERMAL_TRIPS_NONE -1
@@ -88,11 +107,19 @@
 	struct device device;
 	void *devdata;
 	int trips;
+	int tc1;
+	int tc2;
+	int passive_delay;
+	int polling_delay;
+	int last_temperature;
+	bool passive;
+	unsigned int forced_passive;
 	struct thermal_zone_device_ops *ops;
 	struct list_head cooling_devices;
 	struct idr idr;
 	struct mutex lock;	/* protect cooling devices list */
 	struct list_head node;
+	struct delayed_work poll_queue;
 #if defined(CONFIG_THERMAL_HWMON)
 	struct list_head hwmon_node;
 	struct thermal_hwmon_device *hwmon;
@@ -104,13 +131,16 @@
 struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
 							 struct
 							 thermal_zone_device_ops
-							 *);
+							 *, int tc1, int tc2,
+							 int passive_freq,
+							 int polling_freq);
 void thermal_zone_device_unregister(struct thermal_zone_device *);
 
 int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
 				     struct thermal_cooling_device *);
 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
 				       struct thermal_cooling_device *);
+void thermal_zone_device_update(struct thermal_zone_device *);
 struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
 							       struct
 							       thermal_cooling_device_ops