Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
new file mode 100644
index 0000000..0400a52
--- /dev/null
+++ b/drivers/acpi/Kconfig
@@ -0,0 +1,356 @@
+#
+# ACPI Configuration
+#
+
+menu "ACPI (Advanced Configuration and Power Interface) Support"
+	depends on !X86_VISWS
+	depends on !IA64_HP_SIM
+	depends on IA64 || X86
+
+config ACPI
+	bool "ACPI Support"
+	depends on IA64 || X86
+
+	default y
+	---help---
+	  Advanced Configuration and Power Interface (ACPI) support for 
+	  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.
+
+	  Linux ACPI provides a robust functional replacement for several 
+	  legacy configuration and power management interfaces, including
+	  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.
+
+	  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>
+
+	  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>
+
+	  ACPI is an open industry specification co-developed by Compaq, 
+	  Intel, Microsoft, Phoenix, and Toshiba.  The specification is 
+	  available at:
+	  <http://www.acpi.info>
+
+config ACPI_BOOT
+	bool
+	depends on ACPI || X86_HT
+	default y
+
+if ACPI
+
+config ACPI_INTERPRETER
+	bool
+	depends on !IA64_SGI_SN
+	default y
+
+if ACPI_INTERPRETER
+
+config ACPI_SLEEP
+	bool "Sleep States (EXPERIMENTAL)"
+	depends on X86
+	depends on EXPERIMENTAL && PM
+	default y
+	---help---
+	  This option adds support for ACPI suspend states. 
+
+	  With this option, you will be able to put the system "to sleep". 
+	  Sleep states are low power states for the system and devices. All
+	  of the system operating state is saved to either memory or disk
+	  (depending on the state), to allow the system to resume operation
+	  quickly at your request.
+
+	  Although this option sounds really nifty, barely any of the device
+	  drivers have been converted to the new driver model and hence few
+	  have proper power management support. 
+
+	  This option is not recommended for anyone except those doing driver
+	  power management development.
+
+config ACPI_SLEEP_PROC_FS
+	bool
+	depends on ACPI_SLEEP && PROC_FS
+	default y
+
+config ACPI_AC
+	tristate "AC Adapter"
+	depends on X86
+	default m
+	help
+	  This driver adds support for the AC Adapter object, which indicates
+	  whether a system is on AC, or not.  Typically, only mobile systems 
+	  have this object, since desktops are always on AC.
+
+config ACPI_BATTERY
+	tristate "Battery"
+	depends on X86
+	default m
+	help
+	  This driver adds support for battery information through
+	  /proc/acpi/battery. If you have a mobile system with a battery, 
+	  say Y.
+
+config ACPI_BUTTON
+	tristate "Button"
+	depends on !IA64_SGI_SN
+	default m
+	help
+	  This driver registers for events based on buttons, such as the
+	  power, sleep, and lid switch.  In the future, a daemon will read
+	  /proc/acpi/event and perform user-defined actions such as shutting
+	  down the system.  Until then, you can cat it, and see output when
+	  a button is pressed.
+
+config ACPI_VIDEO
+	tristate "Video"
+	depends on EXPERIMENTAL
+	depends on !IA64_SGI_SN
+	default m
+	help
+	  This driver implement 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.
+
+config ACPI_FAN
+	tristate "Fan"
+	depends on !IA64_SGI_SN
+	default m
+	help
+	  This driver adds support for ACPI fan devices, allowing user-mode 
+	  applications to perform basic fan control (on, off, status).
+
+config ACPI_PROCESSOR
+	tristate "Processor"
+	depends on !IA64_SGI_SN
+	default m
+	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
+	  support it.
+
+config ACPI_HOTPLUG_CPU
+	bool "Processor Hotplug (EXPERIMENTAL)"
+	depends on ACPI_PROCESSOR && HOTPLUG_CPU && EXPERIMENTAL
+	depends on !IA64_SGI_SN
+	select ACPI_CONTAINER
+	default n
+	 ---help---
+	 Select this option if your platform support physical CPU hotplug.
+
+config ACPI_THERMAL
+	tristate "Thermal Zone"
+	depends on ACPI_PROCESSOR
+	default m
+	help
+	  This driver adds support for 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.
+
+config ACPI_NUMA
+	bool "NUMA support"
+	depends on NUMA
+	depends on (IA64 || X86_64)
+	default y if IA64_GENERIC || IA64_SGI_SN2
+
+config ACPI_ASUS
+        tristate "ASUS/Medion Laptop Extras"
+	depends on X86
+	default m
+        ---help---
+          This driver provides support for extra features of ACPI-compatible
+          ASUS laptops. As some of Medion laptops are made by ASUS, it may also
+          support some Medion laptops (such as 9675 for example).  It makes all
+          the extra buttons generate standard ACPI events that go through
+          /proc/acpi/events, and (on some models) adds support for changing the
+          display brightness and output, switching the LCD backlight on and off,
+          and most importantly, allows you to blink those fancy LEDs intended
+          for reporting mail and wireless status.
+
+	  Note: display switching code is currently considered EXPERIMENTAL,
+	  toying with these values may even lock your machine.
+          
+          All settings are changed via /proc/acpi/asus directory entries. Owner
+          and group for these entries can be set with asus_uid and asus_gid
+          parameters.
+          
+          More information and a userspace daemon for handling the extra buttons
+          at <http://sourceforge.net/projects/acpi4asus/>.
+          
+          If you have an ACPI-compatible ASUS laptop, say Y or M here. This
+          driver is still under development, so if your laptop is unsupported or
+          something works not quite as expected, please use the mailing list
+          available on the above page (acpi4asus-user@lists.sourceforge.net)
+          
+config ACPI_IBM
+	tristate "IBM ThinkPad Laptop Extras"
+	depends on X86
+	default m
+	---help---
+	  This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
+	  support for Fn-Fx key combinations, Bluetooth control, video
+	  output switching, ThinkLight control, UltraBay eject and more.
+	  For more information about this driver see <file:Documentation/ibm-acpi.txt>
+	  and <http://ibm-acpi.sf.net/> .
+
+	  If you have an IBM ThinkPad laptop, say Y or M here.
+
+config ACPI_TOSHIBA
+	tristate "Toshiba Laptop Extras"
+	depends on X86
+	default m
+	---help---
+	  This driver adds support for access to certain system settings
+	  on "legacy free" Toshiba laptops.  These laptops can be recognized by
+	  their lack of a BIOS setup menu and APM support.
+
+	  On these machines, all system configuration is handled through the
+	  ACPI.  This driver is required for access to controls not covered
+	  by the general ACPI drivers, such as LCD brightness, video output,
+	  etc.
+
+	  This driver differs from the non-ACPI Toshiba laptop driver (located
+	  under "Processor type and features") in several aspects.
+	  Configuration is accessed by reading and writing text files in the
+	  /proc tree instead of by program interface to /dev.  Furthermore, no
+	  power management functions are exposed, as those are handled by the
+	  general ACPI drivers.
+
+	  More information about this driver is available at
+	  <http://memebeam.org/toys/ToshibaAcpiDriver>.
+
+	  If you have a legacy free Toshiba laptop (such as the Libretto L1
+	  series), say Y.
+
+config ACPI_CUSTOM_DSDT
+	bool "Include Custom DSDT"
+	depends on !STANDALONE
+	default n 
+	help
+	  Thist option is to load a custom ACPI DSDT
+	  If you don't know what that is, say N.
+
+config ACPI_CUSTOM_DSDT_FILE
+	string "Custom DSDT Table file to include"
+	depends on ACPI_CUSTOM_DSDT
+	default ""
+	help
+	  Enter the full path name to the file wich includes the AmlCode declaration.
+
+config ACPI_BLACKLIST_YEAR
+	int "Disable ACPI for systems before Jan 1st this year"
+	depends on ACPI_INTERPRETER
+	default 0
+	help
+	  enter a 4-digit year, eg. 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.
+
+	  Enter 0 to disable this mechanism and allow ACPI to
+	  run by default no matter what the year.  (default)
+
+config ACPI_DEBUG
+	bool "Debug Statements"
+	depends on !IA64_SGI_SN
+	default n
+	help
+	  The ACPI driver can optionally report errors with a great deal
+	  of verbosity. Saying Y enables these statements. This will increase
+	  your kernel size by around 50K.
+
+config ACPI_BUS
+	bool
+	depends on !IA64_SGI_SN
+	default y
+
+config ACPI_EC
+	bool
+	depends on X86
+	default y
+	help
+	  This driver is required on some systems for the proper operation of
+	  the battery and thermal drivers.  If you are compiling for a 
+	  mobile system, say Y.
+
+config ACPI_POWER
+	bool
+	depends on !IA64_SGI_SN
+	default y
+
+config ACPI_PCI
+	bool
+	depends on !IA64_SGI_SN
+	default PCI
+
+config ACPI_SYSTEM
+	bool
+	depends on !IA64_SGI_SN
+	default y
+	help
+	  This driver will enable your system to shut down using ACPI, and
+	  dump your ACPI DSDT table using /proc/acpi/dsdt.
+
+endif	# ACPI_INTERPRETER
+
+config X86_PM_TIMER
+	bool "Power Management Timer Support"
+	depends on X86
+	depends on ACPI_BOOT && EXPERIMENTAL
+	depends on !X86_64
+	default n
+	help
+	  The Power Management Timer is available on all ACPI-capable,
+	  in most cases even if ACPI is unusable or blacklisted.
+
+	  This timing source is not affected by powermanagement features
+	  like aggressive processor idling, throttling, frequency and/or
+	  voltage scaling, unlike the commonly used Time Stamp Counter
+	  (TSC) timing source.
+
+	  So, if you see messages like 'Losing too many ticks!' in the
+	  kernel logs, and/or you are using this on a notebook which
+	  does not yet have an HPET, you should say "Y" here.
+
+config ACPI_CONTAINER
+	tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
+	 ---help---
+	 	This is the ACPI generic container driver which supports
+		ACPI0004, PNP0A05 and PNP0A06 devices
+
+config ACPI_HOTPLUG_MEMORY
+	tristate "Memory Hotplug"
+	depends on ACPI
+	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.  
+
+	  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 platfrom defined granularity (individually 
+	  or as a bank) at runtime, then you need not enable this driver.
+
+	  If one selects "m," this driver can be loaded using the following
+	  command: 
+		$>modprobe acpi_memhotplug 
+endif	# ACPI
+
+endmenu
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
new file mode 100644
index 0000000..65c92e2
--- /dev/null
+++ b/drivers/acpi/Makefile
@@ -0,0 +1,58 @@
+#
+# Makefile for the Linux ACPI interpreter
+# 
+
+export ACPI_CFLAGS
+
+ACPI_CFLAGS	:= -Os
+
+ifdef CONFIG_ACPI_DEBUG
+  ACPI_CFLAGS	+= -DACPI_DEBUG_OUTPUT
+endif
+
+EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
+
+#
+# ACPI Boot-Time Table Parsing
+#
+obj-$(CONFIG_ACPI_BOOT)		+= tables.o
+obj-$(CONFIG_ACPI_INTERPRETER)	+= blacklist.o
+
+#
+# ACPI Core Subsystem (Interpreter)
+#
+obj-$(CONFIG_ACPI_INTERPRETER)	+= osl.o utils.o \
+				   dispatcher/ events/ executer/ hardware/ \
+				   namespace/ parser/ resources/ tables/ \
+				   utilities/
+
+#
+# ACPI Bus and Device Drivers
+#
+processor-objs	+= processor_core.o processor_throttling.o \
+				processor_idle.o processor_thermal.o
+ifdef CONFIG_CPU_FREQ
+processor-objs	+= processor_perflib.o			
+endif
+
+obj-$(CONFIG_ACPI_BUS)		+= sleep/
+obj-$(CONFIG_ACPI_BUS)		+= bus.o
+obj-$(CONFIG_ACPI_AC) 		+= ac.o
+obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
+obj-$(CONFIG_ACPI_BUTTON)	+= button.o
+obj-$(CONFIG_ACPI_EC)		+= ec.o
+obj-$(CONFIG_ACPI_FAN)		+= fan.o
+obj-$(CONFIG_ACPI_VIDEO)	+= video.o
+obj-$(CONFIG_ACPI_PCI)		+= pci_root.o pci_link.o pci_irq.o pci_bind.o
+obj-$(CONFIG_ACPI_POWER)	+= power.o
+obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
+obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
+obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
+obj-$(CONFIG_ACPI_SYSTEM)	+= system.o event.o
+obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
+obj-$(CONFIG_ACPI_NUMA)		+= numa.o
+obj-$(CONFIG_ACPI_ASUS)		+= asus_acpi.o
+obj-$(CONFIG_ACPI_IBM)		+= ibm_acpi.o
+obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
+obj-$(CONFIG_ACPI_BUS)		+= scan.o motherboard.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
new file mode 100644
index 0000000..23ab761
--- /dev/null
+++ b/drivers/acpi/ac.c
@@ -0,0 +1,354 @@
+/*
+ *  acpi_ac.c - ACPI AC Adapter Driver ($Revision: 27 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define ACPI_AC_COMPONENT		0x00020000
+#define ACPI_AC_CLASS			"ac_adapter"
+#define ACPI_AC_HID 			"ACPI0003"
+#define ACPI_AC_DRIVER_NAME		"ACPI AC Adapter Driver"
+#define ACPI_AC_DEVICE_NAME		"AC Adapter"
+#define ACPI_AC_FILE_STATE		"state"
+#define ACPI_AC_NOTIFY_STATUS		0x80
+#define ACPI_AC_STATUS_OFFLINE		0x00
+#define ACPI_AC_STATUS_ONLINE		0x01
+#define ACPI_AC_STATUS_UNKNOWN		0xFF
+
+#define _COMPONENT		ACPI_AC_COMPONENT
+ACPI_MODULE_NAME		("acpi_ac")
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static int acpi_ac_add (struct acpi_device *device);
+static int acpi_ac_remove (struct acpi_device *device, int type);
+static int acpi_ac_open_fs(struct inode *inode, struct file *file);
+
+static struct acpi_driver acpi_ac_driver = {
+	.name =		ACPI_AC_DRIVER_NAME,
+	.class =	ACPI_AC_CLASS,
+	.ids =		ACPI_AC_HID,
+	.ops =		{
+				.add =		acpi_ac_add,
+				.remove =	acpi_ac_remove,
+			},
+};
+
+struct acpi_ac {
+	acpi_handle		handle;
+	unsigned long		state;
+};
+
+static struct file_operations acpi_ac_fops = {
+	.open		= acpi_ac_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+/* --------------------------------------------------------------------------
+                               AC Adapter Management
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_ac_get_state (
+	struct acpi_ac		*ac)
+{
+	acpi_status		status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("acpi_ac_get_state");
+
+	if (!ac)
+		return_VALUE(-EINVAL);
+
+	status = acpi_evaluate_integer(ac->handle, "_PSR", NULL, &ac->state);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error reading AC Adapter state\n"));
+		ac->state = ACPI_AC_STATUS_UNKNOWN;
+		return_VALUE(-ENODEV);
+	}
+	
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_ac_dir;
+
+static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_ac		*ac = (struct acpi_ac *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_ac_seq_show");
+
+	if (!ac)
+		return_VALUE(0);
+
+	if (acpi_ac_get_state(ac)) {
+		seq_puts(seq, "ERROR: Unable to read AC Adapter state\n");
+		return_VALUE(0);
+	}
+
+	seq_puts(seq, "state:                   ");
+	switch (ac->state) {
+	case ACPI_AC_STATUS_OFFLINE:
+		seq_puts(seq, "off-line\n");
+		break;
+	case ACPI_AC_STATUS_ONLINE:
+		seq_puts(seq, "on-line\n");
+		break;
+	default:
+		seq_puts(seq, "unknown\n");
+		break;
+	}
+
+	return_VALUE(0);
+}
+	
+static int acpi_ac_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_ac_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_ac_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ac_add_fs");
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_ac_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
+	}
+
+	/* 'state' [R] */
+	entry = create_proc_entry(ACPI_AC_FILE_STATE,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_AC_FILE_STATE));
+	else {
+		entry->proc_fops = &acpi_ac_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_ac_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_ac_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_AC_FILE_STATE,
+				  acpi_device_dir(device));
+
+		remove_proc_entry(acpi_device_bid(device), acpi_ac_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                                   Driver Model
+   -------------------------------------------------------------------------- */
+
+static void
+acpi_ac_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_ac		*ac = (struct acpi_ac *) data;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ac_notify");
+
+	if (!ac)
+		return_VOID;
+
+	if (acpi_bus_get_device(ac->handle, &device))
+		return_VOID;
+
+	switch (event) {
+	case ACPI_AC_NOTIFY_STATUS:
+		acpi_ac_get_state(ac);
+		acpi_bus_generate_event(device, event, (u32) ac->state);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+
+static int
+acpi_ac_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_ac		*ac = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ac_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL);
+	if (!ac)
+		return_VALUE(-ENOMEM);
+	memset(ac, 0, sizeof(struct acpi_ac));
+
+	ac->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_AC_CLASS);
+	acpi_driver_data(device) = ac;
+
+	result = acpi_ac_get_state(ac);
+	if (result)
+		goto end;
+
+	result = acpi_ac_add_fs(device);
+	if (result)
+		goto end;
+
+	status = acpi_install_notify_handler(ac->handle,
+		ACPI_DEVICE_NOTIFY, acpi_ac_notify, ac);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing notify handler\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 
+		acpi_device_name(device), acpi_device_bid(device), 
+		ac->state?"on-line":"off-line");
+
+end:
+	if (result) {
+		acpi_ac_remove_fs(device);
+		kfree(ac);
+	}
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_ac_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_ac		*ac = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ac_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	ac = (struct acpi_ac *) acpi_driver_data(device);
+
+	status = acpi_remove_notify_handler(ac->handle,
+		ACPI_DEVICE_NOTIFY, acpi_ac_notify);
+	if (ACPI_FAILURE(status))
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error removing notify handler\n"));
+
+	acpi_ac_remove_fs(device);
+
+	kfree(ac);
+
+	return_VALUE(0);
+}
+
+
+static int __init
+acpi_ac_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ac_init");
+
+	acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
+	if (!acpi_ac_dir)
+		return_VALUE(-ENODEV);
+	acpi_ac_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_ac_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+
+static void __exit
+acpi_ac_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_ac_exit");
+
+	acpi_bus_unregister_driver(&acpi_ac_driver);
+
+	remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+
+module_init(acpi_ac_init);
+module_exit(acpi_ac_exit);
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
new file mode 100644
index 0000000..77285ff
--- /dev/null
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2004 Intel Corporation <naveen.b.s@intel.com>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * ACPI based HotPlug driver that supports Memory Hotplug
+ * This driver fields notifications from firmare for memory add
+ * and remove operations and alerts the VM of the affected memory
+ * ranges.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/memory_hotplug.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define ACPI_MEMORY_DEVICE_COMPONENT		0x08000000UL
+#define ACPI_MEMORY_DEVICE_CLASS		"memory"
+#define ACPI_MEMORY_DEVICE_HID			"PNP0C80"
+#define ACPI_MEMORY_DEVICE_DRIVER_NAME		"Hotplug Mem Driver"
+#define ACPI_MEMORY_DEVICE_NAME			"Hotplug Mem Device"
+
+#define _COMPONENT		ACPI_MEMORY_DEVICE_COMPONENT
+
+ACPI_MODULE_NAME		("acpi_memory")
+MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
+MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+/* ACPI _STA method values */
+#define ACPI_MEMORY_STA_PRESENT		(0x00000001UL)
+#define ACPI_MEMORY_STA_ENABLED		(0x00000002UL)
+#define ACPI_MEMORY_STA_FUNCTIONAL	(0x00000008UL)
+
+/* Memory Device States */
+#define MEMORY_INVALID_STATE	0
+#define MEMORY_POWER_ON_STATE	1
+#define MEMORY_POWER_OFF_STATE	2
+
+static int acpi_memory_device_add (struct acpi_device *device);
+static int acpi_memory_device_remove (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_memory_device_driver = {
+	.name =		ACPI_MEMORY_DEVICE_DRIVER_NAME,
+	.class =	ACPI_MEMORY_DEVICE_CLASS,
+	.ids =		ACPI_MEMORY_DEVICE_HID,
+	.ops =		{
+				.add =		acpi_memory_device_add,
+				.remove =	acpi_memory_device_remove,
+			},
+};
+
+struct acpi_memory_device {
+	acpi_handle handle;
+	unsigned int state;		/* State of the memory device */
+	unsigned short cache_attribute;	/* memory cache attribute */
+	unsigned short read_write_attribute;/* memory read/write attribute */
+	u64 start_addr;	/* Memory Range start physical addr */
+	u64 end_addr;	/* Memory Range end physical addr */
+};
+
+
+static int
+acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_resource *resource = NULL;
+	struct acpi_resource_address64 address64;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_get_device_resources");
+
+	/* Get the range from the _CRS */
+	status = acpi_get_current_resources(mem_device->handle, &buffer);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-EINVAL);
+
+	resource = (struct acpi_resource *) buffer.pointer;
+	status = acpi_resource_to_address64(resource, &address64);
+	if (ACPI_SUCCESS(status)) {
+		if (address64.resource_type == ACPI_MEMORY_RANGE) {
+			/* Populate the structure */
+			mem_device->cache_attribute =
+				address64.attribute.memory.cache_attribute;
+			mem_device->read_write_attribute =
+			address64.attribute.memory.read_write_attribute;
+			mem_device->start_addr = address64.min_address_range;
+			mem_device->end_addr = address64.max_address_range;
+		}
+	}
+
+	acpi_os_free(buffer.pointer);
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_get_device(acpi_handle handle,
+	struct acpi_memory_device **mem_device)
+{
+	acpi_status status;
+	acpi_handle phandle;
+	struct acpi_device *device = NULL;
+	struct acpi_device *pdevice = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_get_device");
+
+	if (!acpi_bus_get_device(handle, &device) && device)
+		goto end;
+
+	status = acpi_get_parent(handle, &phandle);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error in acpi_get_parent\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	/* Get the parent device */
+	status = acpi_bus_get_device(phandle, &pdevice);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error in acpi_bus_get_device\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	/*
+	 * Now add the notified device.  This creates the acpi_device
+	 * and invokes .add function
+	 */
+	status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error in acpi_bus_add\n"));
+		return_VALUE(-EINVAL);
+	}
+
+end:
+	*mem_device = acpi_driver_data(device);
+	if (!(*mem_device)) {
+		printk(KERN_ERR "\n driver data not found" );
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_check_device(struct acpi_memory_device *mem_device)
+{
+	unsigned long current_status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_check_device");
+
+	/* Get device present/absent information from the _STA */
+	if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->handle, "_STA",
+		NULL, &current_status)))
+		return_VALUE(-ENODEV);
+	/*
+	 * Check for device status. Device should be
+	 * present/enabled/functioning.
+	 */
+	if (!((current_status & ACPI_MEMORY_STA_PRESENT)
+		&& (current_status & ACPI_MEMORY_STA_ENABLED)
+		&& (current_status & ACPI_MEMORY_STA_FUNCTIONAL)))
+		return_VALUE(-ENODEV);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_enable_device(struct acpi_memory_device *mem_device)
+{
+	int result;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_enable_device");
+
+	/* Get the range from the _CRS */
+	result = acpi_memory_get_device_resources(mem_device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"\nget_device_resources failed\n"));
+		mem_device->state = MEMORY_INVALID_STATE;
+		return result;
+	}
+
+	/*
+	 * Tell the VM there is more memory here...
+	 * Note: Assume that this function returns zero on success
+	 */
+	result = add_memory(mem_device->start_addr,
+			(mem_device->end_addr - mem_device->start_addr) + 1,
+			mem_device->read_write_attribute);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"\nadd_memory failed\n"));
+		mem_device->state = MEMORY_INVALID_STATE;
+		return result;
+	}
+
+	return result;
+}
+
+static int
+acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
+{
+	acpi_status status;
+	struct acpi_object_list	arg_list;
+	union acpi_object arg;
+	unsigned long current_status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_powerdown_device");
+
+	/* Issue the _EJ0 command */
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = 1;
+	status = acpi_evaluate_object(mem_device->handle,
+			"_EJ0", &arg_list, NULL);
+	/* Return on _EJ0 failure */
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"_EJ0 failed.\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	/* Evalute _STA to check if the device is disabled */
+	status = acpi_evaluate_integer(mem_device->handle, "_STA",
+		NULL, &current_status);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	/* Check for device status.  Device should be disabled */
+	if (current_status & ACPI_MEMORY_STA_ENABLED)
+		return_VALUE(-EINVAL);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_disable_device(struct acpi_memory_device *mem_device)
+{
+	int result;
+	u64 start = mem_device->start_addr;
+	u64 len = mem_device->end_addr - start + 1;
+	unsigned long attr = mem_device->read_write_attribute;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_disable_device");
+
+	/*
+	 * Ask the VM to offline this memory range.
+	 * Note: Assume that this function returns zero on success
+	 */
+	result = remove_memory(start, len, attr);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n"));
+		return_VALUE(result);
+	}
+
+	/* Power-off and eject the device */
+	result = acpi_memory_powerdown_device(mem_device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Device Power Down failed.\n"));
+		/* Set the status of the device to invalid */
+		mem_device->state = MEMORY_INVALID_STATE;
+		return result;
+	}
+
+	mem_device->state = MEMORY_POWER_OFF_STATE;
+	return result;
+}
+
+static void
+acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct acpi_memory_device *mem_device;
+	struct acpi_device *device;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_notify");
+
+	switch (event) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"\nReceived BUS CHECK notification for device\n"));
+		/* Fall Through */
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		if (event == ACPI_NOTIFY_DEVICE_CHECK)
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"\nReceived DEVICE CHECK notification for device\n"));
+		if (acpi_memory_get_device(handle, &mem_device)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error in finding driver data\n"));
+			return_VOID;
+		}
+
+		if (!acpi_memory_check_device(mem_device)) {
+			if (acpi_memory_enable_device(mem_device))
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error in acpi_memory_enable_device\n"));
+		}
+		break;
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"\nReceived EJECT REQUEST notification for device\n"));
+
+		if (acpi_bus_get_device(handle, &device)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Device doesn't exist\n"));
+			break;
+		}
+		mem_device = acpi_driver_data(device);
+		if (!mem_device) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Driver Data is NULL\n"));
+			break;
+		}
+
+		/*
+		 * Currently disabling memory device from kernel mode
+		 * TBD: Can also be disabled from user mode scripts
+		 * TBD: Can also be disabled by Callback registration
+		 * 	with generic sysfs driver
+		 */
+		if (acpi_memory_disable_device(mem_device))
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error in acpi_memory_disable_device\n"));
+		/*
+		 * TBD: Invoke acpi_bus_remove to cleanup data structures
+		 */
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+static int
+acpi_memory_device_add(struct acpi_device *device)
+{
+	int result;
+	struct acpi_memory_device *mem_device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
+	if (!mem_device)
+		return_VALUE(-ENOMEM);
+	memset(mem_device, 0, sizeof(struct acpi_memory_device));
+
+	mem_device->handle = device->handle;
+	sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
+	sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
+	acpi_driver_data(device) = mem_device;
+
+	/* Get the range from the _CRS */
+	result = acpi_memory_get_device_resources(mem_device);
+	if (result) {
+		kfree(mem_device);
+		return_VALUE(result);
+	}
+
+	/* Set the device state */
+	mem_device->state = MEMORY_POWER_ON_STATE;
+
+	printk(KERN_INFO "%s \n", acpi_device_name(device));
+
+	return_VALUE(result);
+}
+
+static int
+acpi_memory_device_remove (struct acpi_device *device, int type)
+{
+	struct acpi_memory_device *mem_device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	mem_device = (struct acpi_memory_device *) acpi_driver_data(device);
+	kfree(mem_device);
+
+	return_VALUE(0);
+}
+
+/*
+ * Helper function to check for memory device
+ */
+static acpi_status
+is_memory_device(acpi_handle handle)
+{
+	char *hardware_id;
+	acpi_status status;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_device_info *info;
+
+	ACPI_FUNCTION_TRACE("is_memory_device");
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(AE_ERROR);
+
+	info = buffer.pointer;
+	if (!(info->valid & ACPI_VALID_HID)) {
+		acpi_os_free(buffer.pointer);
+		return_ACPI_STATUS(AE_ERROR);
+	}
+
+	hardware_id = info->hardware_id.value;
+	if ((hardware_id == NULL) ||
+		(strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
+		status = AE_ERROR;
+
+	acpi_os_free(buffer.pointer);
+	return_ACPI_STATUS(status);
+}
+
+static acpi_status
+acpi_memory_register_notify_handler (acpi_handle handle,
+	u32 level, void *ctxt, void **retv)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_register_notify_handler");
+
+	status = is_memory_device(handle);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(AE_OK);	/* continue */
+
+	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+			acpi_memory_device_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing notify handler\n"));
+		return_ACPI_STATUS(AE_OK);	/* continue */
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+static acpi_status
+acpi_memory_deregister_notify_handler (acpi_handle handle,
+			       u32 level, void *ctxt, void **retv)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_deregister_notify_handler");
+
+	status = is_memory_device(handle);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(AE_OK);	/* continue */
+
+	status = acpi_remove_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY, acpi_memory_device_notify);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error removing notify handler\n"));
+		return_ACPI_STATUS(AE_OK);	/* continue */
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+static int __init
+acpi_memory_device_init (void)
+{
+	int result;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_init");
+
+	result = acpi_bus_register_driver(&acpi_memory_device_driver);
+
+	if (result < 0)
+		return_VALUE(-ENODEV);
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+				ACPI_UINT32_MAX,
+				acpi_memory_register_notify_handler,
+				NULL, NULL);
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+		acpi_bus_unregister_driver(&acpi_memory_device_driver);
+		return_VALUE(-ENODEV);
+        }
+
+	return_VALUE(0);
+}
+
+static void __exit
+acpi_memory_device_exit (void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_exit");
+
+	/*
+	 * Adding this to un-install notification handlers for all the device
+	 * handles.
+	 */
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			ACPI_UINT32_MAX,
+			acpi_memory_deregister_notify_handler,
+			NULL, NULL);
+
+	if (ACPI_FAILURE (status))
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+
+	acpi_bus_unregister_driver(&acpi_memory_device_driver);
+
+	return_VOID;
+}
+
+module_init(acpi_memory_device_init);
+module_exit(acpi_memory_device_exit);
+
+
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
new file mode 100644
index 0000000..a75cb56
--- /dev/null
+++ b/drivers/acpi/asus_acpi.c
@@ -0,0 +1,1236 @@
+/*
+ *  asus_acpi.c - Asus Laptop ACPI Extras
+ *
+ *
+ *  Copyright (C) 2002, 2003, 2004 Julien Lerouge, Karol Kozimor
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ *  The development page for this driver is located at
+ *  http://sourceforge.net/projects/acpi4asus/
+ *
+ *  Credits:
+ *  Pontus Fuchs   - Helper functions, cleanup
+ *  Johann Wiesner - Small compile fixes
+ *  John Belmonte  - ACPI code for Toshiba laptop was a good starting point.
+ *
+ *  TODO:
+ *  add Fn key status
+ *  Add mode selection on module loading (parameter) -> still necessary?
+ *  Complete display switching -- may require dirty hacks or calling _DOS?
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include <asm/uaccess.h>
+
+#define ASUS_ACPI_VERSION "0.29"
+
+#define PROC_ASUS       "asus"	//the directory
+#define PROC_MLED       "mled"
+#define PROC_WLED       "wled"
+#define PROC_TLED       "tled"
+#define PROC_INFO       "info"
+#define PROC_LCD        "lcd"
+#define PROC_BRN        "brn"
+#define PROC_DISP       "disp"
+
+#define ACPI_HOTK_NAME          "Asus Laptop ACPI Extras Driver"
+#define ACPI_HOTK_CLASS         "hotkey"
+#define ACPI_HOTK_DEVICE_NAME   "Hotkey"
+#define ACPI_HOTK_HID           "ATK0100"
+
+/*
+ * Some events we use, same for all Asus
+ */
+#define BR_UP       0x10      		
+#define BR_DOWN     0x20
+
+/*
+ * Flags for hotk status
+ */
+#define MLED_ON     0x01	//is MLED ON ?
+#define WLED_ON     0x02
+#define TLED_ON     0x04
+
+MODULE_AUTHOR("Julien Lerouge, Karol Kozimor");
+MODULE_DESCRIPTION(ACPI_HOTK_NAME);
+MODULE_LICENSE("GPL");
+
+
+static uid_t asus_uid;
+static gid_t asus_gid;
+module_param(asus_uid, uint, 0);
+MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n");
+module_param(asus_gid, uint, 0);
+MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n");
+
+
+/* For each model, all features implemented, 
+ * those marked with R are relative to HOTK, A for absolute */
+struct model_data {
+	char *name;              //name of the laptop________________A
+	char *mt_mled;           //method to handle mled_____________R
+	char *mled_status;       //node to handle mled reading_______A
+	char *mt_wled;           //method to handle wled_____________R
+	char *wled_status;       //node to handle wled reading_______A
+ 	char *mt_tled;           //method to handle tled_____________R
+ 	char *tled_status;       //node to handle tled reading_______A
+	char *mt_lcd_switch;     //method to turn LCD ON/OFF_________A
+	char *lcd_status;        //node to read LCD panel state______A
+	char *brightness_up;     //method to set brightness up_______A
+	char *brightness_down;   //guess what ?______________________A
+	char *brightness_set;    //method to set absolute brightness_R
+	char *brightness_get;    //method to get absolute brightness_R
+	char *brightness_status; //node to get brightness____________A
+	char *display_set;       //method to set video output________R
+	char *display_get;       //method to get video output________R
+};
+
+/*
+ * This is the main structure, we can use it to store anything interesting
+ * about the hotk device
+ */
+struct asus_hotk {
+	struct acpi_device *device; //the device we are in
+	acpi_handle handle;         //the handle of the hotk device
+	char status;                //status of the hotk, for LEDs, ...
+	struct model_data *methods; //methods available on the laptop
+	u8 brightness;              //brightness level
+	enum {
+		A1x = 0,  //A1340D, A1300F
+		A2x,      //A2500H
+		D1x,      //D1
+		L2D,      //L2000D
+		L3C,      //L3800C
+		L3D,      //L3400D
+		L3H,      //L3H, but also L2000E
+		L4R,      //L4500R
+		L5x,      //L5800C 
+		L8L,      //L8400L
+		M1A,      //M1300A
+		M2E,      //M2400E, L4400L
+		M6N,      //M6800N
+		M6R,      //M6700R
+		P30,	  //Samsung P30
+		S1x,      //S1300A, but also L1400B and M2400A (L84F)
+		S2x,      //S200 (J1 reported), Victor MP-XP7210
+		xxN,      //M2400N, M3700N, M5200N, S1300N, S5200N, W1OOON
+			  //(Centrino)
+		END_MODEL
+	} model;              //Models currently supported
+	u16 event_count[128]; //count for each event TODO make this better
+};
+
+/* Here we go */
+#define A1x_PREFIX "\\_SB.PCI0.ISA.EC0."
+#define L3C_PREFIX "\\_SB.PCI0.PX40.ECD0."
+#define M1A_PREFIX "\\_SB.PCI0.PX40.EC0."
+#define P30_PREFIX "\\_SB.PCI0.LPCB.EC0."
+#define S1x_PREFIX "\\_SB.PCI0.PX40."
+#define S2x_PREFIX A1x_PREFIX
+#define xxN_PREFIX "\\_SB.PCI0.SBRG.EC0."
+
+static struct model_data model_conf[END_MODEL] = {
+        /*
+	 * Those pathnames are relative to the HOTK / ATKD device :
+	 *       - mt_mled
+	 *       - mt_wled
+	 *       - brightness_set
+	 *       - brightness_get
+	 *       - display_set
+	 *       - display_get
+	 *
+	 * TODO I have seen a SWBX and AIBX method on some models, like L1400B,
+	 * it seems to be a kind of switch, but what for ?
+	 *
+	 */
+
+	{
+		.name              = "A1x",
+		.mt_mled           = "MLED",
+		.mled_status       = "\\MAIL",
+		.mt_lcd_switch     = A1x_PREFIX "_Q10",
+		.lcd_status        = "\\BKLI",
+		.brightness_up     = A1x_PREFIX "_Q0E",
+		.brightness_down   = A1x_PREFIX "_Q0F"
+	},
+
+	{
+		.name              = "A2x",
+		.mt_mled           = "MLED",
+		.mt_wled           = "WLED",
+		.wled_status       = "\\SG66",
+		.mt_lcd_switch     = "\\Q10",
+		.lcd_status        = "\\BAOF",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "D1x",
+		.mt_mled           = "MLED",
+		.mt_lcd_switch     = "\\Q0D",
+		.lcd_status        = "\\GP11",
+		.brightness_up     = "\\Q0C",
+		.brightness_down   = "\\Q0B",
+		.brightness_status = "\\BLVL",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "L2D",
+		.mt_mled           = "MLED",
+		.mled_status       = "\\SGP6",
+		.mt_wled           = "WLED",
+		.wled_status       = "\\RCP3",
+		.mt_lcd_switch     = "\\Q10",
+		.lcd_status        = "\\SGP0",
+		.brightness_up     = "\\Q0E",
+		.brightness_down   = "\\Q0F",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "L3C",
+		.mt_mled           = "MLED",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = L3C_PREFIX "_Q10",
+		.lcd_status        = "\\GL32",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\_SB.PCI0.PCI1.VGAC.NMAP"
+	},
+
+	{
+		.name              = "L3D",
+		.mt_mled           = "MLED",
+		.mled_status       = "\\MALD",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = "\\Q10",
+		.lcd_status        = "\\BKLG",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "L3H",
+		.mt_mled           = "MLED",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = "EHK",
+		.lcd_status        = "\\_SB.PCI0.PM.PBC",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "L4R",
+		.mt_mled           = "MLED",
+		.mt_wled           = "WLED",
+		.wled_status       = "\\_SB.PCI0.SBRG.SG13",
+		.mt_lcd_switch     = xxN_PREFIX "_Q10",
+		.lcd_status        = "\\_SB.PCI0.SBSM.SEO4",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV", 
+		.display_set       = "SDSP",
+		.display_get       = "\\_SB.PCI0.P0P1.VGA.GETD"
+	},
+
+	{
+		.name              = "L5x",
+		.mt_mled           = "MLED",
+/* WLED present, but not controlled by ACPI */
+		.mt_tled           = "TLED",
+		.mt_lcd_switch     = "\\Q0D",
+		.lcd_status        = "\\BAOF",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "L8L"
+/* No features, but at least support the hotkeys */
+	},
+
+	{
+		.name              = "M1A",
+		.mt_mled           = "MLED",
+		.mt_lcd_switch     = M1A_PREFIX "Q10",
+		.lcd_status        = "\\PNOF",
+		.brightness_up     = M1A_PREFIX "Q0E",
+		.brightness_down   = M1A_PREFIX "Q0F",
+		.brightness_status = "\\BRIT",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "M2E",
+		.mt_mled           = "MLED",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = "\\Q10",
+		.lcd_status        = "\\GP06",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\INFB"
+	},
+
+	{
+		.name              = "M6N",
+		.mt_mled           = "MLED",
+		.mt_wled           = "WLED",
+		.wled_status       = "\\_SB.PCI0.SBRG.SG13",
+		.mt_lcd_switch     = xxN_PREFIX "_Q10",
+		.lcd_status        = "\\_SB.BKLT",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\SSTE"
+	},
+	{
+		.name              = "M6R",
+		.mt_mled           = "MLED",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = xxN_PREFIX "_Q10",
+		.lcd_status        = "\\_SB.PCI0.SBSM.SEO4",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\SSTE"
+	},
+
+
+	{
+		.name              = "P30",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = P30_PREFIX "_Q0E",
+		.lcd_status        = "\\BKLT",
+		.brightness_up     = P30_PREFIX "_Q68",
+		.brightness_down   = P30_PREFIX "_Q69",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\DNXT"
+	},
+
+	{
+		.name              = "S1x",
+		.mt_mled           = "MLED",
+		.mled_status       = "\\EMLE",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = S1x_PREFIX "Q10" ,
+		.lcd_status        = "\\PNOF",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV"
+	},
+
+	{
+		.name              = "S2x",
+		.mt_mled           = "MLED",
+		.mled_status       = "\\MAIL",
+		.mt_lcd_switch     = S2x_PREFIX "_Q10",
+		.lcd_status        = "\\BKLI",
+		.brightness_up     = S2x_PREFIX "_Q0B",
+		.brightness_down   = S2x_PREFIX "_Q0A"
+	},
+
+	{
+		.name              = "xxN",
+		.mt_mled           = "MLED",
+/* WLED present, but not controlled by ACPI */
+		.mt_lcd_switch     = xxN_PREFIX "_Q10",
+		.lcd_status        = "\\BKLT",
+		.brightness_set    = "SPLV",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\ADVG"
+	}
+};
+
+/* procdir we use */
+static struct proc_dir_entry *asus_proc_dir;
+
+/*
+ * This header is made available to allow proper configuration given model,
+ * revision number , ... this info cannot go in struct asus_hotk because it is
+ * available before the hotk
+ */
+static struct acpi_table_header *asus_info;
+
+/* The actual device the driver binds to */
+static struct asus_hotk *hotk;
+
+/*
+ * The hotkey driver declaration
+ */
+static int asus_hotk_add(struct acpi_device *device);
+static int asus_hotk_remove(struct acpi_device *device, int type);
+static struct acpi_driver asus_hotk_driver = {
+	.name = 	ACPI_HOTK_NAME,
+	.class = 	ACPI_HOTK_CLASS,
+	.ids = 		ACPI_HOTK_HID,
+	.ops = 		{
+				.add = 		asus_hotk_add,
+				.remove = 	asus_hotk_remove,
+			},
+};
+
+/* 
+ * This function evaluates an ACPI method, given an int as parameter, the
+ * method is searched within the scope of the handle, can be NULL. The output
+ * of the method is written is output, which can also be NULL
+ *
+ * returns 1 if write is successful, 0 else. 
+ */
+static int write_acpi_int(acpi_handle handle, const char *method, int val,
+			  struct acpi_buffer *output)
+{
+	struct acpi_object_list params;	//list of input parameters (an int here)
+	union acpi_object in_obj;	//the only param we use
+	acpi_status status;
+
+	params.count = 1;
+	params.pointer = &in_obj;
+	in_obj.type = ACPI_TYPE_INTEGER;
+	in_obj.integer.value = val;
+
+	status = acpi_evaluate_object(handle, (char *) method, &params, output);
+	return (status == AE_OK);
+}
+
+
+static int read_acpi_int(acpi_handle handle, const char *method, int *val)
+{
+	struct acpi_buffer output;
+	union acpi_object out_obj;
+	acpi_status status;
+
+	output.length = sizeof(out_obj);
+	output.pointer = &out_obj;
+
+	status = acpi_evaluate_object(handle, (char *) method, NULL, &output);
+	*val = out_obj.integer.value;
+	return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
+}
+
+/*
+ * We write our info in page, we begin at offset off and cannot write more
+ * than count bytes. We set eof to 1 if we handle those 2 values. We return the
+ * number of bytes written in page
+ */
+static int
+proc_read_info(char *page, char **start, off_t off, int count, int *eof,
+		void *data)
+{
+	int len = 0;
+	int temp;
+	char buf[16];		//enough for all info
+	/*
+	 * We use the easy way, we don't care of off and count, so we don't set eof
+	 * to 1
+	 */
+
+	len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
+	len += sprintf(page + len, "Model reference    : %s\n", 
+		       hotk->methods->name);
+	/* 
+	 * The SFUN method probably allows the original driver to get the list 
+	 * of features supported by a given model. For now, 0x0100 or 0x0800 
+	 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
+	 * The significance of others is yet to be found.
+	 */
+	if (read_acpi_int(hotk->handle, "SFUN", &temp))
+		len += sprintf(page + len, "SFUN value         : 0x%04x\n", temp);
+	/*
+	 * Another value for userspace: the ASYM method returns 0x02 for
+	 * battery low and 0x04 for battery critical, its readings tend to be
+	 * more accurate than those provided by _BST. 
+	 * Note: since not all the laptops provide this method, errors are
+	 * silently ignored.
+	 */
+	if (read_acpi_int(hotk->handle, "ASYM", &temp))
+		len += sprintf(page + len, "ASYM value         : 0x%04x\n", temp);
+	if (asus_info) {
+		snprintf(buf, 16, "%d", asus_info->length);
+		len += sprintf(page + len, "DSDT length        : %s\n", buf);
+		snprintf(buf, 16, "%d", asus_info->checksum);
+		len += sprintf(page + len, "DSDT checksum      : %s\n", buf);
+		snprintf(buf, 16, "%d", asus_info->revision);
+		len += sprintf(page + len, "DSDT revision      : %s\n", buf);
+		snprintf(buf, 7, "%s", asus_info->oem_id);
+		len += sprintf(page + len, "OEM id             : %s\n", buf);
+		snprintf(buf, 9, "%s", asus_info->oem_table_id);
+		len += sprintf(page + len, "OEM table id       : %s\n", buf);
+		snprintf(buf, 16, "%x", asus_info->oem_revision);
+		len += sprintf(page + len, "OEM revision       : 0x%s\n", buf);
+		snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
+		len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
+		snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
+		len += sprintf(page + len, "ASL comp revision  : 0x%s\n", buf);
+	}
+
+	return len;
+}
+
+
+/*
+ * /proc handlers
+ * We write our info in page, we begin at offset off and cannot write more
+ * than count bytes. We set eof to 1 if we handle those 2 values. We return the
+ * number of bytes written in page
+ */
+
+/* Generic LED functions */
+static int
+read_led(const char *ledname, int ledmask)
+{
+	if (ledname) {
+		int led_status;
+
+		if (read_acpi_int(NULL, ledname, &led_status))
+			return led_status;
+		else
+			printk(KERN_WARNING "Asus ACPI: Error reading LED "
+			       "status\n");
+	}
+	return (hotk->status & ledmask) ? 1 : 0;
+}
+
+static int parse_arg(const char __user *buf, unsigned long count, int *val)
+{
+	char s[32];
+	if (!count)
+		return 0;
+	if (count > 31)
+		return -EINVAL;
+	if (copy_from_user(s, buf, count))
+		return -EFAULT;
+	s[count] = 0;
+	if (sscanf(s, "%i", val) != 1)
+		return -EINVAL;
+	return count;
+}
+
+/* FIXME: kill extraneous args so it can be called independently */
+static int
+write_led(const char __user *buffer, unsigned long count,
+          char *ledname, int ledmask, int invert)
+{
+	int value;
+	int led_out = 0;
+
+	count = parse_arg(buffer, count, &value);
+	if (count > 0)
+		led_out = value ? 1 : 0;
+
+	hotk->status =
+	    (led_out) ? (hotk->status | ledmask) : (hotk->status & ~ledmask);
+
+	if (invert) /* invert target value */
+		led_out = !led_out & 0x1;
+
+	if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
+		printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", ledname);
+
+	return count;
+}
+
+
+/*
+ * Proc handlers for MLED
+ */
+static int
+proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
+	       void *data)
+{
+	return sprintf(page, "%d\n", read_led(hotk->methods->mled_status, MLED_ON));
+}
+
+
+static int
+proc_write_mled(struct file *file, const char __user *buffer,
+		unsigned long count, void *data)
+{
+	return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
+}
+
+/*
+ * Proc handlers for WLED
+ */
+static int
+proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
+	       void *data)
+{
+	return sprintf(page, "%d\n", read_led(hotk->methods->wled_status, WLED_ON));
+}
+
+static int
+proc_write_wled(struct file *file, const char __user *buffer,
+		unsigned long count, void *data)
+{
+	return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
+}
+
+/*
+ * Proc handlers for TLED
+ */
+static int
+proc_read_tled(char *page, char **start, off_t off, int count, int *eof,
+	       void *data)
+{
+	return sprintf(page, "%d\n", read_led(hotk->methods->tled_status, TLED_ON));
+}
+
+static int
+proc_write_tled(struct file *file, const char __user *buffer,
+		unsigned long count, void *data)
+{
+	return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
+}
+
+
+static int get_lcd_state(void)
+{
+	int lcd = 0;
+
+	if (hotk->model != L3H) {
+	/* We don't have to check anything if we are here */
+		if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
+			printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n");
+	
+		if (hotk->model == L2D)
+			lcd = ~lcd;
+	} else { /* L3H and the like have to be handled differently */
+		acpi_status status = 0;
+		struct acpi_object_list input;
+		union acpi_object mt_params[2];
+		struct acpi_buffer output;
+		union acpi_object out_obj;
+		
+		input.count = 2;
+		input.pointer = mt_params;
+		/* Note: the following values are partly guessed up, but 
+		   otherwise they seem to work */
+		mt_params[0].type = ACPI_TYPE_INTEGER;
+		mt_params[0].integer.value = 0x02;
+		mt_params[1].type = ACPI_TYPE_INTEGER;
+		mt_params[1].integer.value = 0x02;
+
+		output.length = sizeof(out_obj);
+		output.pointer = &out_obj;
+		
+		status = acpi_evaluate_object(NULL, hotk->methods->lcd_status, &input, &output);
+		if (status != AE_OK)
+			return -1;
+		if (out_obj.type == ACPI_TYPE_INTEGER)
+			/* That's what the AML code does */
+			lcd = out_obj.integer.value >> 8;
+	}
+	
+	return (lcd & 1);
+}
+
+static int set_lcd_state(int value)
+{
+	int lcd = 0;
+	acpi_status status = 0;
+
+	lcd = value ? 1 : 0;
+	if (lcd != get_lcd_state()) {
+		/* switch */
+		if (hotk->model != L3H) {
+			status =
+			    acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch,
+						 NULL, NULL);
+		} else { /* L3H and the like have to be handled differently */
+			if (!write_acpi_int(hotk->handle, hotk->methods->mt_lcd_switch, 0x07, NULL))
+				status = AE_ERROR;
+			/* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, 
+			   the exact behaviour is simulated here */
+		}
+		if (ACPI_FAILURE(status))
+			printk(KERN_WARNING "Asus ACPI: Error switching LCD\n");
+	}
+	return 0;
+
+}
+
+static int
+proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
+	      void *data)
+{
+	return sprintf(page, "%d\n", get_lcd_state());
+}
+
+
+static int
+proc_write_lcd(struct file *file, const char __user *buffer,
+	       unsigned long count, void *data)
+{
+	int value;
+	
+	count = parse_arg(buffer, count, &value);
+	if (count > 0)
+		set_lcd_state(value);
+	return count;
+}
+
+
+static int read_brightness(void)
+{
+	int value;
+	
+	if(hotk->methods->brightness_get) { /* SPLV/GPLV laptop */
+		if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, 
+				   &value))
+			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
+	} else if (hotk->methods->brightness_status) { /* For D1 for example */
+		if (!read_acpi_int(NULL, hotk->methods->brightness_status, 
+				   &value))
+			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
+	} else /* No GPLV method */
+		value = hotk->brightness;
+	return value;
+}
+
+/*
+ * Change the brightness level
+ */
+static void set_brightness(int value)
+{
+	acpi_status status = 0;
+
+	/* SPLV laptop */
+	if(hotk->methods->brightness_set) {
+		if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, 
+				    value, NULL))
+			printk(KERN_WARNING "Asus ACPI: Error changing brightness\n");
+		return;
+	}
+
+	/* No SPLV method if we are here, act as appropriate */
+	value -= read_brightness();
+	while (value != 0) {
+		status = acpi_evaluate_object(NULL, (value > 0) ? 
+					      hotk->methods->brightness_up : 
+					      hotk->methods->brightness_down,
+					      NULL, NULL);
+		(value > 0) ? value-- : value++;
+		if (ACPI_FAILURE(status))
+			printk(KERN_WARNING "Asus ACPI: Error changing brightness\n");
+	}
+	return;
+}
+
+static int
+proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
+	      void *data)
+{
+	return sprintf(page, "%d\n", read_brightness());
+}
+
+static int
+proc_write_brn(struct file *file, const char __user *buffer,
+	       unsigned long count, void *data)
+{
+	int value;
+
+	count = parse_arg(buffer, count, &value);
+	if (count > 0) {
+		value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
+			/* 0 <= value <= 15 */
+		set_brightness(value);
+	} else if (count < 0) {
+		printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
+	}
+
+	return count;
+}
+
+static void set_display(int value)
+{
+	/* no sanity check needed for now */
+	if (!write_acpi_int(hotk->handle, hotk->methods->display_set, 
+			    value, NULL))
+		printk(KERN_WARNING "Asus ACPI: Error setting display\n");
+	return;
+}
+
+/*
+ * Now, *this* one could be more user-friendly, but so far, no-one has 
+ * complained. The significance of bits is the same as in proc_write_disp()
+ */
+static int
+proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
+	      void *data)
+{
+	int value = 0;
+	
+	if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
+		printk(KERN_WARNING "Asus ACPI: Error reading display status\n");
+	value &= 0x07; /* needed for some models, shouldn't hurt others */
+	return sprintf(page, "%d\n", value);
+}
+
+/*
+ * Experimental support for display switching. As of now: 1 should activate 
+ * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination 
+ * (bitwise) of these will suffice. I never actually tested 3 displays hooked up 
+ * simultaneously, so be warned. See the acpi4asus README for more info.
+ */
+static int
+proc_write_disp(struct file *file, const char __user *buffer,
+	       unsigned long count, void *data)
+{
+	int value;
+
+	count = parse_arg(buffer, count, &value);
+	if (count > 0)
+		set_display(value);
+	else if (count < 0)
+		printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
+
+	return count;
+}
+
+
+typedef int (proc_readfunc)(char *page, char **start, off_t off, int count,
+	                     int *eof, void *data);
+typedef int (proc_writefunc)(struct file *file, const char __user *buffer,
+	                      unsigned long count, void *data);
+
+static int
+__init asus_proc_add(char *name, proc_writefunc *writefunc,
+	             proc_readfunc *readfunc, mode_t mode,
+	             struct acpi_device *device)
+{
+	struct proc_dir_entry *proc = create_proc_entry(name, mode, acpi_device_dir(device));
+	if(!proc) {
+		printk(KERN_WARNING "  Unable to create %s fs entry\n", name);
+		return -1;
+	}
+	proc->write_proc = writefunc;
+	proc->read_proc = readfunc;
+	proc->data = acpi_driver_data(device);
+	proc->owner = THIS_MODULE;
+	proc->uid = asus_uid;
+	proc->gid = asus_gid;
+	return 0;
+}
+
+static int __init asus_hotk_add_fs(struct acpi_device *device)
+{
+	struct proc_dir_entry *proc;
+	mode_t mode;
+	
+	/*
+	 * If parameter uid or gid is not changed, keep the default setting for
+	 * our proc entries (-rw-rw-rw-) else, it means we care about security,
+	 * and then set to -rw-rw----
+	 */
+
+	if ((asus_uid == 0) && (asus_gid == 0)){
+		mode = S_IFREG | S_IRUGO | S_IWUGO;
+	} else {
+		mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP;
+	}
+
+	acpi_device_dir(device) = asus_proc_dir;
+	if (!acpi_device_dir(device))
+		return -ENODEV;
+
+	proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device));
+	if (proc) {
+		proc->read_proc = proc_read_info;
+		proc->data = acpi_driver_data(device);
+		proc->owner = THIS_MODULE;
+		proc->uid = asus_uid;
+		proc->gid = asus_gid;
+	} else {
+		printk(KERN_WARNING "  Unable to create " PROC_INFO
+		       " fs entry\n");
+	}
+
+	if (hotk->methods->mt_wled) {
+		asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled, mode, device);
+	}
+
+	if (hotk->methods->mt_mled) {
+		asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, mode, device);
+	}
+
+	if (hotk->methods->mt_tled) {
+		asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled, mode, device);
+	}
+
+	/* 
+	 * We need both read node and write method as LCD switch is also accessible
+	 * from keyboard 
+	 */
+	if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
+		asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, device);
+	}
+	
+	if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
+	    (hotk->methods->brightness_get && hotk->methods->brightness_set)) {
+		asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, device);
+	}
+
+	if (hotk->methods->display_set) {
+		asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, mode, device);
+	}
+
+	return 0;
+}
+
+static int asus_hotk_remove_fs(struct acpi_device* device)
+{
+	if(acpi_device_dir(device)) {
+		remove_proc_entry(PROC_INFO,acpi_device_dir(device));
+		if (hotk->methods->mt_wled)
+			remove_proc_entry(PROC_WLED,acpi_device_dir(device));
+		if (hotk->methods->mt_mled)
+			remove_proc_entry(PROC_MLED,acpi_device_dir(device));
+		if (hotk->methods->mt_tled)
+			remove_proc_entry(PROC_TLED,acpi_device_dir(device));
+		if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status)
+			remove_proc_entry(PROC_LCD, acpi_device_dir(device));
+		if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
+		    (hotk->methods->brightness_get && hotk->methods->brightness_set))
+			remove_proc_entry(PROC_BRN, acpi_device_dir(device));
+		if (hotk->methods->display_set)
+			remove_proc_entry(PROC_DISP, acpi_device_dir(device));
+	}
+	return 0;
+}
+
+
+static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
+{
+	/* TODO Find a better way to handle events count.*/
+	if (!hotk)
+		return;
+
+	if ((event & ~((u32) BR_UP)) < 16) {
+		hotk->brightness = (event & ~((u32) BR_UP));
+	} else if ((event & ~((u32) BR_DOWN)) < 16 ) {
+		hotk->brightness = (event & ~((u32) BR_DOWN));
+	}
+
+	acpi_bus_generate_event(hotk->device, event,
+				hotk->event_count[event % 128]++);
+
+	return;
+}
+
+/*
+ * This function is used to initialize the hotk with right values. In this
+ * method, we can make all the detection we want, and modify the hotk struct
+ */
+static int __init asus_hotk_get_info(void)
+{
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *model = NULL;
+	int bsts_result;
+	acpi_status status;
+
+	/*
+	 * Get DSDT headers early enough to allow for differentiating between 
+	 * models, but late enough to allow acpi_bus_register_driver() to fail 
+	 * before doing anything ACPI-specific. Should we encounter a machine,
+	 * which needs special handling (i.e. its hotkey device has a different
+	 * HID), this bit will be moved. A global variable asus_info contains
+	 * the DSDT header.
+	 */
+	status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt);
+	if (ACPI_FAILURE(status))
+		printk(KERN_WARNING "  Couldn't get the DSDT table header\n");
+	else
+		asus_info = (struct acpi_table_header *) dsdt.pointer;
+
+	/* We have to write 0 on init this far for all ASUS models */
+	if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
+		printk(KERN_ERR "  Hotkey initialization failed\n");
+		return -ENODEV;
+	}
+
+	/* This needs to be called for some laptops to init properly */
+	if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result))
+		printk(KERN_WARNING "  Error calling BSTS\n");
+	else if (bsts_result)
+		printk(KERN_NOTICE "  BSTS called, 0x%02x returned\n", bsts_result);
+
+	/* Samsung P30 has a device with a valid _HID whose INIT does not 
+	 * return anything. Catch this one and any similar here */
+	if (buffer.pointer == NULL) {
+		if (asus_info && /* Samsung P30 */
+		    strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) {
+			hotk->model = P30;
+			printk(KERN_NOTICE "  Samsung P30 detected, supported\n");
+		} else {
+			hotk->model = M2E;
+			printk(KERN_WARNING "  no string returned by INIT\n");
+			printk(KERN_WARNING "  trying default values, supply "
+			       "the developers with your DSDT\n");
+		}
+		hotk->methods = &model_conf[hotk->model];
+		return AE_OK;
+	}
+	
+	model = (union acpi_object *) buffer.pointer;
+	if (model->type == ACPI_TYPE_STRING) {
+		printk(KERN_NOTICE "  %s model detected, ", model->string.pointer);
+	}
+
+	hotk->model = END_MODEL;
+	if (strncmp(model->string.pointer, "L3D", 3) == 0)
+		hotk->model = L3D;
+	else if (strncmp(model->string.pointer, "L3H", 3) == 0 ||
+		 strncmp(model->string.pointer, "L2E", 3) == 0)
+		hotk->model = L3H;
+	else if (strncmp(model->string.pointer, "L3", 2) == 0 ||
+		 strncmp(model->string.pointer, "L2B", 3) == 0)
+		hotk->model = L3C;
+	else if (strncmp(model->string.pointer, "L8L", 3) == 0)
+		hotk->model = L8L;
+	else if (strncmp(model->string.pointer, "L4R", 3) == 0)
+		hotk->model = L4R;
+	else if (strncmp(model->string.pointer, "M6N", 3) == 0)
+		hotk->model = M6N;
+	else if (strncmp(model->string.pointer, "M6R", 3) == 0)
+		hotk->model = M6R;
+	else if (strncmp(model->string.pointer, "M2N", 3) == 0 ||
+		 strncmp(model->string.pointer, "M3N", 3) == 0 ||
+		 strncmp(model->string.pointer, "M5N", 3) == 0 ||
+		 strncmp(model->string.pointer, "M6N", 3) == 0 ||
+		 strncmp(model->string.pointer, "S1N", 3) == 0 ||
+		 strncmp(model->string.pointer, "S5N", 3) == 0 ||
+                 strncmp(model->string.pointer, "W1N", 3) == 0)
+		hotk->model = xxN;
+	else if (strncmp(model->string.pointer, "M1", 2) == 0)
+		hotk->model = M1A;
+	else if (strncmp(model->string.pointer, "M2", 2) == 0 ||
+		 strncmp(model->string.pointer, "L4E", 3) == 0)
+		hotk->model = M2E;
+	else if (strncmp(model->string.pointer, "L2", 2) == 0)
+		hotk->model = L2D;
+	else if (strncmp(model->string.pointer, "L8", 2) == 0)
+		hotk->model = S1x;
+	else if (strncmp(model->string.pointer, "D1", 2) == 0)
+		hotk->model = D1x;
+	else if (strncmp(model->string.pointer, "A1", 2) == 0)
+		hotk->model = A1x;
+	else if (strncmp(model->string.pointer, "A2", 2) == 0)
+		hotk->model = A2x;
+	else if (strncmp(model->string.pointer, "J1", 2) == 0)
+		hotk->model = S2x;
+	else if (strncmp(model->string.pointer, "L5", 2) == 0)
+		hotk->model = L5x;
+
+	if (hotk->model == END_MODEL) {
+		printk("unsupported, trying default values, supply the "
+		       "developers with your DSDT\n");
+		hotk->model = M2E;
+	} else {
+		printk("supported\n");
+	}
+
+	hotk->methods = &model_conf[hotk->model];
+
+	/* Sort of per-model blacklist */
+	if (strncmp(model->string.pointer, "L2B", 3) == 0)
+		hotk->methods->lcd_status = NULL; 
+	/* L2B is similar enough to L3C to use its settings, with this only 
+	   exception */
+	else if (strncmp(model->string.pointer, "S5N", 3) == 0 ||
+		 strncmp(model->string.pointer, "M5N", 3) == 0)
+		hotk->methods->mt_mled = NULL; 
+	/* S5N and M5N have no MLED */
+	else if (strncmp(model->string.pointer, "M2N", 3) == 0 ||
+		 strncmp(model->string.pointer, "W1N", 3) == 0)
+		hotk->methods->mt_wled = "WLED"; 
+	/* M2N and W1N have a usable WLED */
+	else if (asus_info) {
+		if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
+			hotk->methods->mled_status = NULL;
+	/* S1300A reports L84F, but L1400B too, account for that */
+	}
+
+	acpi_os_free(model);
+
+	return AE_OK;
+}
+
+
+static int __init asus_hotk_check(void)
+{
+	int result = 0;
+
+	result = acpi_bus_get_status(hotk->device);
+	if (result)
+		return result;
+
+	if (hotk->device->status.present) {
+		result = asus_hotk_get_info();
+	} else {
+		printk(KERN_ERR "  Hotkey device not present, aborting\n");
+		return -EINVAL;
+	}
+
+	return result;
+}
+
+
+static int __init asus_hotk_add(struct acpi_device *device)
+{
+	acpi_status status = AE_OK;
+	int result;
+
+	if (!device)
+		return -EINVAL;
+
+	printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
+	       ASUS_ACPI_VERSION);
+
+	hotk =
+	    (struct asus_hotk *) kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
+	if (!hotk)
+		return -ENOMEM;
+	memset(hotk, 0, sizeof(struct asus_hotk));
+
+	hotk->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_HOTK_CLASS);
+	acpi_driver_data(device) = hotk;
+	hotk->device = device;
+
+
+	result = asus_hotk_check();
+	if (result)
+		goto end;
+
+	result = asus_hotk_add_fs(device);
+	if (result)
+		goto end;
+
+	/*
+	 * We install the handler, it will receive the hotk in parameter, so, we
+	 * could add other data to the hotk struct
+	 */
+	status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
+					     asus_hotk_notify, hotk);
+	if (ACPI_FAILURE(status))
+		printk(KERN_ERR "  Error installing notify handler\n");
+
+	/* For laptops without GPLV: init the hotk->brightness value */
+	if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) &&
+	    (hotk->methods->brightness_up && hotk->methods->brightness_down)) {
+		status = acpi_evaluate_object(NULL, hotk->methods->brightness_down,
+					      NULL, NULL);
+		if (ACPI_FAILURE(status))
+			printk(KERN_WARNING "  Error changing brightness\n");
+		else {
+			status = acpi_evaluate_object(NULL, hotk->methods->brightness_up,
+						      NULL, NULL);
+			if (ACPI_FAILURE(status))
+				printk(KERN_WARNING "  Strange, error changing" 
+				       " brightness\n");
+		}
+	}
+
+      end:
+	if (result) {
+		kfree(hotk);
+	}
+
+	return result;
+}
+
+
+static int asus_hotk_remove(struct acpi_device *device, int type)
+{
+	acpi_status status = 0;
+
+	if (!device || !acpi_driver_data(device))
+		return -EINVAL;
+
+	status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
+					    asus_hotk_notify);
+	if (ACPI_FAILURE(status))
+		printk(KERN_ERR "Asus ACPI: Error removing notify handler\n");
+
+	asus_hotk_remove_fs(device);
+
+	kfree(hotk);
+
+	return 0;
+}
+
+
+static int __init asus_acpi_init(void)
+{
+	int result;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
+	if (!asus_proc_dir) {
+		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
+		return -ENODEV;
+	}
+	asus_proc_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&asus_hotk_driver);
+	if (result < 1) {
+		acpi_bus_unregister_driver(&asus_hotk_driver);
+		remove_proc_entry(PROC_ASUS, acpi_root_dir);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
+static void __exit asus_acpi_exit(void)
+{
+	acpi_bus_unregister_driver(&asus_hotk_driver);
+	remove_proc_entry(PROC_ASUS, acpi_root_dir);
+
+	acpi_os_free(asus_info);
+
+	return;
+}
+
+module_init(asus_acpi_init);
+module_exit(asus_acpi_exit);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
new file mode 100644
index 0000000..c55feca
--- /dev/null
+++ b/drivers/acpi/battery.c
@@ -0,0 +1,846 @@
+/*
+ *  acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
+
+#define ACPI_BATTERY_FORMAT_BIF	"NNNNNNNNNSSSS"
+#define ACPI_BATTERY_FORMAT_BST	"NNNN"
+
+#define ACPI_BATTERY_COMPONENT		0x00040000
+#define ACPI_BATTERY_CLASS		"battery"
+#define ACPI_BATTERY_HID		"PNP0C0A"
+#define ACPI_BATTERY_DRIVER_NAME	"ACPI Battery Driver"
+#define ACPI_BATTERY_DEVICE_NAME	"Battery"
+#define ACPI_BATTERY_FILE_INFO		"info"
+#define ACPI_BATTERY_FILE_STATUS	"state"
+#define ACPI_BATTERY_FILE_ALARM		"alarm"
+#define ACPI_BATTERY_NOTIFY_STATUS	0x80
+#define ACPI_BATTERY_NOTIFY_INFO	0x81
+#define ACPI_BATTERY_UNITS_WATTS	"mW"
+#define ACPI_BATTERY_UNITS_AMPS		"mA"
+
+
+#define _COMPONENT		ACPI_BATTERY_COMPONENT
+ACPI_MODULE_NAME		("acpi_battery")
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static int acpi_battery_add (struct acpi_device *device);
+static int acpi_battery_remove (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_battery_driver = {
+	.name =		ACPI_BATTERY_DRIVER_NAME,
+	.class =	ACPI_BATTERY_CLASS,
+	.ids =		ACPI_BATTERY_HID,
+	.ops =		{
+				.add =		acpi_battery_add,
+				.remove =	acpi_battery_remove,
+			},
+};
+
+struct acpi_battery_status {
+	acpi_integer		state;
+	acpi_integer		present_rate;
+	acpi_integer		remaining_capacity;
+	acpi_integer		present_voltage;
+};
+
+struct acpi_battery_info {
+	acpi_integer		power_unit;
+	acpi_integer		design_capacity;
+	acpi_integer		last_full_capacity;
+	acpi_integer		battery_technology;
+	acpi_integer		design_voltage;
+	acpi_integer		design_capacity_warning;
+	acpi_integer		design_capacity_low;
+	acpi_integer		battery_capacity_granularity_1;
+	acpi_integer		battery_capacity_granularity_2;
+	acpi_string		model_number;
+	acpi_string		serial_number;
+	acpi_string		battery_type;
+	acpi_string		oem_info;
+};
+
+struct acpi_battery_flags {
+	u8			present:1;	/* Bay occupied? */
+	u8			power_unit:1;	/* 0=watts, 1=apms */
+	u8			alarm:1;	/* _BTP present? */
+	u8			reserved:5;
+};
+
+struct acpi_battery_trips {
+	unsigned long		warning;
+	unsigned long		low;
+};
+
+struct acpi_battery {
+	acpi_handle		handle;
+	struct acpi_battery_flags flags;
+	struct acpi_battery_trips trips;
+	unsigned long		alarm;
+	struct acpi_battery_info *info;
+};
+
+
+/* --------------------------------------------------------------------------
+                               Battery Management
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_battery_get_info (
+	struct acpi_battery	*battery,
+	struct acpi_battery_info **bif)
+{
+	int			result = 0;
+	acpi_status 		status = 0;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_buffer	format = {sizeof(ACPI_BATTERY_FORMAT_BIF),
+						ACPI_BATTERY_FORMAT_BIF};
+	struct acpi_buffer	data = {0, NULL};
+	union acpi_object	*package = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_get_info");
+
+	if (!battery || !bif)
+		return_VALUE(-EINVAL);
+
+	/* Evalute _BIF */
+
+	status = acpi_evaluate_object(battery->handle, "_BIF", NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BIF\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	package = (union acpi_object *) buffer.pointer;
+
+	/* Extract Package Data */
+
+	status = acpi_extract_package(package, &format, &data);
+	if (status != AE_BUFFER_OVERFLOW) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BIF\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	data.pointer = kmalloc(data.length, GFP_KERNEL);
+	if (!data.pointer) {
+		result = -ENOMEM;
+		goto end;
+	}
+	memset(data.pointer, 0, data.length);
+
+	status = acpi_extract_package(package, &format, &data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BIF\n"));
+		kfree(data.pointer);
+		result = -ENODEV;
+		goto end;
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	if (!result)
+		(*bif) = (struct acpi_battery_info *) data.pointer;
+
+	return_VALUE(result);
+}
+
+static int
+acpi_battery_get_status (
+	struct acpi_battery	*battery,
+	struct acpi_battery_status **bst)
+{
+	int			result = 0;
+	acpi_status 		status = 0;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_buffer	format = {sizeof(ACPI_BATTERY_FORMAT_BST),
+						ACPI_BATTERY_FORMAT_BST};
+	struct acpi_buffer	data = {0, NULL};
+	union acpi_object	*package = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_get_status");
+
+	if (!battery || !bst)
+		return_VALUE(-EINVAL);
+
+	/* Evalute _BST */
+
+	status = acpi_evaluate_object(battery->handle, "_BST", NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BST\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	package = (union acpi_object *) buffer.pointer;
+
+	/* Extract Package Data */
+
+	status = acpi_extract_package(package, &format, &data);
+	if (status != AE_BUFFER_OVERFLOW) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	data.pointer = kmalloc(data.length, GFP_KERNEL);
+	if (!data.pointer) {
+		result = -ENOMEM;
+		goto end;
+	}
+	memset(data.pointer, 0, data.length);
+
+	status = acpi_extract_package(package, &format, &data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n"));
+		kfree(data.pointer);
+		result = -ENODEV;
+		goto end;
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	if (!result)
+		(*bst) = (struct acpi_battery_status *) data.pointer;
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_battery_set_alarm (
+	struct acpi_battery	*battery,
+	unsigned long		alarm)
+{
+	acpi_status		status = 0;
+	union acpi_object	arg0 = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	arg_list = {1, &arg0};
+
+	ACPI_FUNCTION_TRACE("acpi_battery_set_alarm");
+
+	if (!battery)
+		return_VALUE(-EINVAL);
+
+	if (!battery->flags.alarm)
+		return_VALUE(-ENODEV);
+
+	arg0.integer.value = alarm;
+
+	status = acpi_evaluate_object(battery->handle, "_BTP", &arg_list, NULL);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
+
+	battery->alarm = alarm;
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_battery_check (
+	struct acpi_battery	*battery)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	acpi_handle		handle = NULL;
+	struct acpi_device	*device = NULL;
+	struct acpi_battery_info *bif = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_check");
+	
+	if (!battery)
+		return_VALUE(-EINVAL);
+
+	result = acpi_bus_get_device(battery->handle, &device);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_bus_get_status(device);
+	if (result)
+		return_VALUE(result);
+
+	/* Insertion? */
+
+	if (!battery->flags.present && device->status.battery_present) {
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n"));
+
+		/* Evalute _BIF to get certain static information */
+
+		result = acpi_battery_get_info(battery, &bif);
+		if (result)
+			return_VALUE(result);
+
+		battery->flags.power_unit = bif->power_unit;
+		battery->trips.warning = bif->design_capacity_warning;
+		battery->trips.low = bif->design_capacity_low;
+		kfree(bif);
+
+		/* See if alarms are supported, and if so, set default */
+
+		status = acpi_get_handle(battery->handle, "_BTP", &handle);
+		if (ACPI_SUCCESS(status)) {
+			battery->flags.alarm = 1;
+			acpi_battery_set_alarm(battery, battery->trips.warning);
+		}
+	}
+
+	/* Removal? */
+
+	else if (battery->flags.present && !device->status.battery_present) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n"));
+	}
+
+	battery->flags.present = device->status.battery_present;
+
+	return_VALUE(result);
+}
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_battery_dir;
+static int acpi_battery_read_info(struct seq_file *seq, void *offset)
+{
+	int			result = 0;
+	struct acpi_battery	*battery = (struct acpi_battery *) seq->private;
+	struct acpi_battery_info *bif = NULL;
+	char			*units = "?";
+
+	ACPI_FUNCTION_TRACE("acpi_battery_read_info");
+
+	if (!battery)
+		goto end;
+
+	if (battery->flags.present)
+		seq_printf(seq, "present:                 yes\n");
+	else {
+		seq_printf(seq, "present:                 no\n");
+		goto end;
+	}
+
+	/* Battery Info (_BIF) */
+
+	result = acpi_battery_get_info(battery, &bif);
+	if (result || !bif) {
+		seq_printf(seq, "ERROR: Unable to read battery information\n");
+		goto end;
+	}
+
+	units = bif->power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
+					
+	if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+		seq_printf(seq, "design capacity:         unknown\n");
+	else
+		seq_printf(seq, "design capacity:         %d %sh\n",
+			(u32) bif->design_capacity, units);
+
+	if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+		seq_printf(seq, "last full capacity:      unknown\n");
+	else
+		seq_printf(seq, "last full capacity:      %d %sh\n",
+			(u32) bif->last_full_capacity, units);
+
+	switch ((u32) bif->battery_technology) {
+	case 0:
+		seq_printf(seq, "battery technology:      non-rechargeable\n");
+		break;
+	case 1:
+		seq_printf(seq, "battery technology:      rechargeable\n");
+		break;
+	default:
+		seq_printf(seq, "battery technology:      unknown\n");
+		break;
+	}
+
+	if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+		seq_printf(seq, "design voltage:          unknown\n");
+	else
+		seq_printf(seq, "design voltage:          %d mV\n",
+			(u32) bif->design_voltage);
+	
+	seq_printf(seq, "design capacity warning: %d %sh\n",
+		(u32) bif->design_capacity_warning, units);
+	seq_printf(seq, "design capacity low:     %d %sh\n",
+		(u32) bif->design_capacity_low, units);
+	seq_printf(seq, "capacity granularity 1:  %d %sh\n",
+		(u32) bif->battery_capacity_granularity_1, units);
+	seq_printf(seq, "capacity granularity 2:  %d %sh\n",
+		(u32) bif->battery_capacity_granularity_2, units);
+	seq_printf(seq, "model number:            %s\n",
+		bif->model_number);
+	seq_printf(seq, "serial number:           %s\n",
+		bif->serial_number);
+	seq_printf(seq, "battery type:            %s\n",
+		bif->battery_type);
+	seq_printf(seq, "OEM info:                %s\n",
+		bif->oem_info);
+
+end:
+	kfree(bif);
+
+	return_VALUE(0);
+}
+
+static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_battery_read_info, PDE(inode)->data);
+}
+
+
+static int
+acpi_battery_read_state (struct seq_file *seq, void *offset)
+{
+	int			result = 0;
+	struct acpi_battery	*battery = (struct acpi_battery *) seq->private;
+	struct acpi_battery_status *bst = NULL;
+	char			*units = "?";
+
+	ACPI_FUNCTION_TRACE("acpi_battery_read_state");
+
+	if (!battery)
+		goto end;
+
+	if (battery->flags.present)
+		seq_printf(seq, "present:                 yes\n");
+	else {
+		seq_printf(seq, "present:                 no\n");
+		goto end;
+	}
+
+	/* Battery Units */
+
+	units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
+
+	/* Battery Status (_BST) */
+
+	result = acpi_battery_get_status(battery, &bst);
+	if (result || !bst) {
+		seq_printf(seq, "ERROR: Unable to read battery status\n");
+		goto end;
+	}
+
+	if (!(bst->state & 0x04))
+		seq_printf(seq, "capacity state:          ok\n");
+	else
+		seq_printf(seq, "capacity state:          critical\n");
+
+	if ((bst->state & 0x01) && (bst->state & 0x02)){
+		seq_printf(seq, "charging state:          charging/discharging\n");
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Battery Charging and Discharging?\n"));
+	}
+	else if (bst->state & 0x01)
+		seq_printf(seq, "charging state:          discharging\n");
+	else if (bst->state & 0x02)
+		seq_printf(seq, "charging state:          charging\n");
+	else {
+		seq_printf(seq, "charging state:          charged\n");
+	}
+
+	if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
+		seq_printf(seq, "present rate:            unknown\n");
+	else
+		seq_printf(seq, "present rate:            %d %s\n",
+			(u32) bst->present_rate, units);
+
+	if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+		seq_printf(seq, "remaining capacity:      unknown\n");
+	else
+		seq_printf(seq, "remaining capacity:      %d %sh\n",
+			(u32) bst->remaining_capacity, units);
+
+	if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+		seq_printf(seq, "present voltage:         unknown\n");
+	else
+		seq_printf(seq, "present voltage:         %d mV\n",
+			(u32) bst->present_voltage);
+
+end:
+	kfree(bst);
+
+	return_VALUE(0);
+}
+
+static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_battery_read_state, PDE(inode)->data);
+}
+
+
+static int
+acpi_battery_read_alarm (struct seq_file *seq, void *offset)
+{
+	struct acpi_battery	*battery = (struct acpi_battery *) seq->private;
+	char			*units = "?";
+
+	ACPI_FUNCTION_TRACE("acpi_battery_read_alarm");
+
+	if (!battery)
+		goto end;
+
+	if (!battery->flags.present) {
+		seq_printf(seq, "present:                 no\n");
+		goto end;
+	}
+
+	/* Battery Units */
+	
+	units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
+
+	/* Battery Alarm */
+
+	seq_printf(seq, "alarm:                   ");
+	if (!battery->alarm)
+		seq_printf(seq, "unsupported\n");
+	else
+		seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units);
+
+end:
+	return_VALUE(0);
+}
+
+
+static ssize_t
+acpi_battery_write_alarm (
+	struct file	*file,
+	const char	__user *buffer,
+	size_t		count,
+	loff_t		*ppos)
+{
+	int			result = 0;
+	char			alarm_string[12] = {'\0'};
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_battery	*battery = (struct acpi_battery *)m->private;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_write_alarm");
+
+	if (!battery || (count > sizeof(alarm_string) - 1))
+		return_VALUE(-EINVAL);
+
+	if (!battery->flags.present)
+		return_VALUE(-ENODEV);
+
+	if (copy_from_user(alarm_string, buffer, count))
+		return_VALUE(-EFAULT);
+	
+	alarm_string[count] = '\0';
+
+	result = acpi_battery_set_alarm(battery, 
+		simple_strtoul(alarm_string, NULL, 0));
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(count);
+}
+
+static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
+}
+
+static struct file_operations acpi_battery_info_ops = {
+	.open		= acpi_battery_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner = THIS_MODULE,
+};
+
+static struct file_operations acpi_battery_state_ops = {
+	.open		= acpi_battery_state_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner = THIS_MODULE,
+};
+
+static struct file_operations acpi_battery_alarm_ops = {
+	.open		= acpi_battery_alarm_open_fs,
+	.read		= seq_read,
+	.write		= acpi_battery_write_alarm,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner = THIS_MODULE,
+};
+
+static int
+acpi_battery_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_add_fs");
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_battery_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
+	}
+
+	/* 'info' [R] */
+	entry = create_proc_entry(ACPI_BATTERY_FILE_INFO,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_BATTERY_FILE_INFO));
+	else {
+		entry->proc_fops = &acpi_battery_info_ops; 
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'status' [R] */
+	entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_BATTERY_FILE_STATUS));
+	else {
+		entry->proc_fops = &acpi_battery_state_ops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'alarm' [R/W] */
+	entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_BATTERY_FILE_ALARM));
+	else {
+		entry->proc_fops = &acpi_battery_alarm_ops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_battery_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_battery_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_BATTERY_FILE_ALARM,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_BATTERY_FILE_STATUS,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_BATTERY_FILE_INFO,
+				  acpi_device_dir(device));
+
+		remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+static void
+acpi_battery_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_battery	*battery = (struct acpi_battery *) data;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_notify");
+
+	if (!battery)
+		return_VOID;
+
+	if (acpi_bus_get_device(handle, &device))
+		return_VOID;
+
+	switch (event) {
+	case ACPI_BATTERY_NOTIFY_STATUS:
+	case ACPI_BATTERY_NOTIFY_INFO:
+		acpi_battery_check(battery);
+		acpi_bus_generate_event(device, event, battery->flags.present);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+
+static int
+acpi_battery_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = 0;
+	struct acpi_battery	*battery = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_add");
+	
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL);
+	if (!battery)
+		return_VALUE(-ENOMEM);
+	memset(battery, 0, sizeof(struct acpi_battery));
+
+	battery->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
+	acpi_driver_data(device) = battery;
+
+	result = acpi_battery_check(battery);
+	if (result)
+		goto end;
+
+	result = acpi_battery_add_fs(device);
+	if (result)
+		goto end;
+
+	status = acpi_install_notify_handler(battery->handle,
+		ACPI_DEVICE_NOTIFY, acpi_battery_notify, battery);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing notify handler\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
+		ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
+		device->status.battery_present?"present":"absent");
+		
+end:
+	if (result) {
+		acpi_battery_remove_fs(device);
+		kfree(battery);
+	}
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_battery_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	acpi_status		status = 0;
+	struct acpi_battery	*battery = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	battery = (struct acpi_battery *) acpi_driver_data(device);
+
+	status = acpi_remove_notify_handler(battery->handle,
+		ACPI_DEVICE_NOTIFY, acpi_battery_notify);
+	if (ACPI_FAILURE(status))
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error removing notify handler\n"));
+
+	acpi_battery_remove_fs(device);
+
+	kfree(battery);
+
+	return_VALUE(0);
+}
+
+
+static int __init
+acpi_battery_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_battery_init");
+
+	acpi_battery_dir = proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir);
+	if (!acpi_battery_dir)
+		return_VALUE(-ENODEV);
+	acpi_battery_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_battery_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+
+static void __exit
+acpi_battery_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_battery_exit");
+
+	acpi_bus_unregister_driver(&acpi_battery_driver);
+
+	remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+
+module_init(acpi_battery_init);
+module_exit(acpi_battery_exit);
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
new file mode 100644
index 0000000..4c010e7
--- /dev/null
+++ b/drivers/acpi/blacklist.c
@@ -0,0 +1,169 @@
+/*
+ *  blacklist.c
+ *
+ *  Check to see if the given machine has a known bad ACPI BIOS
+ *  or if the BIOS is too old.
+ *
+ *  Copyright (C) 2004 Len Brown <len.brown@intel.com>
+ *  Copyright (C) 2002 Andy Grover <andrew.grover@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <linux/dmi.h>
+
+enum acpi_blacklist_predicates
+{
+        all_versions,
+        less_than_or_equal,
+        equal,
+        greater_than_or_equal,
+};
+
+struct acpi_blacklist_item
+{
+        char            oem_id[7];
+        char            oem_table_id[9];
+        u32             oem_revision;
+        acpi_table_type table;
+        enum acpi_blacklist_predicates oem_revision_predicate;
+        char            *reason;
+        u32             is_critical_error;
+};
+
+/*
+ * POLICY: If *anything* doesn't work, put it on the blacklist.
+ *	   If they are critical errors, mark it critical, and abort driver load.
+ */
+static struct acpi_blacklist_item acpi_blacklist[] __initdata =
+{
+	/* Compaq Presario 1700 */
+	{"PTLTD ", "  DSDT  ", 0x06040000, ACPI_DSDT, less_than_or_equal, "Multiple problems", 1},
+	/* Sony FX120, FX140, FX150? */
+	{"SONY  ", "U0      ", 0x20010313, ACPI_DSDT, less_than_or_equal, "ACPI driver problem", 1},
+	/* Compaq Presario 800, Insyde BIOS */
+	{"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal, "Does not use _REG to protect EC OpRegions", 1},
+	/* IBM 600E - _ADR should return 7, but it returns 1 */
+	{"IBM   ", "TP600E  ", 0x00000105, ACPI_DSDT, less_than_or_equal, "Incorrect _ADR", 1},
+	{"ASUS\0\0", "P2B-S   ", 0, ACPI_DSDT, all_versions, "Bogus PCI routing", 1},
+
+	{""}
+};
+
+
+#if	CONFIG_ACPI_BLACKLIST_YEAR
+
+static int __init
+blacklist_by_year(void)
+{
+	int year;
+	char *s = dmi_get_system_info(DMI_BIOS_DATE);
+
+	if (!s)
+		return 0;
+	if (!*s)
+		return 0;
+
+	s = strrchr(s, '/');
+	if (!s)
+		return 0;
+
+	s += 1;
+
+	year = simple_strtoul(s,NULL,0); 
+
+	if (year < 100) {		/* 2-digit year */
+		year += 1900;
+		if (year < 1996)	/* no dates < spec 1.0 */
+			year += 100;
+	}
+
+	if (year < CONFIG_ACPI_BLACKLIST_YEAR) {
+		printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), " 
+			"acpi=force is required to enable ACPI\n",
+			year, CONFIG_ACPI_BLACKLIST_YEAR);
+		return 1;
+	}
+	return 0;
+}
+#else
+static inline int blacklist_by_year(void) { return 0; }
+#endif
+
+int __init
+acpi_blacklisted(void)
+{
+	int i = 0;
+	int blacklisted = 0;
+	struct acpi_table_header *table_header;
+
+	while (acpi_blacklist[i].oem_id[0] != '\0')
+	{
+		if (acpi_get_table_header_early(acpi_blacklist[i].table, &table_header)) {
+			i++;
+			continue;
+		}
+
+		if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) {
+			i++;
+			continue;
+		}
+
+		if (strncmp(acpi_blacklist[i].oem_table_id, table_header->oem_table_id, 8)) {
+			i++;
+			continue;
+		}
+
+		if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
+		    || (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal
+		        && table_header->oem_revision <= acpi_blacklist[i].oem_revision)
+		    || (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal
+		        && table_header->oem_revision >= acpi_blacklist[i].oem_revision)
+		    || (acpi_blacklist[i].oem_revision_predicate == equal
+		        && table_header->oem_revision == acpi_blacklist[i].oem_revision)) {
+
+			printk(KERN_ERR PREFIX "Vendor \"%6.6s\" System \"%8.8s\" "
+				"Revision 0x%x has a known ACPI BIOS problem.\n",
+				acpi_blacklist[i].oem_id,
+				acpi_blacklist[i].oem_table_id,
+				acpi_blacklist[i].oem_revision);
+
+			printk(KERN_ERR PREFIX "Reason: %s. This is a %s error\n",
+				acpi_blacklist[i].reason,
+				(acpi_blacklist[i].is_critical_error ? "non-recoverable" : "recoverable"));
+
+			blacklisted = acpi_blacklist[i].is_critical_error;
+			break;
+		}
+		else {
+			i++;
+		}
+	}
+
+	blacklisted += blacklist_by_year();
+
+	return blacklisted;
+}
+
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
new file mode 100644
index 0000000..4edff17
--- /dev/null
+++ b/drivers/acpi/bus.c
@@ -0,0 +1,775 @@
+/*
+ *  acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
+ *
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/proc_fs.h>
+#ifdef CONFIG_X86
+#include <asm/mpspec.h>
+#endif
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_BUS_COMPONENT
+ACPI_MODULE_NAME		("acpi_bus")
+
+#ifdef	CONFIG_X86
+extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
+#endif
+
+FADT_DESCRIPTOR			acpi_fadt;
+EXPORT_SYMBOL(acpi_fadt);
+
+struct acpi_device		*acpi_root;
+struct proc_dir_entry		*acpi_root_dir;
+EXPORT_SYMBOL(acpi_root_dir);
+
+#define STRUCT_TO_INT(s)	(*((int*)&s))
+
+/* --------------------------------------------------------------------------
+                                Device Management
+   -------------------------------------------------------------------------- */
+
+int
+acpi_bus_get_device (
+	acpi_handle		handle,
+	struct acpi_device	**device)
+{
+	acpi_status		status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_get_device");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	/* TBD: Support fixed-feature devices */
+
+	status = acpi_get_data(handle, acpi_bus_data_handler, (void**) device);
+	if (ACPI_FAILURE(status) || !*device) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "No context for object [%p]\n",
+			handle));
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_bus_get_device);
+
+int
+acpi_bus_get_status (
+	struct acpi_device	*device)
+{
+	acpi_status		status = AE_OK;
+	unsigned long		sta = 0;
+	
+	ACPI_FUNCTION_TRACE("acpi_bus_get_status");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * Evaluate _STA if present.
+	 */
+	if (device->flags.dynamic_status) {
+		status = acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
+		if (ACPI_FAILURE(status))
+			return_VALUE(-ENODEV);
+		STRUCT_TO_INT(device->status) = (int) sta;
+	}
+
+	/*
+	 * Otherwise we assume the status of our parent (unless we don't
+	 * have one, in which case status is implied).
+	 */
+	else if (device->parent)
+		device->status = device->parent->status;
+	else
+		STRUCT_TO_INT(device->status) = 0x0F;
+
+	if (device->status.functional && !device->status.present) {
+		printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
+			"functional but not present; setting present\n",
+			device->pnp.bus_id,
+			(u32) STRUCT_TO_INT(device->status));
+		device->status.present = 1;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", 
+		device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)));
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_bus_get_status);
+
+
+/* --------------------------------------------------------------------------
+                                 Power Management
+   -------------------------------------------------------------------------- */
+
+int
+acpi_bus_get_power (
+	acpi_handle		handle,
+	int			*state)
+{
+	int			result = 0;
+	acpi_status             status = 0;
+	struct acpi_device	*device = NULL;
+	unsigned long		psc = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_get_power");
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result)
+		return_VALUE(result);
+
+	*state = ACPI_STATE_UNKNOWN;
+
+	if (!device->flags.power_manageable) {
+		/* TBD: Non-recursive algorithm for walking up hierarchy */
+		if (device->parent)
+			*state = device->parent->power.state;
+		else
+			*state = ACPI_STATE_D0;
+	}
+	else {
+		/*
+		 * Get the device's power state either directly (via _PSC) or 
+		 * indirectly (via power resources).
+		 */
+		if (device->power.flags.explicit_get) {
+			status = acpi_evaluate_integer(device->handle, "_PSC", 
+				NULL, &psc);
+			if (ACPI_FAILURE(status))
+				return_VALUE(-ENODEV);
+			device->power.state = (int) psc;
+		}
+		else if (device->power.flags.power_resources) {
+			result = acpi_power_get_inferred_state(device);
+			if (result)
+				return_VALUE(result);
+		}
+
+		*state = device->power.state;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
+		device->pnp.bus_id, device->power.state));
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_bus_get_power);
+
+
+int
+acpi_bus_set_power (
+	acpi_handle		handle,
+	int			state)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_device	*device = NULL;
+	char			object_name[5] = {'_','P','S','0'+state,'\0'};
+
+	ACPI_FUNCTION_TRACE("acpi_bus_set_power");
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result)
+		return_VALUE(result);
+
+	if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
+		return_VALUE(-EINVAL);
+
+	/* Make sure this is a valid target state */
+
+	if (!device->flags.power_manageable) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n"));
+		return_VALUE(-ENODEV);
+	}
+	if (state == device->power.state) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state));
+		return_VALUE(0);
+	}
+	if (!device->power.states[state].flags.valid) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", state));
+		return_VALUE(-ENODEV);
+	}
+	if (device->parent && (state < device->parent->power.state)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Cannot set device to a higher-powered state than parent\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	/*
+	 * Transition Power
+	 * ----------------
+	 * On transitions to a high-powered state we first apply power (via
+	 * power resources) then evalute _PSx.  Conversly for transitions to
+	 * a lower-powered state.
+	 */ 
+	if (state < device->power.state) {
+		if (device->power.flags.power_resources) {
+			result = acpi_power_transition(device, state);
+			if (result)
+				goto end;
+		}
+		if (device->power.states[state].flags.explicit_set) {
+			status = acpi_evaluate_object(device->handle, 
+				object_name, NULL, NULL);
+			if (ACPI_FAILURE(status)) {
+				result = -ENODEV;
+				goto end;
+			}
+		}
+	}
+	else {
+		if (device->power.states[state].flags.explicit_set) {
+			status = acpi_evaluate_object(device->handle, 
+				object_name, NULL, NULL);
+			if (ACPI_FAILURE(status)) {
+				result = -ENODEV;
+				goto end;
+			}
+		}
+		if (device->power.flags.power_resources) {
+			result = acpi_power_transition(device, state);
+			if (result)
+				goto end;
+		}
+	}
+
+end:
+	if (result)
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error transitioning device [%s] to D%d\n",
+			device->pnp.bus_id, state));
+	else
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n",
+			device->pnp.bus_id, state));
+
+	return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_set_power);
+
+
+
+/* --------------------------------------------------------------------------
+                                Event Management
+   -------------------------------------------------------------------------- */
+
+static DEFINE_SPINLOCK(acpi_bus_event_lock);
+
+LIST_HEAD(acpi_bus_event_list);
+DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
+
+extern int			event_is_open;
+
+int
+acpi_bus_generate_event (
+	struct acpi_device	*device,
+	u8			type,
+	int			data)
+{
+	struct acpi_bus_event	*event = NULL;
+	unsigned long		flags = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_generate_event");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	/* drop event on the floor if no one's listening */
+	if (!event_is_open)
+		return_VALUE(0);
+
+	event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
+	if (!event)
+		return_VALUE(-ENOMEM);
+
+	strcpy(event->device_class, device->pnp.device_class);
+	strcpy(event->bus_id, device->pnp.bus_id);
+	event->type = type;
+	event->data = data;
+
+	spin_lock_irqsave(&acpi_bus_event_lock, flags);
+	list_add_tail(&event->node, &acpi_bus_event_list);
+	spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
+
+	wake_up_interruptible(&acpi_bus_event_queue);
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_bus_generate_event);
+
+int
+acpi_bus_receive_event (
+	struct acpi_bus_event	*event)
+{
+	unsigned long		flags = 0;
+	struct acpi_bus_event	*entry = NULL;
+
+	DECLARE_WAITQUEUE(wait, current);
+
+	ACPI_FUNCTION_TRACE("acpi_bus_receive_event");
+
+	if (!event)
+		return_VALUE(-EINVAL);
+
+	if (list_empty(&acpi_bus_event_list)) {
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&acpi_bus_event_queue, &wait);
+
+		if (list_empty(&acpi_bus_event_list))
+			schedule();
+
+		remove_wait_queue(&acpi_bus_event_queue, &wait);
+		set_current_state(TASK_RUNNING);
+
+		if (signal_pending(current))
+			return_VALUE(-ERESTARTSYS);
+	}
+
+	spin_lock_irqsave(&acpi_bus_event_lock, flags);
+	entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
+	if (entry)
+		list_del(&entry->node);
+	spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
+
+	if (!entry)
+		return_VALUE(-ENODEV);
+
+	memcpy(event, entry, sizeof(struct acpi_bus_event));
+
+	kfree(entry);
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_bus_receive_event);
+
+
+/* --------------------------------------------------------------------------
+                             Notification Handling
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_bus_check_device (
+	struct acpi_device	*device,
+	int			*status_changed)
+{
+	acpi_status             status = 0;
+	struct acpi_device_status old_status;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_check_device");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	if (status_changed)
+		*status_changed = 0;
+
+	old_status = device->status;
+
+	/*
+	 * Make sure this device's parent is present before we go about
+	 * messing with the device.
+	 */
+	if (device->parent && !device->parent->status.present) {
+		device->status = device->parent->status;
+		if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) {
+			if (status_changed)
+				*status_changed = 1;
+		}
+		return_VALUE(0);
+	}
+
+	status = acpi_bus_get_status(device);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
+		return_VALUE(0);
+
+	if (status_changed)
+		*status_changed = 1;
+	
+	/*
+	 * Device Insertion/Removal
+	 */
+	if ((device->status.present) && !(old_status.present)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
+		/* TBD: Handle device insertion */
+	}
+	else if (!(device->status.present) && (old_status.present)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
+		/* TBD: Handle device removal */
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_bus_check_scope (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	int			status_changed = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_check_scope");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	/* Status Change? */
+	result = acpi_bus_check_device(device, &status_changed);
+	if (result)
+		return_VALUE(result);
+
+	if (!status_changed)
+		return_VALUE(0);
+
+	/*
+	 * TBD: Enumerate child devices within this device's scope and
+	 *       run acpi_bus_check_device()'s on them.
+	 */
+
+	return_VALUE(0);
+}
+
+
+/**
+ * acpi_bus_notify
+ * ---------------
+ * Callback for all 'system-level' device notifications (values 0x00-0x7F).
+ */
+static void 
+acpi_bus_notify (
+	acpi_handle             handle,
+	u32                     type,
+	void                    *data)
+{
+	int			result = 0;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_notify");
+
+	if (acpi_bus_get_device(handle, &device))
+		return_VOID;
+
+	switch (type) {
+
+	case ACPI_NOTIFY_BUS_CHECK:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS CHECK notification for device [%s]\n", 
+			device->pnp.bus_id));
+		result = acpi_bus_check_scope(device);
+		/* 
+		 * TBD: We'll need to outsource certain events to non-ACPI
+		 *	drivers via the device manager (device.c).
+		 */
+		break;
+
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK notification for device [%s]\n", 
+			device->pnp.bus_id));
+		result = acpi_bus_check_device(device, NULL);
+		/* 
+		 * TBD: We'll need to outsource certain events to non-ACPI
+		 *	drivers via the device manager (device.c).
+		 */
+		break;
+
+	case ACPI_NOTIFY_DEVICE_WAKE:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE WAKE notification for device [%s]\n", 
+			device->pnp.bus_id));
+		/* TBD */
+		break;
+
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received EJECT REQUEST notification for device [%s]\n", 
+			device->pnp.bus_id));
+		/* TBD */
+		break;
+
+	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK LIGHT notification for device [%s]\n", 
+			device->pnp.bus_id));
+		/* TBD: Exactly what does 'light' mean? */
+		break;
+
+	case ACPI_NOTIFY_FREQUENCY_MISMATCH:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received FREQUENCY MISMATCH notification for device [%s]\n", 
+			device->pnp.bus_id));
+		/* TBD */
+		break;
+
+	case ACPI_NOTIFY_BUS_MODE_MISMATCH:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS MODE MISMATCH notification for device [%s]\n", 
+			device->pnp.bus_id));
+		/* TBD */
+		break;
+
+	case ACPI_NOTIFY_POWER_FAULT:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received POWER FAULT notification for device [%s]\n", 
+			device->pnp.bus_id));
+		/* TBD */
+		break;
+
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received unknown/unsupported notification [%08x]\n", 
+			type));
+		break;
+	}
+
+	return_VOID;
+}
+
+/* --------------------------------------------------------------------------
+                             Initialization/Cleanup
+   -------------------------------------------------------------------------- */
+
+static int __init
+acpi_bus_init_irq (void)
+{
+	acpi_status		status = AE_OK;
+	union acpi_object	arg = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	arg_list = {1, &arg};
+	char			*message = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_init_irq");
+
+	/* 
+	 * Let the system know what interrupt model we are using by
+	 * evaluating the \_PIC object, if exists.
+	 */
+
+	switch (acpi_irq_model) {
+	case ACPI_IRQ_MODEL_PIC:
+		message = "PIC";
+		break;
+	case ACPI_IRQ_MODEL_IOAPIC:
+		message = "IOAPIC";
+		break;
+	case ACPI_IRQ_MODEL_IOSAPIC:
+		message = "IOSAPIC";
+		break;
+	default:
+		printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
+		return_VALUE(-ENODEV);
+	}
+
+	printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
+
+	arg.integer.value = acpi_irq_model;
+
+	status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PIC\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+
+void __init
+acpi_early_init (void)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_buffer	buffer = {sizeof(acpi_fadt), &acpi_fadt};
+
+	ACPI_FUNCTION_TRACE("acpi_early_init");
+
+	if (acpi_disabled)
+		return_VOID;
+
+	/* enable workarounds, unless strict ACPI spec. compliance */
+	if (!acpi_strict)
+		acpi_gbl_enable_interpreter_slack = TRUE;
+
+	status = acpi_initialize_subsystem();
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n");
+		goto error0;
+	}
+
+	status = acpi_load_tables();
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to load the System Description Tables\n");
+		goto error0;
+	}
+
+	/*
+	 * Get a separate copy of the FADT for use by other drivers.
+	 */
+	status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to get the FADT\n");
+		goto error0;
+	}
+
+#ifdef CONFIG_X86
+	if (!acpi_ioapic) {
+		extern acpi_interrupt_flags acpi_sci_flags;
+
+		/* compatible (0) means level (3) */
+		if (acpi_sci_flags.trigger == 0)
+			acpi_sci_flags.trigger = 3;
+
+		/* Set PIC-mode SCI trigger type */
+		acpi_pic_sci_set_trigger(acpi_fadt.sci_int, acpi_sci_flags.trigger);
+	} else {
+		extern int acpi_sci_override_gsi;
+		/*
+		 * now that acpi_fadt is initialized,
+		 * update it with result from INT_SRC_OVR parsing
+		 */
+		acpi_fadt.sci_int = acpi_sci_override_gsi;
+	}
+#endif
+
+	status = acpi_enable_subsystem(~(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE));
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
+		goto error0;
+	}
+
+	return_VOID;
+
+error0:
+	disable_acpi();
+	return_VOID;
+}
+
+static int __init
+acpi_bus_init (void)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	extern acpi_status	acpi_os_initialize1(void);
+
+	ACPI_FUNCTION_TRACE("acpi_bus_init");
+
+	status = acpi_os_initialize1();
+
+	status = acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n");
+		goto error1;
+	}
+
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to initialize ACPI OS objects\n");
+		goto error1;
+	}
+#ifdef CONFIG_ACPI_EC
+	/*
+	 * ACPI 2.0 requires the EC driver to be loaded and work before
+	 * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
+	 * is called).
+	 *
+	 * This is accomplished by looking for the ECDT table, and getting 
+	 * the EC parameters out of that.
+	 */
+	status = acpi_ec_ecdt_probe();
+	/* Ignore result. Not having an ECDT is not fatal. */
+#endif
+
+	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
+		goto error1;
+	}
+
+	printk(KERN_INFO PREFIX "Interpreter enabled\n");
+
+	/*
+	 * Get the system interrupt model and evaluate \_PIC.
+	 */
+	result = acpi_bus_init_irq();
+	if (result)
+		goto error1;
+
+	/*
+	 * Register the for all standard device notifications.
+	 */
+	status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to register for device notifications\n");
+		goto error1;
+	}
+
+	/*
+	 * Create the top ACPI proc directory
+	 */
+	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
+
+	return_VALUE(0);
+
+	/* Mimic structured exception handling */
+error1:
+	acpi_terminate();
+	return_VALUE(-ENODEV);
+}
+
+decl_subsys(acpi,NULL,NULL);
+
+static int __init acpi_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_init");
+
+	printk(KERN_INFO PREFIX "Subsystem revision %08x\n",
+		ACPI_CA_VERSION);
+
+	if (acpi_disabled) {
+		printk(KERN_INFO PREFIX "Interpreter disabled.\n");
+		return_VALUE(-ENODEV);
+	}
+
+	firmware_register(&acpi_subsys);
+
+	result = acpi_bus_init();
+
+	if (!result) {
+#ifdef CONFIG_PM
+		if (!PM_IS_ACTIVE())
+			pm_active = 1;
+		else {
+			printk(KERN_INFO PREFIX "APM is already active, exiting\n");
+			disable_acpi();
+			result = -ENODEV;
+		}
+#endif
+	} else
+		disable_acpi();
+
+	return_VALUE(result);
+}
+
+subsys_initcall(acpi_init);
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
new file mode 100644
index 0000000..ec4430e
--- /dev/null
+++ b/drivers/acpi/button.c
@@ -0,0 +1,558 @@
+/*
+ *  acpi_button.c - ACPI Button Driver ($Revision: 30 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define ACPI_BUTTON_COMPONENT		0x00080000
+#define ACPI_BUTTON_DRIVER_NAME		"ACPI Button Driver"
+#define ACPI_BUTTON_CLASS		"button"
+#define ACPI_BUTTON_FILE_INFO		"info"
+#define ACPI_BUTTON_FILE_STATE		"state"
+#define ACPI_BUTTON_TYPE_UNKNOWN	0x00
+#define ACPI_BUTTON_NOTIFY_STATUS	0x80
+
+#define ACPI_BUTTON_SUBCLASS_POWER	"power"
+#define ACPI_BUTTON_HID_POWER		"PNP0C0C"	
+#define ACPI_BUTTON_DEVICE_NAME_POWER	"Power Button (CM)"
+#define ACPI_BUTTON_DEVICE_NAME_POWERF	"Power Button (FF)"
+#define ACPI_BUTTON_TYPE_POWER		0x01
+#define ACPI_BUTTON_TYPE_POWERF		0x02
+
+#define ACPI_BUTTON_SUBCLASS_SLEEP	"sleep"
+#define ACPI_BUTTON_HID_SLEEP		"PNP0C0E"
+#define ACPI_BUTTON_DEVICE_NAME_SLEEP	"Sleep Button (CM)"
+#define ACPI_BUTTON_DEVICE_NAME_SLEEPF	"Sleep Button (FF)"
+#define ACPI_BUTTON_TYPE_SLEEP		0x03
+#define ACPI_BUTTON_TYPE_SLEEPF		0x04
+
+#define ACPI_BUTTON_SUBCLASS_LID	"lid"
+#define ACPI_BUTTON_HID_LID		"PNP0C0D"
+#define ACPI_BUTTON_DEVICE_NAME_LID	"Lid Switch"
+#define ACPI_BUTTON_TYPE_LID		0x05
+
+#define _COMPONENT		ACPI_BUTTON_COMPONENT
+ACPI_MODULE_NAME		("acpi_button")
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+
+static int acpi_button_add (struct acpi_device *device);
+static int acpi_button_remove (struct acpi_device *device, int type);
+static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
+static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
+
+static struct acpi_driver acpi_button_driver = {
+	.name =		ACPI_BUTTON_DRIVER_NAME,
+	.class =	ACPI_BUTTON_CLASS,
+	.ids =		"ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E",
+	.ops =		{
+				.add =		acpi_button_add,
+				.remove =	acpi_button_remove,
+			},
+};
+
+struct acpi_button {
+	acpi_handle		handle;
+	struct acpi_device	*device;	/* Fixed button kludge */
+	u8			type;
+	unsigned long		pushed;
+};
+
+static struct file_operations acpi_button_info_fops = {
+	.open		= acpi_button_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_button_state_fops = {
+	.open		= acpi_button_state_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_button_dir;
+
+static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_button	*button = (struct acpi_button *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_button_info_seq_show");
+
+	if (!button || !button->device)
+		return_VALUE(0);
+
+	seq_printf(seq, "type:                    %s\n", 
+		acpi_device_name(button->device));
+
+	return_VALUE(0);
+}
+
+static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
+}
+	
+static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_button	*button = (struct acpi_button *) seq->private;
+	acpi_status		status;
+	unsigned long		state;
+
+	ACPI_FUNCTION_TRACE("acpi_button_state_seq_show");
+
+	if (!button || !button->device)
+		return_VALUE(0);
+
+	status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state);
+	if (ACPI_FAILURE(status)) {
+		seq_printf(seq, "state:      unsupported\n");
+	}
+	else{
+		seq_printf(seq, "state:      %s\n", (state ? "open" : "closed")); 
+	}
+
+	return_VALUE(0);
+}
+
+static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_button_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_button	*button = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_button_add_fs");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	button = acpi_driver_data(device);
+
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWER:
+	case ACPI_BUTTON_TYPE_POWERF:
+			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 
+				acpi_button_dir);
+		break;
+	case ACPI_BUTTON_TYPE_SLEEP:
+	case ACPI_BUTTON_TYPE_SLEEPF:
+			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, 
+				acpi_button_dir);
+		break;
+	case ACPI_BUTTON_TYPE_LID:
+			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, 
+				acpi_button_dir);
+		break;
+	}
+
+	if (!entry)
+		return_VALUE(-ENODEV);
+	entry->owner = THIS_MODULE;
+
+	acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
+	if (!acpi_device_dir(device))
+		return_VALUE(-ENODEV);
+	acpi_device_dir(device)->owner = THIS_MODULE;
+
+	/* 'info' [R] */
+	entry = create_proc_entry(ACPI_BUTTON_FILE_INFO,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_BUTTON_FILE_INFO));
+	else {
+		entry->proc_fops = &acpi_button_info_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* show lid state [R] */
+	if (button->type == ACPI_BUTTON_TYPE_LID) {
+		entry = create_proc_entry(ACPI_BUTTON_FILE_STATE,
+			S_IRUGO, acpi_device_dir(device));
+		if (!entry)
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Unable to create '%s' fs entry\n",
+				ACPI_BUTTON_FILE_INFO));
+		else {
+			entry->proc_fops = &acpi_button_state_fops;
+			entry->data = acpi_driver_data(device);
+			entry->owner = THIS_MODULE;
+		}
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_button_remove_fs (
+	struct acpi_device	*device)
+{
+	struct acpi_button	*button = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_button_remove_fs");
+
+	button = acpi_driver_data(device);
+	if (acpi_device_dir(device)) {
+		if (button->type == ACPI_BUTTON_TYPE_LID)
+			remove_proc_entry(ACPI_BUTTON_FILE_STATE,
+					     acpi_device_dir(device));
+		remove_proc_entry(ACPI_BUTTON_FILE_INFO,
+				     acpi_device_dir(device));
+
+		remove_proc_entry(acpi_device_bid(device),
+				     acpi_device_dir(device)->parent);
+
+
+		switch (button->type) {
+			case ACPI_BUTTON_TYPE_POWER:
+			case ACPI_BUTTON_TYPE_POWERF:
+				remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, 
+					acpi_button_dir);
+				break;
+			case ACPI_BUTTON_TYPE_SLEEP:
+			case ACPI_BUTTON_TYPE_SLEEPF:
+				remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, 
+					acpi_button_dir);
+				break;
+			case ACPI_BUTTON_TYPE_LID:
+				remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, 
+					acpi_button_dir);
+				break;
+		}
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                                Driver Interface
+   -------------------------------------------------------------------------- */
+
+static void
+acpi_button_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_button	*button = (struct acpi_button *) data;
+
+	ACPI_FUNCTION_TRACE("acpi_button_notify");
+
+	if (!button || !button->device)
+		return_VOID;
+
+	switch (event) {
+	case ACPI_BUTTON_NOTIFY_STATUS:
+		acpi_bus_generate_event(button->device, event, ++button->pushed);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+
+static acpi_status
+acpi_button_notify_fixed (
+	void			*data)
+{
+	struct acpi_button	*button = (struct acpi_button *) data;
+	
+	ACPI_FUNCTION_TRACE("acpi_button_notify_fixed");
+
+	if (!button)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+static int
+acpi_button_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_button	*button = NULL;
+
+	static struct acpi_device *power_button;
+	static struct acpi_device *sleep_button;
+	static struct acpi_device *lid_button;
+
+	ACPI_FUNCTION_TRACE("acpi_button_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL);
+	if (!button)
+		return_VALUE(-ENOMEM);
+	memset(button, 0, sizeof(struct acpi_button));
+
+	button->device = device;
+	button->handle = device->handle;
+	acpi_driver_data(device) = button;
+
+	/*
+	 * Determine the button type (via hid), as fixed-feature buttons
+	 * need to be handled a bit differently than generic-space.
+	 */
+	if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) {
+		button->type = ACPI_BUTTON_TYPE_POWER;
+		strcpy(acpi_device_name(device),
+			ACPI_BUTTON_DEVICE_NAME_POWER);
+		sprintf(acpi_device_class(device), "%s/%s", 
+			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
+	}
+	else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) {
+		button->type = ACPI_BUTTON_TYPE_POWERF;
+		strcpy(acpi_device_name(device),
+			ACPI_BUTTON_DEVICE_NAME_POWERF);
+		sprintf(acpi_device_class(device), "%s/%s", 
+			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
+	}
+	else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) {
+		button->type = ACPI_BUTTON_TYPE_SLEEP;
+		strcpy(acpi_device_name(device),
+			ACPI_BUTTON_DEVICE_NAME_SLEEP);
+		sprintf(acpi_device_class(device), "%s/%s", 
+			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
+	}
+	else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) {
+		button->type = ACPI_BUTTON_TYPE_SLEEPF;
+		strcpy(acpi_device_name(device),
+			ACPI_BUTTON_DEVICE_NAME_SLEEPF);
+		sprintf(acpi_device_class(device), "%s/%s", 
+			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
+	}
+	else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) {
+		button->type = ACPI_BUTTON_TYPE_LID;
+		strcpy(acpi_device_name(device),
+			ACPI_BUTTON_DEVICE_NAME_LID);
+		sprintf(acpi_device_class(device), "%s/%s", 
+			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
+	}
+	else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported hid [%s]\n",
+			acpi_device_hid(device)));
+		result = -ENODEV;
+		goto end;
+	}
+
+	/*
+	 * Ensure only one button of each type is used.
+	 */
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWER:
+	case ACPI_BUTTON_TYPE_POWERF:
+		if (!power_button)
+			power_button = device;
+		else {
+			kfree(button);
+			return_VALUE(-ENODEV);
+		}
+		break;
+	case ACPI_BUTTON_TYPE_SLEEP:
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		if (!sleep_button)
+			sleep_button = device;
+		else {
+			kfree(button);
+			return_VALUE(-ENODEV);
+		}
+		break;
+	case ACPI_BUTTON_TYPE_LID:
+		if (!lid_button)
+			lid_button = device;
+		else {
+			kfree(button);
+			return_VALUE(-ENODEV);
+		}
+		break;
+	}
+
+	result = acpi_button_add_fs(device);
+	if (result)
+		goto end;
+
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWERF:
+		status = acpi_install_fixed_event_handler (
+			ACPI_EVENT_POWER_BUTTON,
+			acpi_button_notify_fixed,
+			button);
+		break;
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		status = acpi_install_fixed_event_handler (
+			ACPI_EVENT_SLEEP_BUTTON,
+			acpi_button_notify_fixed,
+			button);
+		break;
+	default:
+		status = acpi_install_notify_handler (
+			button->handle,
+			ACPI_DEVICE_NOTIFY,
+			acpi_button_notify,
+			button);
+		break;
+	}
+
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing notify handler\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	if (device->wakeup.flags.valid) {
+		/* Button's GPE is run-wake GPE */
+		acpi_set_gpe_type(device->wakeup.gpe_device, 
+			device->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
+		acpi_enable_gpe(device->wakeup.gpe_device, 
+			device->wakeup.gpe_number, ACPI_NOT_ISR);
+		device->wakeup.state.enabled = 1;
+	}
+
+	printk(KERN_INFO PREFIX "%s [%s]\n", 
+		acpi_device_name(device), acpi_device_bid(device));
+
+end:
+	if (result) {
+		acpi_button_remove_fs(device);
+		kfree(button);
+	}
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_button_remove (struct acpi_device *device, int type)
+{
+	acpi_status		status = 0;
+	struct acpi_button	*button = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_button_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	button = acpi_driver_data(device);
+
+	/* Unregister for device notifications. */
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWERF:
+		status = acpi_remove_fixed_event_handler(
+			ACPI_EVENT_POWER_BUTTON, acpi_button_notify_fixed);
+		break;
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		status = acpi_remove_fixed_event_handler(
+			ACPI_EVENT_SLEEP_BUTTON, acpi_button_notify_fixed);
+		break;
+	default:
+		status = acpi_remove_notify_handler(button->handle,
+			ACPI_DEVICE_NOTIFY, acpi_button_notify);
+		break;
+	}
+
+	if (ACPI_FAILURE(status))
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error removing notify handler\n"));
+
+	acpi_button_remove_fs(device);	
+
+	kfree(button);
+
+	return_VALUE(0);
+}
+
+
+static int __init
+acpi_button_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_button_init");
+
+	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
+	if (!acpi_button_dir)
+		return_VALUE(-ENODEV);
+	acpi_button_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_button_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+
+static void __exit
+acpi_button_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_button_exit");
+
+	acpi_bus_unregister_driver(&acpi_button_driver);
+
+	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+
+module_init(acpi_button_init);
+module_exit(acpi_button_exit);
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
new file mode 100644
index 0000000..5a0adbf
--- /dev/null
+++ b/drivers/acpi/container.c
@@ -0,0 +1,303 @@
+/*
+ * acpi_container.c  - ACPI Generic Container Driver
+ * ($Revision: )
+ *
+ * Copyright (C) 2004 Anil S Keshavamurthy (anil.s.keshavamurthy@intel.com)
+ * Copyright (C) 2004 Keiichiro Tokunaga (tokunaga.keiich@jp.fujitsu.com)
+ * Copyright (C) 2004 Motoyuki Ito (motoyuki@soft.fujitsu.com)
+ * Copyright (C) 2004 Intel Corp.
+ * Copyright (C) 2004 FUJITSU LIMITED
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/container.h>
+
+#define ACPI_CONTAINER_DRIVER_NAME	"ACPI container driver"
+#define ACPI_CONTAINER_DEVICE_NAME	"ACPI container device"
+#define ACPI_CONTAINER_CLASS		"container"
+
+#define INSTALL_NOTIFY_HANDLER		1
+#define UNINSTALL_NOTIFY_HANDLER	2
+
+#define ACPI_CONTAINER_COMPONENT	0x01000000
+#define _COMPONENT			ACPI_CONTAINER_COMPONENT
+ACPI_MODULE_NAME			("acpi_container")
+
+MODULE_AUTHOR("Anil S Keshavamurthy");
+MODULE_DESCRIPTION(ACPI_CONTAINER_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+#define ACPI_STA_PRESENT		(0x00000001)
+
+static int acpi_container_add(struct acpi_device *device);
+static int acpi_container_remove(struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_container_driver = {
+	.name =		ACPI_CONTAINER_DRIVER_NAME,
+	.class =	ACPI_CONTAINER_CLASS,
+	.ids =		"ACPI0004,PNP0A05,PNP0A06",
+	.ops =		{
+				.add =		acpi_container_add,
+				.remove =	acpi_container_remove,
+			},
+};
+
+
+/*******************************************************************/
+
+static int
+is_device_present(acpi_handle handle)
+{
+	acpi_handle		temp;
+	acpi_status		status;
+	unsigned long	sta;
+
+	ACPI_FUNCTION_TRACE("is_device_present");
+
+	status = acpi_get_handle(handle, "_STA", &temp);
+	if (ACPI_FAILURE(status))
+		return_VALUE(1); /* _STA not found, assmue device present */
+
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+	if (ACPI_FAILURE(status))
+		return_VALUE(0); /* Firmware error */
+
+	return_VALUE((sta & ACPI_STA_PRESENT) == ACPI_STA_PRESENT);
+}
+
+/*******************************************************************/
+static int
+acpi_container_add(struct acpi_device *device)
+{
+	struct acpi_container *container;
+
+	ACPI_FUNCTION_TRACE("acpi_container_add");
+
+	if (!device) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "device is NULL\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL);
+	if(!container)
+		return_VALUE(-ENOMEM);
+	
+	memset(container, 0, sizeof(struct acpi_container));
+	container->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
+	acpi_driver_data(device) = container;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",	\
+		acpi_device_name(device), acpi_device_bid(device)));
+
+
+	return_VALUE(0);
+}
+
+static int
+acpi_container_remove(struct acpi_device *device, int type)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_container	*pc = NULL;
+	pc = (struct acpi_container*) acpi_driver_data(device);
+
+	if (pc)
+		kfree(pc);
+
+	return status;
+}
+
+
+static int
+container_device_add(struct acpi_device **device, acpi_handle handle)
+{
+	acpi_handle phandle;
+	struct acpi_device *pdev;
+	int result;
+
+	ACPI_FUNCTION_TRACE("container_device_add");
+
+	if (acpi_get_parent(handle, &phandle)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_get_device(phandle, &pdev)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_DEVICE)) {
+		return_VALUE(-ENODEV);
+	}
+
+	result = acpi_bus_scan(*device);
+
+	return_VALUE(result);
+}
+
+static void
+container_notify_cb(acpi_handle handle, u32 type, void *context)
+{
+	struct acpi_device		*device = NULL;
+	int result;
+	int present;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("container_notify_cb");
+
+	present = is_device_present(handle);
+	
+	switch (type) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		/* Fall through */
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		printk("Container driver received %s event\n",
+			(type == ACPI_NOTIFY_BUS_CHECK)?
+			"ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+		status = acpi_bus_get_device(handle, &device);
+		if (present) {
+			if (ACPI_FAILURE(status) || !device) {
+				result = container_device_add(&device, handle);
+				if (!result)
+					kobject_hotplug(&device->kobj,
+							KOBJ_ONLINE);
+				else
+					printk("Failed to add container\n");
+			}
+		} else {
+			if (ACPI_SUCCESS(status)) {
+				/* device exist and this is a remove request */
+				kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+			}
+		}
+		break;
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		if (!acpi_bus_get_device(handle, &device) && device) {
+			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+		}
+		break;
+	default:
+		break;
+	}
+	return_VOID;
+}
+
+static acpi_status
+container_walk_namespace_cb(acpi_handle handle,
+	u32 lvl,
+	void *context,
+	void **rv)
+{
+	char 				*hid = NULL;
+	struct acpi_buffer 		buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_device_info 	*info;
+	acpi_status 			status;
+	int 				*action = context;
+
+	ACPI_FUNCTION_TRACE("container_walk_namespace_cb");
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_FAILURE(status) || !buffer.pointer) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	info = buffer.pointer;
+	if (info->valid & ACPI_VALID_HID)
+		hid = info->hardware_id.value;
+
+	if (hid == NULL) {
+		goto end;
+	}
+
+	if (strcmp(hid, "ACPI0004") && strcmp(hid, "PNP0A05") &&
+			strcmp(hid, "PNP0A06")) {
+		goto end;
+	}
+
+	switch(*action) {
+	case INSTALL_NOTIFY_HANDLER:
+		acpi_install_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			container_notify_cb,
+			NULL);
+		break;
+	case UNINSTALL_NOTIFY_HANDLER:
+		acpi_remove_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			container_notify_cb);
+		break;
+	default:
+		break;
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+
+static int __init
+acpi_container_init(void)
+{
+	int	result = 0;
+	int	action = INSTALL_NOTIFY_HANDLER;
+
+	result = acpi_bus_register_driver(&acpi_container_driver);
+	if (result < 0) {
+		return(result);
+	}
+
+	/* register notify handler to every container device */
+	acpi_walk_namespace(ACPI_TYPE_DEVICE,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     container_walk_namespace_cb,
+				     &action, NULL);
+
+	return(0);
+}
+
+static void __exit
+acpi_container_exit(void)
+{
+	int			action = UNINSTALL_NOTIFY_HANDLER;
+
+	ACPI_FUNCTION_TRACE("acpi_container_exit");
+
+	acpi_walk_namespace(ACPI_TYPE_DEVICE,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     container_walk_namespace_cb,
+				     &action, NULL);
+
+	acpi_bus_unregister_driver(&acpi_container_driver);
+
+	return_VOID;
+}
+
+module_init(acpi_container_init);
+module_exit(acpi_container_exit);
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
new file mode 100644
index 0000000..2c0dac5
--- /dev/null
+++ b/drivers/acpi/debug.c
@@ -0,0 +1,233 @@
+/*
+ * debug.c - ACPI debug interface to userspace.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <asm/uaccess.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acglobal.h>
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("debug")
+
+#define ACPI_SYSTEM_FILE_DEBUG_LAYER	"debug_layer"
+#define ACPI_SYSTEM_FILE_DEBUG_LEVEL	"debug_level"
+
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+
+#define MODULE_PARAM_PREFIX
+module_param(acpi_dbg_layer, uint, 0400);
+module_param(acpi_dbg_level, uint, 0400);
+
+struct acpi_dlayer {
+	const char *name;
+	unsigned long value;
+};
+struct acpi_dlevel {
+	const char *name;
+	unsigned long value;
+};
+#define ACPI_DEBUG_INIT(v)	{ .name = #v, .value = v }
+
+static const struct acpi_dlayer acpi_debug_layers[] =
+{
+	ACPI_DEBUG_INIT(ACPI_UTILITIES),
+	ACPI_DEBUG_INIT(ACPI_HARDWARE),
+	ACPI_DEBUG_INIT(ACPI_EVENTS),
+	ACPI_DEBUG_INIT(ACPI_TABLES),
+	ACPI_DEBUG_INIT(ACPI_NAMESPACE),
+	ACPI_DEBUG_INIT(ACPI_PARSER),
+	ACPI_DEBUG_INIT(ACPI_DISPATCHER),
+	ACPI_DEBUG_INIT(ACPI_EXECUTER),
+	ACPI_DEBUG_INIT(ACPI_RESOURCES),
+	ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER),
+	ACPI_DEBUG_INIT(ACPI_OS_SERVICES),
+	ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
+	ACPI_DEBUG_INIT(ACPI_COMPILER),
+	ACPI_DEBUG_INIT(ACPI_TOOLS),
+};
+
+static const struct acpi_dlevel acpi_debug_levels[] =
+{
+	ACPI_DEBUG_INIT(ACPI_LV_ERROR),
+	ACPI_DEBUG_INIT(ACPI_LV_WARN),
+	ACPI_DEBUG_INIT(ACPI_LV_INIT),
+	ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
+	ACPI_DEBUG_INIT(ACPI_LV_INFO),
+
+	ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
+	ACPI_DEBUG_INIT(ACPI_LV_PARSE),
+	ACPI_DEBUG_INIT(ACPI_LV_LOAD),
+	ACPI_DEBUG_INIT(ACPI_LV_DISPATCH),
+	ACPI_DEBUG_INIT(ACPI_LV_EXEC),
+	ACPI_DEBUG_INIT(ACPI_LV_NAMES),
+	ACPI_DEBUG_INIT(ACPI_LV_OPREGION),
+	ACPI_DEBUG_INIT(ACPI_LV_BFIELD),
+	ACPI_DEBUG_INIT(ACPI_LV_TABLES),
+	ACPI_DEBUG_INIT(ACPI_LV_VALUES),
+	ACPI_DEBUG_INIT(ACPI_LV_OBJECTS),
+	ACPI_DEBUG_INIT(ACPI_LV_RESOURCES),
+	ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS),
+	ACPI_DEBUG_INIT(ACPI_LV_PACKAGE),
+
+	ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS),
+	ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS),
+	ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS),
+
+	ACPI_DEBUG_INIT(ACPI_LV_MUTEX),
+	ACPI_DEBUG_INIT(ACPI_LV_THREADS),
+	ACPI_DEBUG_INIT(ACPI_LV_IO),
+	ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS),
+
+	ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
+	ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
+	ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
+	ACPI_DEBUG_INIT(ACPI_LV_EVENTS),             
+};
+
+static int
+acpi_system_read_debug (
+	char			*page,
+	char			**start,
+	off_t			off,
+	int 			count,
+	int 			*eof,
+	void			*data)
+{
+	char			*p = page;
+	int 			size = 0;
+	unsigned int		i;
+
+	if (off != 0)
+		goto end;
+
+	p += sprintf(p, "%-25s\tHex        SET\n", "Description");
+
+	switch ((unsigned long) data) {
+	case 0:
+		for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
+			p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
+				acpi_debug_layers[i].name,
+				acpi_debug_layers[i].value,
+				(acpi_dbg_layer & acpi_debug_layers[i].value) ?
+				'*' : ' ');
+		}
+		p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
+			ACPI_ALL_DRIVERS,
+			(acpi_dbg_layer & ACPI_ALL_DRIVERS) == ACPI_ALL_DRIVERS?
+			'*' : (acpi_dbg_layer & ACPI_ALL_DRIVERS) == 0 ?
+			' ' : '-');
+		p += sprintf(p,
+			"--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n",
+			acpi_dbg_layer);
+		break;
+	case 1:
+		for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
+			p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
+				acpi_debug_levels[i].name,
+				acpi_debug_levels[i].value,
+				(acpi_dbg_level & acpi_debug_levels[i].value) ?
+				'*' : ' ');
+		}
+		p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n",
+				acpi_dbg_level);
+		break;
+	default:
+		p += sprintf(p, "Invalid debug option\n");
+		break;
+	}
+	
+end:
+	size = (p - page);
+	if (size <= off+count) *eof = 1;
+	*start = page + off;
+	size -= off;
+	if (size>count) size = count;
+	if (size<0) size = 0;
+
+	return size;
+}
+
+
+static int
+acpi_system_write_debug (
+	struct file             *file,
+        const char              __user *buffer,
+	unsigned long           count,
+        void                    *data)
+{
+	char			debug_string[12] = {'\0'};
+
+	ACPI_FUNCTION_TRACE("acpi_system_write_debug");
+
+	if (count > sizeof(debug_string) - 1)
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(debug_string, buffer, count))
+		return_VALUE(-EFAULT);
+
+	debug_string[count] = '\0';
+
+	switch ((unsigned long) data) {
+	case 0:
+		acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0);
+		break;
+	case 1:
+		acpi_dbg_level = simple_strtoul(debug_string, NULL, 0);
+		break;
+	default:
+		return_VALUE(-EINVAL);
+	}
+
+	return_VALUE(count);
+}
+
+static int __init acpi_debug_init(void)
+{
+	struct proc_dir_entry	*entry;
+	int error = 0;
+	char * name;
+
+	ACPI_FUNCTION_TRACE("acpi_debug_init");
+
+	if (acpi_disabled)
+		return_VALUE(0);
+
+	/* 'debug_layer' [R/W] */
+	name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
+	entry = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir,
+				       acpi_system_read_debug,(void *)0);
+	if (entry)
+		entry->write_proc = acpi_system_write_debug;
+	else
+		goto Error;
+
+	/* 'debug_level' [R/W] */
+	name = ACPI_SYSTEM_FILE_DEBUG_LEVEL;
+	entry = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir,
+				       acpi_system_read_debug, (void *)1);
+	if (entry) 
+		entry->write_proc = acpi_system_write_debug;
+	else
+		goto Error;
+
+ Done:
+	return_VALUE(error);
+
+ Error:
+	ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			 "Unable to create '%s' proc fs entry\n", name));
+
+	remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir);
+	remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
+	error = -EFAULT;
+	goto Done;
+}
+
+subsys_initcall(acpi_debug_init);
diff --git a/drivers/acpi/dispatcher/Makefile b/drivers/acpi/dispatcher/Makefile
new file mode 100644
index 0000000..eb7e602
--- /dev/null
+++ b/drivers/acpi/dispatcher/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := dsfield.o   dsmthdat.o  dsopcode.o  dswexec.o  dswscope.o \
+	 dsmethod.o  dsobject.o  dsutils.o   dswload.o  dswstate.o \
+	 dsinit.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
new file mode 100644
index 0000000..2779211
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -0,0 +1,601 @@
+/******************************************************************************
+ *
+ * Module Name: dsfield - Dispatcher field routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsfield")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_buffer_field
+ *
+ * PARAMETERS:  Opcode              - The opcode to be executed
+ *              Operands            - List of operands for the opcode
+ *              walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute the create_field operators:
+ *              create_bit_field_op,
+ *              create_byte_field_op,
+ *              create_word_field_op,
+ *              create_dword_field_op,
+ *              create_qword_field_op,
+ *              create_field_op     (all of which define fields in buffers)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_create_buffer_field (
+	union acpi_parse_object         *op,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_parse_object         *arg;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *second_desc = NULL;
+	u32                             flags;
+
+
+	ACPI_FUNCTION_TRACE ("ds_create_buffer_field");
+
+
+	/* Get the name_string argument */
+
+	if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
+		arg = acpi_ps_get_arg (op, 3);
+	}
+	else {
+		/* Create Bit/Byte/Word/Dword field */
+
+		arg = acpi_ps_get_arg (op, 2);
+	}
+
+	if (!arg) {
+		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+	}
+
+	if (walk_state->deferred_node) {
+		node = walk_state->deferred_node;
+		status = AE_OK;
+	}
+	else {
+		/*
+		 * During the load phase, we want to enter the name of the field into
+		 * the namespace.  During the execute phase (when we evaluate the size
+		 * operand), we want to lookup the name
+		 */
+		if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
+			flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
+		}
+		else {
+			flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND;
+		}
+
+		/*
+		 * Enter the name_string into the namespace
+		 */
+		status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
+				 ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
+				 flags, walk_state, &(node));
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_NSERROR (arg->common.value.string, status);
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* We could put the returned object (Node) on the object stack for later, but
+	 * for now, we will put it in the "op" object that the parser uses, so we
+	 * can get it again at the end of this scope
+	 */
+	op->common.node = node;
+
+	/*
+	 * If there is no object attached to the node, this node was just created and
+	 * we need to create the field object.  Otherwise, this was a lookup of an
+	 * existing node and we don't want to create the field object again.
+	 */
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (obj_desc) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * The Field definition is not fully parsed at this time.
+	 * (We must save the address of the AML for the buffer and index operands)
+	 */
+
+	/* Create the buffer field object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER_FIELD);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Remember location in AML stream of the field unit
+	 * opcode and operands -- since the buffer and index
+	 * operands must be evaluated.
+	 */
+	second_desc                 = obj_desc->common.next_object;
+	second_desc->extra.aml_start = op->named.data;
+	second_desc->extra.aml_length = op->named.length;
+	obj_desc->buffer_field.node = node;
+
+	/* Attach constructed field descriptors to parent node */
+
+	status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+
+cleanup:
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_get_field_names
+ *
+ * PARAMETERS:  Info            - create_field info structure
+ *  `           walk_state      - Current method state
+ *              Arg             - First parser arg for the field name list
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Process all named fields in a field declaration.  Names are
+ *              entered into the namespace.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_get_field_names (
+	struct acpi_create_field_info   *info,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *arg)
+{
+	acpi_status                     status;
+	acpi_integer                    position;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_get_field_names", info);
+
+
+	/* First field starts at bit zero */
+
+	info->field_bit_position = 0;
+
+	/* Process all elements in the field list (of parse nodes) */
+
+	while (arg) {
+		/*
+		 * Three types of field elements are handled:
+		 * 1) Offset - specifies a bit offset
+		 * 2) access_as - changes the access mode
+		 * 3) Name - Enters a new named field into the namespace
+		 */
+		switch (arg->common.aml_opcode) {
+		case AML_INT_RESERVEDFIELD_OP:
+
+			position = (acpi_integer) info->field_bit_position
+					 + (acpi_integer) arg->common.value.size;
+
+			if (position > ACPI_UINT32_MAX) {
+				ACPI_REPORT_ERROR (("Bit offset within field too large (> 0xFFFFFFFF)\n"));
+				return_ACPI_STATUS (AE_SUPPORT);
+			}
+
+			info->field_bit_position = (u32) position;
+			break;
+
+
+		case AML_INT_ACCESSFIELD_OP:
+
+			/*
+			 * Get a new access_type and access_attribute -- to be used for all
+			 * field units that follow, until field end or another access_as keyword.
+			 *
+			 * In field_flags, preserve the flag bits other than the ACCESS_TYPE bits
+			 */
+			info->field_flags = (u8) ((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
+					  ((u8) ((u32) arg->common.value.integer >> 8)));
+
+			info->attribute = (u8) (arg->common.value.integer);
+			break;
+
+
+		case AML_INT_NAMEDFIELD_OP:
+
+			/* Lookup the name */
+
+			status = acpi_ns_lookup (walk_state->scope_info,
+					  (char *) &arg->named.name,
+					  info->field_type, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+					  walk_state, &info->field_node);
+			if (ACPI_FAILURE (status)) {
+				ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
+				if (status != AE_ALREADY_EXISTS) {
+					return_ACPI_STATUS (status);
+				}
+
+				/* Already exists, ignore error */
+			}
+			else {
+				arg->common.node = info->field_node;
+				info->field_bit_length = arg->common.value.size;
+
+				/* Create and initialize an object for the new Field Node */
+
+				status = acpi_ex_prep_field_value (info);
+				if (ACPI_FAILURE (status)) {
+					return_ACPI_STATUS (status);
+				}
+			}
+
+			/* Keep track of bit position for the next field */
+
+			position = (acpi_integer) info->field_bit_position
+					 + (acpi_integer) arg->common.value.size;
+
+			if (position > ACPI_UINT32_MAX) {
+				ACPI_REPORT_ERROR (("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n",
+						(char *) &info->field_node->name));
+				return_ACPI_STATUS (AE_SUPPORT);
+			}
+
+			info->field_bit_position += info->field_bit_length;
+			break;
+
+
+		default:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %X\n",
+				arg->common.aml_opcode));
+			return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+		}
+
+		arg = arg->common.next;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_field
+ *
+ * PARAMETERS:  Op              - Op containing the Field definition and args
+ *              region_node     - Object for the containing Operation Region
+ *  `           walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new field in the specified operation region
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_create_field (
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *region_node,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_parse_object         *arg;
+	struct acpi_create_field_info   info;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_create_field", op);
+
+
+	/* First arg is the name of the parent op_region (must already exist) */
+
+	arg = op->common.value.arg;
+	if (!region_node) {
+		status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name,
+				  ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
+				  ACPI_NS_SEARCH_PARENT, walk_state, &region_node);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_NSERROR (arg->common.value.name, status);
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Second arg is the field flags */
+
+	arg = arg->common.next;
+	info.field_flags = (u8) arg->common.value.integer;
+	info.attribute = 0;
+
+	/* Each remaining arg is a Named Field */
+
+	info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
+	info.region_node = region_node;
+
+	status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_init_field_objects
+ *
+ * PARAMETERS:  Op              - Op containing the Field definition and args
+ *  `           walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: For each "Field Unit" name in the argument list that is
+ *              part of the field declaration, enter the name into the
+ *              namespace.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_init_field_objects (
+	union acpi_parse_object         *op,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_parse_object         *arg = NULL;
+	struct acpi_namespace_node      *node;
+	u8                              type = 0;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_init_field_objects", op);
+
+
+	switch (walk_state->opcode) {
+	case AML_FIELD_OP:
+		arg = acpi_ps_get_arg (op, 2);
+		type = ACPI_TYPE_LOCAL_REGION_FIELD;
+		break;
+
+	case AML_BANK_FIELD_OP:
+		arg = acpi_ps_get_arg (op, 4);
+		type = ACPI_TYPE_LOCAL_BANK_FIELD;
+		break;
+
+	case AML_INDEX_FIELD_OP:
+		arg = acpi_ps_get_arg (op, 3);
+		type = ACPI_TYPE_LOCAL_INDEX_FIELD;
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Walk the list of entries in the field_list
+	 */
+	while (arg) {
+		/* Ignore OFFSET and ACCESSAS terms here */
+
+		if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
+			status = acpi_ns_lookup (walk_state->scope_info,
+					  (char *) &arg->named.name,
+					  type, ACPI_IMODE_LOAD_PASS1,
+					  ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
+					  walk_state, &node);
+			if (ACPI_FAILURE (status)) {
+				ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
+				if (status != AE_ALREADY_EXISTS) {
+					return_ACPI_STATUS (status);
+				}
+
+				/* Name already exists, just ignore this error */
+
+				status = AE_OK;
+			}
+
+			arg->common.node = node;
+		}
+
+		/* Move to next field in the list */
+
+		arg = arg->common.next;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_bank_field
+ *
+ * PARAMETERS:  Op              - Op containing the Field definition and args
+ *              region_node     - Object for the containing Operation Region
+ *  `           walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new bank field in the specified operation region
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_create_bank_field (
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *region_node,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_parse_object         *arg;
+	struct acpi_create_field_info   info;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_create_bank_field", op);
+
+
+	/* First arg is the name of the parent op_region (must already exist) */
+
+	arg = op->common.value.arg;
+	if (!region_node) {
+		status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name,
+				  ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
+				  ACPI_NS_SEARCH_PARENT, walk_state, &region_node);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_NSERROR (arg->common.value.name, status);
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Second arg is the Bank Register (Field) (must already exist) */
+
+	arg = arg->common.next;
+	status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
+			  ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+			  ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_NSERROR (arg->common.value.string, status);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Third arg is the bank_value */
+
+	arg = arg->common.next;
+	info.bank_value = (u32) arg->common.value.integer;
+
+	/* Fourth arg is the field flags */
+
+	arg = arg->common.next;
+	info.field_flags = (u8) arg->common.value.integer;
+
+	/* Each remaining arg is a Named Field */
+
+	info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
+	info.region_node = region_node;
+
+	status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_index_field
+ *
+ * PARAMETERS:  Op              - Op containing the Field definition and args
+ *              region_node     - Object for the containing Operation Region
+ *  `           walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new index field in the specified operation region
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_create_index_field (
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *region_node,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_parse_object         *arg;
+	struct acpi_create_field_info   info;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_create_index_field", op);
+
+
+	/* First arg is the name of the Index register (must already exist) */
+
+	arg = op->common.value.arg;
+	status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
+			  ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+			  ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_NSERROR (arg->common.value.string, status);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Second arg is the data register (must already exist) */
+
+	arg = arg->common.next;
+	status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
+			  ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+			  ACPI_NS_SEARCH_PARENT, walk_state, &info.data_register_node);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_NSERROR (arg->common.value.string, status);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Next arg is the field flags */
+
+	arg = arg->common.next;
+	info.field_flags = (u8) arg->common.value.integer;
+
+	/* Each remaining arg is a Named Field */
+
+	info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
+	info.region_node = region_node;
+
+	status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
new file mode 100644
index 0000000..b4d264d
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -0,0 +1,235 @@
+/******************************************************************************
+ *
+ * Module Name: dsinit - Object initialization namespace walk
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsinit")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_init_one_object
+ *
+ * PARAMETERS:  obj_handle      - Node
+ *              Level           - Current nesting level
+ *              Context         - Points to a init info struct
+ *              return_value    - Not used
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
+ *              within the namespace.
+ *
+ *              Currently, the only objects that require initialization are:
+ *              1) Methods
+ *              2) Operation Regions
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_init_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value)
+{
+	acpi_object_type                type;
+	acpi_status                     status;
+	struct acpi_init_walk_info      *info = (struct acpi_init_walk_info *) context;
+
+
+	ACPI_FUNCTION_NAME ("ds_init_one_object");
+
+
+	/*
+	 * We are only interested in objects owned by the table that
+	 * was just loaded
+	 */
+	if (((struct acpi_namespace_node *) obj_handle)->owner_id !=
+			info->table_desc->table_id) {
+		return (AE_OK);
+	}
+
+	info->object_count++;
+
+	/* And even then, we are only interested in a few object types */
+
+	type = acpi_ns_get_type (obj_handle);
+
+	switch (type) {
+	case ACPI_TYPE_REGION:
+
+		status = acpi_ds_initialize_region (obj_handle);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
+				obj_handle, acpi_ut_get_node_name (obj_handle),
+				acpi_format_exception (status)));
+		}
+
+		info->op_region_count++;
+		break;
+
+
+	case ACPI_TYPE_METHOD:
+
+		info->method_count++;
+
+		/* Print a dot for each method unless we are going to print the entire pathname */
+
+		if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+		}
+
+		/*
+		 * Set the execution data width (32 or 64) based upon the
+		 * revision number of the parent ACPI table.
+		 * TBD: This is really for possible future support of integer width
+		 * on a per-table basis. Currently, we just use a global for the width.
+		 */
+		if (info->table_desc->pointer->revision == 1) {
+			((struct acpi_namespace_node *) obj_handle)->flags |= ANOBJ_DATA_WIDTH_32;
+		}
+
+		/*
+		 * Always parse methods to detect errors, we will delete
+		 * the parse tree below
+		 */
+		status = acpi_ds_parse_method (obj_handle);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
+				obj_handle, acpi_ut_get_node_name (obj_handle),
+				acpi_format_exception (status)));
+
+			/* This parse failed, but we will continue parsing more methods */
+
+			break;
+		}
+
+		/*
+		 * Delete the parse tree.  We simply re-parse the method
+		 * for every execution since there isn't much overhead
+		 */
+		acpi_ns_delete_namespace_subtree (obj_handle);
+		acpi_ns_delete_namespace_by_owner (((struct acpi_namespace_node *) obj_handle)->object->method.owning_id);
+		break;
+
+
+	case ACPI_TYPE_DEVICE:
+
+		info->device_count++;
+		break;
+
+
+	default:
+		break;
+	}
+
+	/*
+	 * We ignore errors from above, and always return OK, since
+	 * we don't want to abort the walk on a single error.
+	 */
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_initialize_objects
+ *
+ * PARAMETERS:  table_desc      - Descriptor for parent ACPI table
+ *              start_node      - Root of subtree to be initialized.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk the namespace starting at "start_node" and perform any
+ *              necessary initialization on the objects found therein
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_initialize_objects (
+	struct acpi_table_desc          *table_desc,
+	struct acpi_namespace_node      *start_node)
+{
+	acpi_status                     status;
+	struct acpi_init_walk_info      info;
+
+
+	ACPI_FUNCTION_TRACE ("ds_initialize_objects");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"**** Starting initialization of namespace objects ****\n"));
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
+
+	info.method_count   = 0;
+	info.op_region_count = 0;
+	info.object_count   = 0;
+	info.device_count   = 0;
+	info.table_desc     = table_desc;
+
+	/* 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);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed, %s\n",
+			acpi_format_exception (status)));
+	}
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+		"\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+		table_desc->pointer->signature, table_desc->table_id, info.object_count,
+		info.device_count, info.method_count, info.op_region_count));
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"%hd Methods, %hd Regions\n", info.method_count, info.op_region_count));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
new file mode 100644
index 0000000..9f0456c
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -0,0 +1,597 @@
+/******************************************************************************
+ *
+ * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsmethod")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_parse_method
+ *
+ * PARAMETERS:  obj_handle      - Method node
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Call the parser and parse the AML that is associated with the
+ *              method.
+ *
+ * MUTEX:       Assumes parser is locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_parse_method (
+	acpi_handle                     obj_handle)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+	union acpi_parse_object         *op;
+	struct acpi_namespace_node      *node;
+	acpi_owner_id                   owner_id;
+	struct acpi_walk_state          *walk_state;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", obj_handle);
+
+
+	/* Parameter Validation */
+
+	if (!obj_handle) {
+		return_ACPI_STATUS (AE_NULL_ENTRY);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n",
+		acpi_ut_get_node_name (obj_handle), obj_handle));
+
+	/* Extract the method object from the method Node */
+
+	node = (struct acpi_namespace_node *) obj_handle;
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NULL_OBJECT);
+	}
+
+	/* Create a mutex for the method if there is a concurrency limit */
+
+	if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
+		(!obj_desc->method.semaphore)) {
+		status = acpi_os_create_semaphore (obj_desc->method.concurrency,
+				   obj_desc->method.concurrency,
+				   &obj_desc->method.semaphore);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Allocate a new parser op to be the root of the parsed
+	 * method tree
+	 */
+	op = acpi_ps_alloc_op (AML_METHOD_OP);
+	if (!op) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Init new op with the method name and pointer back to the Node */
+
+	acpi_ps_set_name (op, node->name.integer);
+	op->common.node = node;
+
+	/*
+	 * Get a new owner_id for objects created by this method. Namespace
+	 * objects (such as Operation Regions) can be created during the
+	 * first pass parse.
+	 */
+	owner_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
+	obj_desc->method.owning_id = owner_id;
+
+	/* Create and initialize a new walk state */
+
+	walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL);
+	if (!walk_state) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	status = acpi_ds_init_aml_walk (walk_state, op, node,
+			  obj_desc->method.aml_start,
+			  obj_desc->method.aml_length, NULL, 1);
+	if (ACPI_FAILURE (status)) {
+		acpi_ds_delete_walk_state (walk_state);
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Parse the method, first pass
+	 *
+	 * The first pass load is where newly declared named objects are
+	 * added into the namespace.  Actual evaluation of
+	 * the named objects (what would be called a "second
+	 * pass") happens during the actual execution of the
+	 * method so that operands to the named objects can
+	 * take on dynamic run-time values.
+	 */
+	status = acpi_ps_parse_aml (walk_state);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+		"**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
+		acpi_ut_get_node_name (obj_handle), obj_handle, op));
+
+	acpi_ps_delete_parse_tree (op);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_begin_method_execution
+ *
+ * PARAMETERS:  method_node         - Node of the method
+ *              obj_desc            - The method object
+ *              calling_method_node - Caller of this method (if non-null)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Prepare a method for execution.  Parses the method if necessary,
+ *              increments the thread count, and waits at the method semaphore
+ *              for clearance to execute.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_begin_method_execution (
+	struct acpi_namespace_node      *method_node,
+	union acpi_operand_object       *obj_desc,
+	struct acpi_namespace_node      *calling_method_node)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node);
+
+
+	if (!method_node) {
+		return_ACPI_STATUS (AE_NULL_ENTRY);
+	}
+
+	/*
+	 * If there is a concurrency limit on this method, we need to
+	 * obtain a unit from the method semaphore.
+	 */
+	if (obj_desc->method.semaphore) {
+		/*
+		 * Allow recursive method calls, up to the reentrancy/concurrency
+		 * limit imposed by the SERIALIZED rule and the sync_level method
+		 * parameter.
+		 *
+		 * The point of this code is to avoid permanently blocking a
+		 * thread that is making recursive method calls.
+		 */
+		if (method_node == calling_method_node) {
+			if (obj_desc->method.thread_count >= obj_desc->method.concurrency) {
+				return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
+			}
+		}
+
+		/*
+		 * Get a unit from the method semaphore. This releases the
+		 * interpreter if we block
+		 */
+		status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore,
+				 ACPI_WAIT_FOREVER);
+	}
+
+	/*
+	 * Increment the method parse tree thread count since it has been
+	 * reentered one more time (even if it is the same thread)
+	 */
+	obj_desc->method.thread_count++;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_call_control_method
+ *
+ * PARAMETERS:  Thread              - Info for this thread
+ *              this_walk_state     - Current walk state
+ *              Op                  - Current Op to be walked
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Transfer execution to a called control method
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_call_control_method (
+	struct acpi_thread_state        *thread,
+	struct acpi_walk_state          *this_walk_state,
+	union acpi_parse_object         *op)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *method_node;
+	struct acpi_walk_state          *next_walk_state;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_parameter_info      info;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_call_control_method", this_walk_state);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n",
+		this_walk_state->prev_op, this_walk_state));
+
+	/*
+	 * Get the namespace entry for the control method we are about to call
+	 */
+	method_node = this_walk_state->method_call_node;
+	if (!method_node) {
+		return_ACPI_STATUS (AE_NULL_ENTRY);
+	}
+
+	obj_desc = acpi_ns_get_attached_object (method_node);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NULL_OBJECT);
+	}
+
+	obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
+
+	/* Init for new method, wait on concurrency semaphore */
+
+	status = acpi_ds_begin_method_execution (method_node, obj_desc,
+			  this_walk_state->method_node);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
+		/* 1) Parse: Create a new walk state for the preempting walk */
+
+		next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
+				  op, obj_desc, NULL);
+		if (!next_walk_state) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Create and init a Root Node */
+
+		op = acpi_ps_create_scope_op ();
+		if (!op) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
+				  obj_desc->method.aml_start, obj_desc->method.aml_length,
+				  NULL, 1);
+		if (ACPI_FAILURE (status)) {
+			acpi_ds_delete_walk_state (next_walk_state);
+			goto cleanup;
+		}
+
+		/* Begin AML parse */
+
+		status = acpi_ps_parse_aml (next_walk_state);
+		acpi_ps_delete_parse_tree (op);
+	}
+
+	/* 2) Execute: Create a new state for the preempting walk */
+
+	next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
+			  NULL, obj_desc, thread);
+	if (!next_walk_state) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+	/*
+	 * The resolved arguments were put on the previous walk state's operand
+	 * stack.  Operands on the previous walk state stack always
+	 * start at index 0.
+	 * Null terminate the list of arguments
+	 */
+	this_walk_state->operands [this_walk_state->num_operands] = NULL;
+
+	info.parameters = &this_walk_state->operands[0];
+	info.parameter_type = ACPI_PARAM_ARGS;
+
+	status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node,
+			  obj_desc->method.aml_start, obj_desc->method.aml_length,
+			  &info, 3);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/*
+	 * Delete the operands on the previous walkstate operand stack
+	 * (they were copied to new objects)
+	 */
+	for (i = 0; i < obj_desc->method.param_count; i++) {
+		acpi_ut_remove_reference (this_walk_state->operands [i]);
+		this_walk_state->operands [i] = NULL;
+	}
+
+	/* Clear the operand stack */
+
+	this_walk_state->num_operands = 0;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"Starting nested execution, newstate=%p\n", next_walk_state));
+
+	if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
+		status = obj_desc->method.implementation (next_walk_state);
+		return_ACPI_STATUS (status);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+
+
+	/* On error, we must delete the new walk state */
+
+cleanup:
+	if (next_walk_state && (next_walk_state->method_desc)) {
+		/* Decrement the thread count on the method parse tree */
+
+	   next_walk_state->method_desc->method.thread_count--;
+	}
+	(void) acpi_ds_terminate_control_method (next_walk_state);
+	acpi_ds_delete_walk_state (next_walk_state);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_restart_control_method
+ *
+ * PARAMETERS:  walk_state          - State for preempted method (caller)
+ *              return_desc         - Return value from the called method
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Restart a method that was preempted by another (nested) method
+ *              invocation.  Handle the return value (if any) from the callee.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_restart_control_method (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *return_desc)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state);
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"****Restart [%4.4s] Op %p return_value_from_callee %p\n",
+		(char *) &walk_state->method_node->name, walk_state->method_call_op,
+		return_desc));
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"    return_from_this_method_used?=%X res_stack %p Walk %p\n",
+		walk_state->return_used,
+		walk_state->results, walk_state));
+
+	/* Did the called method return a value? */
+
+	if (return_desc) {
+		/* Are we actually going to use the return value? */
+
+		if (walk_state->return_used) {
+			/* Save the return value from the previous method */
+
+			status = acpi_ds_result_push (return_desc, walk_state);
+			if (ACPI_FAILURE (status)) {
+				acpi_ut_remove_reference (return_desc);
+				return_ACPI_STATUS (status);
+			}
+
+			/*
+			 * Save as THIS method's return value in case it is returned
+			 * immediately to yet another method
+			 */
+			walk_state->return_desc = return_desc;
+		}
+
+		/*
+		 * The following code is the
+		 * optional support for a so-called "implicit return". Some AML code
+		 * assumes that the last value of the method is "implicitly" returned
+		 * to the caller. Just save the last result as the return value.
+		 * NOTE: this is optional because the ASL language does not actually
+		 * support this behavior.
+		 */
+		else if (!acpi_ds_do_implicit_return (return_desc, walk_state, FALSE)) {
+			/*
+			 * Delete the return value if it will not be used by the
+			 * calling method
+			 */
+			acpi_ut_remove_reference (return_desc);
+		}
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_terminate_control_method
+ *
+ * PARAMETERS:  walk_state          - State of the method
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Terminate a control method.  Delete everything that the method
+ *              created, delete all locals and arguments, and delete the parse
+ *              tree if requested.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_terminate_control_method (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *method_node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_terminate_control_method", walk_state);
+
+
+	if (!walk_state) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* The current method object was saved in the walk state */
+
+	obj_desc = walk_state->method_desc;
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Delete all arguments and locals */
+
+	acpi_ds_method_data_delete_all (walk_state);
+
+	/*
+	 * Lock the parser while we terminate this method.
+	 * If this is the last thread executing the method,
+	 * we have additional cleanup to perform
+	 */
+	status = acpi_ut_acquire_mutex (ACPI_MTX_PARSER);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Signal completion of the execution of this method if necessary */
+
+	if (walk_state->method_desc->method.semaphore) {
+		status = acpi_os_signal_semaphore (
+				  walk_state->method_desc->method.semaphore, 1);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Could not signal method semaphore\n"));
+			status = AE_OK;
+
+			/* Ignore error and continue cleanup */
+		}
+	}
+
+	if (walk_state->method_desc->method.thread_count) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"*** Not deleting method namespace, there are still %d threads\n",
+			walk_state->method_desc->method.thread_count));
+	}
+
+	if (!walk_state->method_desc->method.thread_count) {
+		/*
+		 * Support to dynamically change a method from not_serialized to
+		 * Serialized if it appears that the method is written foolishly and
+		 * does not support multiple thread execution.  The best example of this
+		 * is if such a method creates namespace objects and blocks.  A second
+		 * thread will fail with an AE_ALREADY_EXISTS exception
+		 *
+		 * This code is here because we must wait until the last thread exits
+		 * before creating the synchronization semaphore.
+		 */
+		if ((walk_state->method_desc->method.concurrency == 1) &&
+			(!walk_state->method_desc->method.semaphore)) {
+			status = acpi_os_create_semaphore (1,
+					 1,
+					 &walk_state->method_desc->method.semaphore);
+		}
+
+		/*
+		 * There are no more threads executing this method.  Perform
+		 * additional cleanup.
+		 *
+		 * The method Node is stored in the walk state
+		 */
+		method_node = walk_state->method_node;
+
+		/*
+		 * Delete any namespace entries created immediately underneath
+		 * the method
+		 */
+		status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		if (method_node->child) {
+			acpi_ns_delete_namespace_subtree (method_node);
+		}
+
+		/*
+		 * Delete any namespace entries created anywhere else within
+		 * the namespace
+		 */
+		acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
+		status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	status = acpi_ut_release_mutex (ACPI_MTX_PARSER);
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
new file mode 100644
index 0000000..f31d095
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -0,0 +1,715 @@
+/*******************************************************************************
+ *
+ * Module Name: dsmthdat - control method arguments and local variables
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsmthdat")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_init
+ *
+ * PARAMETERS:  walk_state          - Current walk state object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the data structures that hold the method's arguments
+ *              and locals.  The data struct is an array of NTEs for each.
+ *              This allows ref_of and de_ref_of to work properly for these
+ *              special data types.
+ *
+ * NOTES:       walk_state fields are initialized to zero by the
+ *              ACPI_MEM_CALLOCATE().
+ *
+ *              A pseudo-Namespace Node is assigned to each argument and local
+ *              so that ref_of() can return a pointer to the Node.
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_method_data_init (
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ds_method_data_init");
+
+
+	/* Init the method arguments */
+
+	for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
+		ACPI_MOVE_32_TO_32 (&walk_state->arguments[i].name,
+				   NAMEOF_ARG_NTE);
+		walk_state->arguments[i].name.integer |= (i << 24);
+		walk_state->arguments[i].descriptor   = ACPI_DESC_TYPE_NAMED;
+		walk_state->arguments[i].type         = ACPI_TYPE_ANY;
+		walk_state->arguments[i].flags        = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
+	}
+
+	/* Init the method locals */
+
+	for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
+		ACPI_MOVE_32_TO_32 (&walk_state->local_variables[i].name,
+				   NAMEOF_LOCAL_NTE);
+
+		walk_state->local_variables[i].name.integer |= (i << 24);
+		walk_state->local_variables[i].descriptor  = ACPI_DESC_TYPE_NAMED;
+		walk_state->local_variables[i].type        = ACPI_TYPE_ANY;
+		walk_state->local_variables[i].flags       = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_delete_all
+ *
+ * PARAMETERS:  walk_state          - Current walk state object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete method locals and arguments.  Arguments are only
+ *              deleted if this method was called from another method.
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_method_data_delete_all (
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             index;
+
+
+	ACPI_FUNCTION_TRACE ("ds_method_data_delete_all");
+
+
+	/* Detach the locals */
+
+	for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
+		if (walk_state->local_variables[index].object) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
+					index, walk_state->local_variables[index].object));
+
+			/* Detach object (if present) and remove a reference */
+
+			acpi_ns_detach_object (&walk_state->local_variables[index]);
+		}
+	}
+
+	/* Detach the arguments */
+
+	for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
+		if (walk_state->arguments[index].object) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
+					index, walk_state->arguments[index].object));
+
+			/* Detach object (if present) and remove a reference */
+
+			acpi_ns_detach_object (&walk_state->arguments[index]);
+		}
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_init_args
+ *
+ * PARAMETERS:  *Params         - Pointer to a parameter list for the method
+ *              max_param_count - The arg count for this method
+ *              walk_state      - Current walk state object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
+ *              of ACPI operand objects, either null terminated or whose length
+ *              is defined by max_param_count.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_method_data_init_args (
+	union acpi_operand_object       **params,
+	u32                             max_param_count,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	u32                             index = 0;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_method_data_init_args", params);
+
+
+	if (!params) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Copy passed parameters into the new method stack frame  */
+
+	while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) {
+		/*
+		 * A valid parameter.
+		 * Store the argument in the method/walk descriptor.
+		 * Do not copy the arg in order to implement call by reference
+		 */
+		status = acpi_ds_method_data_set_value (AML_ARG_OP, index, params[index], walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		index++;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", index));
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_get_node
+ *
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ *              Index               - which local_var or argument whose type
+ *                                      to get
+ *              walk_state          - Current walk state object
+ *
+ * RETURN:      Get the Node associated with a local or arg.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_method_data_get_node (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      **node)
+{
+	ACPI_FUNCTION_TRACE ("ds_method_data_get_node");
+
+
+	/*
+	 * Method Locals and Arguments are supported
+	 */
+	switch (opcode) {
+	case AML_LOCAL_OP:
+
+		if (index > ACPI_METHOD_MAX_LOCAL) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n",
+				index, ACPI_METHOD_MAX_LOCAL));
+			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+		}
+
+		/* Return a pointer to the pseudo-node */
+
+		*node = &walk_state->local_variables[index];
+		break;
+
+	case AML_ARG_OP:
+
+		if (index > ACPI_METHOD_MAX_ARG) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
+				index, ACPI_METHOD_MAX_ARG));
+			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+		}
+
+		/* Return a pointer to the pseudo-node */
+
+		*node = &walk_state->arguments[index];
+		break;
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode));
+		return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_set_value
+ *
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ *              Index               - which local_var or argument to get
+ *              Object              - Object to be inserted into the stack entry
+ *              walk_state          - Current walk state object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
+ *              Note: There is no "implicit conversion" for locals.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_method_data_set_value (
+	u16                             opcode,
+	u32                             index,
+	union acpi_operand_object       *object,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+
+
+	ACPI_FUNCTION_TRACE ("ds_method_data_set_value");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"new_obj %p Opcode %X, Refs=%d [%s]\n", object,
+		opcode, object->common.reference_count,
+		acpi_ut_get_type_name (object->common.type)));
+
+	/* Get the namespace node for the arg/local */
+
+	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Increment ref count so object can't be deleted while installed.
+	 * NOTE: We do not copy the object in order to preserve the call by
+	 * reference semantics of ACPI Control Method invocation.
+	 * (See ACPI specification 2.0_c)
+	 */
+	acpi_ut_add_reference (object);
+
+	/* Install the object */
+
+	node->object = object;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_get_type
+ *
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ *              Index               - which local_var or argument whose type
+ *                                      to get
+ *              walk_state          - Current walk state object
+ *
+ * RETURN:      Data type of current value of the selected Arg or Local
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_object_type
+acpi_ds_method_data_get_type (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	union acpi_operand_object       *object;
+
+
+	ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
+
+
+	/* Get the namespace node for the arg/local */
+
+	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
+	if (ACPI_FAILURE (status)) {
+		return_VALUE ((ACPI_TYPE_NOT_FOUND));
+	}
+
+	/* Get the object */
+
+	object = acpi_ns_get_attached_object (node);
+	if (!object) {
+		/* Uninitialized local/arg, return TYPE_ANY */
+
+		return_VALUE (ACPI_TYPE_ANY);
+	}
+
+	/* Get the object type */
+
+	return_VALUE (ACPI_GET_OBJECT_TYPE (object));
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_get_value
+ *
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ *              Index               - which local_var or argument to get
+ *              walk_state          - Current walk state object
+ *              *dest_desc          - Ptr to Descriptor into which selected Arg
+ *                                    or Local value should be copied
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
+ *              at the current top of the method stack.
+ *              Used only in acpi_ex_resolve_to_value().
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_method_data_get_value (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       **dest_desc)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	union acpi_operand_object       *object;
+
+
+	ACPI_FUNCTION_TRACE ("ds_method_data_get_value");
+
+
+	/* Validate the object descriptor */
+
+	if (!dest_desc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null object descriptor pointer\n"));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Get the namespace node for the arg/local */
+
+	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get the object from the node */
+
+	object = node->object;
+
+	/* Examine the returned object, it must be valid. */
+
+	if (!object) {
+		/*
+		 * Index points to uninitialized object.
+		 * This means that either 1) The expected argument was
+		 * not passed to the method, or 2) A local variable
+		 * was referenced by the method (via the ASL)
+		 * before it was initialized.  Either case is an error.
+		 */
+
+		/* If slack enabled, init the local_x/arg_x to an Integer of value zero */
+
+		if (acpi_gbl_enable_interpreter_slack) {
+			object = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+			if (!object) {
+				return_ACPI_STATUS (AE_NO_MEMORY);
+			}
+
+			object->integer.value = 0;
+			node->object = object;
+		}
+
+		/* Otherwise, return the error */
+
+		else switch (opcode) {
+		case AML_ARG_OP:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n",
+				index, node));
+
+			return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
+
+		case AML_LOCAL_OP:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at node %p\n",
+				index, node));
+
+			return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
+
+		default:
+			ACPI_REPORT_ERROR (("Not Arg/Local opcode: %X\n", opcode));
+			return_ACPI_STATUS (AE_AML_INTERNAL);
+		}
+	}
+
+	/*
+	 * The Index points to an initialized and valid object.
+	 * Return an additional reference to the object
+	 */
+	*dest_desc = object;
+	acpi_ut_add_reference (object);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_delete_value
+ *
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ *              Index               - which local_var or argument to delete
+ *              walk_state          - Current walk state object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete the entry at Opcode:Index on the method stack.  Inserts
+ *              a null into the stack slot after the object is deleted.
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_method_data_delete_value (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	union acpi_operand_object       *object;
+
+
+	ACPI_FUNCTION_TRACE ("ds_method_data_delete_value");
+
+
+	/* Get the namespace node for the arg/local */
+
+	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
+	if (ACPI_FAILURE (status)) {
+		return_VOID;
+	}
+
+	/* Get the associated object */
+
+	object = acpi_ns_get_attached_object (node);
+
+	/*
+	 * Undefine the Arg or Local by setting its descriptor
+	 * pointer to NULL. Locals/Args can contain both
+	 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
+	 */
+	node->object = NULL;
+
+	if ((object) &&
+		(ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_OPERAND)) {
+		/*
+		 * There is a valid object.
+		 * Decrement the reference count by one to balance the
+		 * increment when the object was stored.
+		 */
+		acpi_ut_remove_reference (object);
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_store_object_to_local
+ *
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ *              Index               - which local_var or argument to set
+ *              obj_desc            - Value to be stored
+ *              walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store a value in an Arg or Local.  The obj_desc is installed
+ *              as the new value for the Arg or Local and the reference count
+ *              for obj_desc is incremented.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_store_object_to_local (
+	u16                             opcode,
+	u32                             index,
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	union acpi_operand_object       *current_obj_desc;
+	union acpi_operand_object       *new_obj_desc;
+
+
+	ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
+		opcode, index, obj_desc));
+
+	/* Parameter validation */
+
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Get the namespace node for the arg/local */
+
+	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	current_obj_desc = acpi_ns_get_attached_object (node);
+	if (current_obj_desc == obj_desc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
+			obj_desc));
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * If the reference count on the object is more than one, we must
+	 * take a copy of the object before we store.  A reference count
+	 * of exactly 1 means that the object was just created during the
+	 * evaluation of an expression, and we can safely use it since it
+	 * is not used anywhere else.
+	 */
+	new_obj_desc = obj_desc;
+	if (obj_desc->common.reference_count > 1) {
+		status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * If there is an object already in this slot, we either
+	 * have to delete it, or if this is an argument and there
+	 * is an object reference stored there, we have to do
+	 * an indirect store!
+	 */
+	if (current_obj_desc) {
+		/*
+		 * Check for an indirect store if an argument
+		 * contains an object reference (stored as an Node).
+		 * We don't allow this automatic dereferencing for
+		 * locals, since a store to a local should overwrite
+		 * anything there, including an object reference.
+		 *
+		 * If both Arg0 and Local0 contain ref_of (Local4):
+		 *
+		 * Store (1, Arg0)             - Causes indirect store to local4
+		 * Store (1, Local0)           - Stores 1 in local0, overwriting
+		 *                                  the reference to local4
+		 * Store (1, de_refof (Local0)) - Causes indirect store to local4
+		 *
+		 * Weird, but true.
+		 */
+		if (opcode == AML_ARG_OP) {
+			/*
+			 * Make sure that the object is the correct type.  This may be overkill, but
+			 * it is here because references were NS nodes in the past.  Now they are
+			 * operand objects of type Reference.
+			 */
+			if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+				ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
+						acpi_ut_get_descriptor_name (current_obj_desc)));
+				return_ACPI_STATUS (AE_AML_INTERNAL);
+			}
+
+			/*
+			 * If we have a valid reference object that came from ref_of(), do the
+			 * indirect store
+			 */
+			if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+				(current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+						"Arg (%p) is an obj_ref(Node), storing in node %p\n",
+						new_obj_desc, current_obj_desc));
+
+				/*
+				 * Store this object to the Node (perform the indirect store)
+				 * NOTE: No implicit conversion is performed, as per the ACPI
+				 * specification rules on storing to Locals/Args.
+				 */
+				status = acpi_ex_store_object_to_node (new_obj_desc,
+						 current_obj_desc->reference.object, walk_state,
+						 ACPI_NO_IMPLICIT_CONVERSION);
+
+				/* Remove local reference if we copied the object above */
+
+				if (new_obj_desc != obj_desc) {
+					acpi_ut_remove_reference (new_obj_desc);
+				}
+				return_ACPI_STATUS (status);
+			}
+		}
+
+		/*
+		 * Delete the existing object
+		 * before storing the new one
+		 */
+		acpi_ds_method_data_delete_value (opcode, index, walk_state);
+	}
+
+	/*
+	 * Install the Obj descriptor (*new_obj_desc) into
+	 * the descriptor for the Arg or Local.
+	 * (increments the object reference count by one)
+	 */
+	status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);
+
+	/* Remove local reference if we copied the object above */
+
+	if (new_obj_desc != obj_desc) {
+		acpi_ut_remove_reference (new_obj_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
new file mode 100644
index 0000000..eb8af47
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -0,0 +1,618 @@
+/******************************************************************************
+ *
+ * Module Name: dsobject - Dispatcher object management routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsobject")
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_build_internal_object
+ *
+ * PARAMETERS:  walk_state      - Current walk state
+ *              Op              - Parser object to be translated
+ *              obj_desc_ptr    - Where the ACPI internal object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
+ *              Simple objects are any objects other than a package object!
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_build_internal_object (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	union acpi_operand_object       **obj_desc_ptr)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ds_build_internal_object");
+
+
+	*obj_desc_ptr = NULL;
+	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
+		/*
+		 * This is an named object reference.  If this name was
+		 * previously looked up in the namespace, it was stored in this op.
+		 * Otherwise, go ahead and look it up now
+		 */
+		if (!op->common.node) {
+			status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string,
+					  ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+					  ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
+					  (struct acpi_namespace_node **) &(op->common.node));
+
+			if (ACPI_FAILURE (status)) {
+				ACPI_REPORT_NSERROR (op->common.value.string, status);
+				return_ACPI_STATUS (status);
+			}
+		}
+	}
+
+	/* Create and init the internal ACPI object */
+
+	obj_desc = acpi_ut_create_internal_object ((acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (obj_desc);
+		return_ACPI_STATUS (status);
+	}
+
+	*obj_desc_ptr = obj_desc;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_build_internal_buffer_obj
+ *
+ * PARAMETERS:  walk_state      - Current walk state
+ *              Op              - Parser object to be translated
+ *              buffer_length   - Length of the buffer
+ *              obj_desc_ptr    - Where the ACPI internal object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ *              namespace object
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_build_internal_buffer_obj (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	u32                             buffer_length,
+	union acpi_operand_object       **obj_desc_ptr)
+{
+	union acpi_parse_object         *arg;
+	union acpi_operand_object       *obj_desc;
+	union acpi_parse_object         *byte_list;
+	u32                             byte_list_length = 0;
+
+
+	ACPI_FUNCTION_TRACE ("ds_build_internal_buffer_obj");
+
+
+	obj_desc = *obj_desc_ptr;
+	if (obj_desc) {
+		/*
+		 * We are evaluating a Named buffer object "Name (xxxx, Buffer)".
+		 * The buffer object already exists (from the NS node)
+		 */
+	}
+	else {
+		/* Create a new buffer object */
+
+		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+		*obj_desc_ptr = obj_desc;
+		if (!obj_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+	}
+
+	/*
+	 * Second arg is the buffer data (optional) byte_list can be either
+	 * individual bytes or a string initializer.  In either case, a
+	 * byte_list appears in the AML.
+	 */
+	arg = op->common.value.arg;         /* skip first arg */
+
+	byte_list = arg->named.next;
+	if (byte_list) {
+		if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Expecting bytelist, got AML opcode %X in op %p\n",
+				byte_list->common.aml_opcode, byte_list));
+
+			acpi_ut_remove_reference (obj_desc);
+			return (AE_TYPE);
+		}
+
+		byte_list_length = (u32) byte_list->common.value.integer;
+	}
+
+	/*
+	 * The buffer length (number of bytes) will be the larger of:
+	 * 1) The specified buffer length and
+	 * 2) The length of the initializer byte list
+	 */
+	obj_desc->buffer.length = buffer_length;
+	if (byte_list_length > buffer_length) {
+		obj_desc->buffer.length = byte_list_length;
+	}
+
+	/* Allocate the buffer */
+
+	if (obj_desc->buffer.length == 0) {
+		obj_desc->buffer.pointer = NULL;
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Buffer defined with zero length in AML, creating\n"));
+	}
+	else {
+		obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
+				   obj_desc->buffer.length);
+		if (!obj_desc->buffer.pointer) {
+			acpi_ut_delete_object_desc (obj_desc);
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Initialize buffer from the byte_list (if present) */
+
+		if (byte_list) {
+			ACPI_MEMCPY (obj_desc->buffer.pointer, byte_list->named.data,
+					  byte_list_length);
+		}
+	}
+
+	obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
+	op->common.node = (struct acpi_namespace_node *) obj_desc;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_build_internal_package_obj
+ *
+ * PARAMETERS:  walk_state      - Current walk state
+ *              Op              - Parser object to be translated
+ *              package_length  - Number of elements in the package
+ *              obj_desc_ptr    - Where the ACPI internal object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ *              namespace object
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_build_internal_package_obj (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	u32                             package_length,
+	union acpi_operand_object       **obj_desc_ptr)
+{
+	union acpi_parse_object         *arg;
+	union acpi_parse_object         *parent;
+	union acpi_operand_object       *obj_desc = NULL;
+	u32                             package_list_length;
+	acpi_status                     status = AE_OK;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ds_build_internal_package_obj");
+
+
+	/* Find the parent of a possibly nested package */
+
+	parent = op->common.parent;
+	while ((parent->common.aml_opcode == AML_PACKAGE_OP)    ||
+		   (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
+		parent = parent->common.parent;
+	}
+
+	obj_desc = *obj_desc_ptr;
+	if (obj_desc) {
+		/*
+		 * We are evaluating a Named package object "Name (xxxx, Package)".
+		 * Get the existing package object from the NS node
+		 */
+	}
+	else {
+		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
+		*obj_desc_ptr = obj_desc;
+		if (!obj_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		obj_desc->package.node = parent->common.node;
+	}
+
+	obj_desc->package.count = package_length;
+
+	/* Count the number of items in the package list */
+
+	package_list_length = 0;
+	arg = op->common.value.arg;
+	arg = arg->common.next;
+	while (arg) {
+		package_list_length++;
+		arg = arg->common.next;
+	}
+
+	/*
+	 * The package length (number of elements) will be the greater
+	 * of the specified length and the length of the initializer list
+	 */
+	if (package_list_length > package_length) {
+		obj_desc->package.count = package_list_length;
+	}
+
+	/*
+	 * Allocate the pointer array (array of pointers to the
+	 * individual objects). Add an extra pointer slot so
+	 * that the list is always null terminated.
+	 */
+	obj_desc->package.elements = ACPI_MEM_CALLOCATE (
+			 ((acpi_size) obj_desc->package.count + 1) * sizeof (void *));
+
+	if (!obj_desc->package.elements) {
+		acpi_ut_delete_object_desc (obj_desc);
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * Now init the elements of the package
+	 */
+	i = 0;
+	arg = op->common.value.arg;
+	arg = arg->common.next;
+	while (arg) {
+		if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
+			/* Object (package or buffer) is already built */
+
+			obj_desc->package.elements[i] = ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
+		}
+		else {
+			status = acpi_ds_build_internal_object (walk_state, arg,
+					  &obj_desc->package.elements[i]);
+		}
+
+		i++;
+		arg = arg->common.next;
+	}
+
+	obj_desc->package.flags |= AOPOBJ_DATA_VALID;
+	op->common.node = (struct acpi_namespace_node *) obj_desc;
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_node
+ *
+ * PARAMETERS:  walk_state      - Current walk state
+ *              Node            - NS Node to be initialized
+ *              Op              - Parser object to be translated
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create the object to be associated with a namespace node
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_create_node (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      *node,
+	union acpi_parse_object         *op)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_create_node", op);
+
+
+	/*
+	 * Because of the execution pass through the non-control-method
+	 * parts of the table, we can arrive here twice.  Only init
+	 * the named object node the first time through
+	 */
+	if (acpi_ns_get_attached_object (node)) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	if (!op->common.value.arg) {
+		/* No arguments, there is nothing to do */
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Build an internal object for the argument(s) */
+
+	status = acpi_ds_build_internal_object (walk_state, op->common.value.arg, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Re-type the object according to its argument */
+
+	node->type = ACPI_GET_OBJECT_TYPE (obj_desc);
+
+	/* Attach obj to node */
+
+	status = acpi_ns_attach_object (node, obj_desc, node->type);
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_init_object_from_op
+ *
+ * PARAMETERS:  walk_state      - Current walk state
+ *              Op              - Parser op used to init the internal object
+ *              Opcode          - AML opcode associated with the object
+ *              ret_obj_desc    - Namespace object to be initialized
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize a namespace object from a parser Op and its
+ *              associated arguments.  The namespace object is a more compact
+ *              representation of the Op and its arguments.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_init_object_from_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	u16                             opcode,
+	union acpi_operand_object       **ret_obj_desc)
+{
+	const struct acpi_opcode_info   *op_info;
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ds_init_object_from_op");
+
+
+	obj_desc = *ret_obj_desc;
+	op_info = acpi_ps_get_opcode_info (opcode);
+	if (op_info->class == AML_CLASS_UNKNOWN) {
+		/* Unknown opcode */
+
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+	/* Perform per-object initialization */
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_BUFFER:
+
+		/*
+		 * Defer evaluation of Buffer term_arg operand
+		 */
+		obj_desc->buffer.node     = (struct acpi_namespace_node *) walk_state->operands[0];
+		obj_desc->buffer.aml_start = op->named.data;
+		obj_desc->buffer.aml_length = op->named.length;
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		/*
+		 * Defer evaluation of Package term_arg operand
+		 */
+		obj_desc->package.node     = (struct acpi_namespace_node *) walk_state->operands[0];
+		obj_desc->package.aml_start = op->named.data;
+		obj_desc->package.aml_length = op->named.length;
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		switch (op_info->type) {
+		case AML_TYPE_CONSTANT:
+			/*
+			 * Resolve AML Constants here - AND ONLY HERE!
+			 * All constants are integers.
+			 * We mark the integer with a flag that indicates that it started life
+			 * as a constant -- so that stores to constants will perform as expected (noop).
+			 * (zero_op is used as a placeholder for optional target operands.)
+			 */
+			obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
+
+			switch (opcode) {
+			case AML_ZERO_OP:
+
+				obj_desc->integer.value = 0;
+				break;
+
+			case AML_ONE_OP:
+
+				obj_desc->integer.value = 1;
+				break;
+
+			case AML_ONES_OP:
+
+				obj_desc->integer.value = ACPI_INTEGER_MAX;
+
+				/* Truncate value if we are executing from a 32-bit ACPI table */
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+				acpi_ex_truncate_for32bit_table (obj_desc);
+#endif
+				break;
+
+			case AML_REVISION_OP:
+
+				obj_desc->integer.value = ACPI_CA_VERSION;
+				break;
+
+			default:
+
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode));
+				status = AE_AML_OPERAND_TYPE;
+				break;
+			}
+			break;
+
+
+		case AML_TYPE_LITERAL:
+
+			obj_desc->integer.value = op->common.value.integer;
+			break;
+
+
+		default:
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type));
+			status = AE_AML_OPERAND_TYPE;
+			break;
+		}
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		obj_desc->string.pointer = op->common.value.string;
+		obj_desc->string.length = (u32) ACPI_STRLEN (op->common.value.string);
+
+		/*
+		 * The string is contained in the ACPI table, don't ever try
+		 * to delete it
+		 */
+		obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
+		break;
+
+
+	case ACPI_TYPE_METHOD:
+		break;
+
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		switch (op_info->type) {
+		case AML_TYPE_LOCAL_VARIABLE:
+
+			/* Split the opcode into a base opcode + offset */
+
+			obj_desc->reference.opcode = AML_LOCAL_OP;
+			obj_desc->reference.offset = opcode - AML_LOCAL_OP;
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+			status = acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset,
+					 walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
+#endif
+			break;
+
+
+		case AML_TYPE_METHOD_ARGUMENT:
+
+			/* Split the opcode into a base opcode + offset */
+
+			obj_desc->reference.opcode = AML_ARG_OP;
+			obj_desc->reference.offset = opcode - AML_ARG_OP;
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+			status = acpi_ds_method_data_get_node (AML_ARG_OP, obj_desc->reference.offset,
+					 walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
+#endif
+			break;
+
+		default: /* Other literals, etc.. */
+
+			if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
+				/* Node was saved in Op */
+
+				obj_desc->reference.node = op->common.node;
+			}
+
+			obj_desc->reference.opcode = opcode;
+			break;
+		}
+		break;
+
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n",
+			ACPI_GET_OBJECT_TYPE (obj_desc)));
+
+		status = AE_AML_OPERAND_TYPE;
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
new file mode 100644
index 0000000..5c987a0
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -0,0 +1,1151 @@
+/******************************************************************************
+ *
+ * Module Name: dsopcode - Dispatcher Op Region support and handling of
+ *                         "control" opcodes
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsopcode")
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_execute_arguments
+ *
+ * PARAMETERS:  Node                - Parent NS node
+ *              aml_length          - Length of executable AML
+ *              aml_start           - Pointer to the AML
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Late (deferred) execution of region or field arguments
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_execute_arguments (
+	struct acpi_namespace_node      *node,
+	struct acpi_namespace_node      *scope_node,
+	u32                             aml_length,
+	u8                              *aml_start)
+{
+	acpi_status                     status;
+	union acpi_parse_object         *op;
+	struct acpi_walk_state          *walk_state;
+
+
+	ACPI_FUNCTION_TRACE ("ds_execute_arguments");
+
+
+	/*
+	 * Allocate a new parser op to be the root of the parsed tree
+	 */
+	op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
+	if (!op) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Save the Node for use in acpi_ps_parse_aml */
+
+	op->common.node = scope_node;
+
+	/* Create and initialize a new parser state */
+
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+	if (!walk_state) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
+			  aml_length, NULL, 1);
+	if (ACPI_FAILURE (status)) {
+		acpi_ds_delete_walk_state (walk_state);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Mark this parse as a deferred opcode */
+
+	walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
+	walk_state->deferred_node = node;
+
+	/* Pass1: Parse the entire declaration */
+
+	status = acpi_ps_parse_aml (walk_state);
+	if (ACPI_FAILURE (status)) {
+		acpi_ps_delete_parse_tree (op);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get and init the Op created above */
+
+	op->common.node = node;
+	acpi_ps_delete_parse_tree (op);
+
+	/* Evaluate the deferred arguments */
+
+	op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
+	if (!op) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	op->common.node = scope_node;
+
+	/* Create and initialize a new parser state */
+
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+	if (!walk_state) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Execute the opcode and arguments */
+
+	status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
+			  aml_length, NULL, 3);
+	if (ACPI_FAILURE (status)) {
+		acpi_ds_delete_walk_state (walk_state);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Mark this execution as a deferred opcode */
+
+	walk_state->deferred_node = node;
+	status = acpi_ps_parse_aml (walk_state);
+	acpi_ps_delete_parse_tree (op);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_get_buffer_field_arguments
+ *
+ * PARAMETERS:  obj_desc        - A valid buffer_field object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
+ *              evaluation of these field attributes.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_get_buffer_field_arguments (
+	union acpi_operand_object       *obj_desc)
+{
+	union acpi_operand_object       *extra_desc;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc);
+
+
+	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Get the AML pointer (method object) and buffer_field node */
+
+	extra_desc = acpi_ns_get_secondary_object (obj_desc);
+	node = obj_desc->buffer_field.node;
+
+	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
+		acpi_ut_get_node_name (node)));
+
+	/* Execute the AML code for the term_arg arguments */
+
+	status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
+			 extra_desc->extra.aml_length, extra_desc->extra.aml_start);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_get_buffer_arguments
+ *
+ * PARAMETERS:  obj_desc        - A valid Buffer object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
+ *              the late evaluation of these attributes.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_get_buffer_arguments (
+	union acpi_operand_object       *obj_desc)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc);
+
+
+	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Get the Buffer node */
+
+	node = obj_desc->buffer.node;
+	if (!node) {
+		ACPI_REPORT_ERROR ((
+				"No pointer back to NS node in buffer obj %p\n", obj_desc));
+		return_ACPI_STATUS (AE_AML_INTERNAL);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
+
+	/* Execute the AML code for the term_arg arguments */
+
+	status = acpi_ds_execute_arguments (node, node,
+			 obj_desc->buffer.aml_length, obj_desc->buffer.aml_start);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_get_package_arguments
+ *
+ * PARAMETERS:  obj_desc        - A valid Package object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get Package length and initializer byte list.  This implements
+ *              the late evaluation of these attributes.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_get_package_arguments (
+	union acpi_operand_object       *obj_desc)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc);
+
+
+	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Get the Package node */
+
+	node = obj_desc->package.node;
+	if (!node) {
+		ACPI_REPORT_ERROR ((
+				"No pointer back to NS node in package %p\n", obj_desc));
+		return_ACPI_STATUS (AE_AML_INTERNAL);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
+
+	/* Execute the AML code for the term_arg arguments */
+
+	status = acpi_ds_execute_arguments (node, node,
+			 obj_desc->package.aml_length, obj_desc->package.aml_start);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_get_region_arguments
+ *
+ * PARAMETERS:  obj_desc        - A valid region object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get region address and length.  This implements the late
+ *              evaluation of these region attributes.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_get_region_arguments (
+	union acpi_operand_object       *obj_desc)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+	union acpi_operand_object       *extra_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc);
+
+
+	if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	extra_desc = acpi_ns_get_secondary_object (obj_desc);
+	if (!extra_desc) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/* Get the Region node */
+
+	node = obj_desc->region.node;
+
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
+		acpi_ut_get_node_name (node), extra_desc->extra.aml_start));
+
+	/* Execute the argument AML */
+
+	status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
+			 extra_desc->extra.aml_length, extra_desc->extra.aml_start);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_initialize_region
+ *
+ * PARAMETERS:  Op              - A valid region Op object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Front end to ev_initialize_region
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_initialize_region (
+	acpi_handle                     obj_handle)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	obj_desc = acpi_ns_get_attached_object (obj_handle);
+
+	/* Namespace is NOT locked */
+
+	status = acpi_ev_initialize_region (obj_desc, FALSE);
+	return (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_init_buffer_field
+ *
+ * PARAMETERS:  aml_opcode      - create_xxx_field
+ *              obj_desc        - buffer_field object
+ *              buffer_desc     - Host Buffer
+ *              offset_desc     - Offset into buffer
+ *              Length          - Length of field (CREATE_FIELD_OP only)
+ *              Result          - Where to store the result
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform actual initialization of a buffer field
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_init_buffer_field (
+	u16                             aml_opcode,
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *buffer_desc,
+	union acpi_operand_object       *offset_desc,
+	union acpi_operand_object       *length_desc,
+	union acpi_operand_object       *result_desc)
+{
+	u32                             offset;
+	u32                             bit_offset;
+	u32                             bit_count;
+	u8                              field_flags;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc);
+
+
+	/* Host object must be a Buffer */
+
+	if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Target of Create Field is not a Buffer object - %s\n",
+			acpi_ut_get_object_type_name (buffer_desc)));
+
+		status = AE_AML_OPERAND_TYPE;
+		goto cleanup;
+	}
+
+	/*
+	 * The last parameter to all of these opcodes (result_desc) started
+	 * out as a name_string, and should therefore now be a NS node
+	 * after resolution in acpi_ex_resolve_operands().
+	 */
+	if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
+				acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
+
+		status = AE_AML_OPERAND_TYPE;
+		goto cleanup;
+	}
+
+	offset = (u32) offset_desc->integer.value;
+
+	/*
+	 * Setup the Bit offsets and counts, according to the opcode
+	 */
+	switch (aml_opcode) {
+	case AML_CREATE_FIELD_OP:
+
+		/* Offset is in bits, count is in bits */
+
+		bit_offset = offset;
+		bit_count  = (u32) length_desc->integer.value;
+		field_flags = AML_FIELD_ACCESS_BYTE;
+		break;
+
+	case AML_CREATE_BIT_FIELD_OP:
+
+		/* Offset is in bits, Field is one bit */
+
+		bit_offset = offset;
+		bit_count  = 1;
+		field_flags = AML_FIELD_ACCESS_BYTE;
+		break;
+
+	case AML_CREATE_BYTE_FIELD_OP:
+
+		/* Offset is in bytes, field is one byte */
+
+		bit_offset = 8 * offset;
+		bit_count  = 8;
+		field_flags = AML_FIELD_ACCESS_BYTE;
+		break;
+
+	case AML_CREATE_WORD_FIELD_OP:
+
+		/* Offset is in bytes, field is one word */
+
+		bit_offset = 8 * offset;
+		bit_count  = 16;
+		field_flags = AML_FIELD_ACCESS_WORD;
+		break;
+
+	case AML_CREATE_DWORD_FIELD_OP:
+
+		/* Offset is in bytes, field is one dword */
+
+		bit_offset = 8 * offset;
+		bit_count  = 32;
+		field_flags = AML_FIELD_ACCESS_DWORD;
+		break;
+
+	case AML_CREATE_QWORD_FIELD_OP:
+
+		/* Offset is in bytes, field is one qword */
+
+		bit_offset = 8 * offset;
+		bit_count  = 64;
+		field_flags = AML_FIELD_ACCESS_QWORD;
+		break;
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown field creation opcode %02x\n",
+			aml_opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+	/* Entire field must fit within the current length of the buffer */
+
+	if ((bit_offset + bit_count) >
+		(8 * (u32) buffer_desc->buffer.length)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
+			 acpi_ut_get_node_name (result_desc),
+			 bit_offset + bit_count,
+			 acpi_ut_get_node_name (buffer_desc->buffer.node),
+			 8 * (u32) buffer_desc->buffer.length));
+		status = AE_AML_BUFFER_LIMIT;
+		goto cleanup;
+	}
+
+	/*
+	 * Initialize areas of the field object that are common to all fields
+	 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
+	 */
+	status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,
+			  bit_offset, bit_count);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	obj_desc->buffer_field.buffer_obj = buffer_desc;
+
+	/* Reference count for buffer_desc inherits obj_desc count */
+
+	buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count +
+			  obj_desc->common.reference_count);
+
+
+cleanup:
+
+	/* Always delete the operands */
+
+	acpi_ut_remove_reference (offset_desc);
+	acpi_ut_remove_reference (buffer_desc);
+
+	if (aml_opcode == AML_CREATE_FIELD_OP) {
+		acpi_ut_remove_reference (length_desc);
+	}
+
+	/* On failure, delete the result descriptor */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (result_desc); /* Result descriptor */
+	}
+	else {
+		/* Now the address and length are valid for this buffer_field */
+
+		obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_eval_buffer_field_operands
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *              Op              - A valid buffer_field Op object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get buffer_field Buffer and Index
+ *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_eval_buffer_field_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	union acpi_parse_object         *next_op;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op);
+
+
+	/*
+	 * This is where we evaluate the address and length fields of the
+	 * create_xxx_field declaration
+	 */
+	node =  op->common.node;
+
+	/* next_op points to the op that holds the Buffer */
+
+	next_op = op->common.value.arg;
+
+	/* Evaluate/create the address and length operands */
+
+	status = acpi_ds_create_operands (walk_state, next_op);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/* Resolve the operands */
+
+	status = acpi_ex_resolve_operands (op->common.aml_opcode,
+			  ACPI_WALK_OPERANDS, walk_state);
+
+	ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
+			  acpi_ps_get_opcode_name (op->common.aml_opcode),
+			  walk_state->num_operands, "after acpi_ex_resolve_operands");
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
+			acpi_ps_get_opcode_name (op->common.aml_opcode), status));
+
+		return_ACPI_STATUS (status);
+	}
+
+	/* Initialize the Buffer Field */
+
+	if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
+		/* NOTE: Slightly different operands for this opcode */
+
+		status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
+				 walk_state->operands[0], walk_state->operands[1],
+				 walk_state->operands[2], walk_state->operands[3]);
+	}
+	else {
+		/* All other, create_xxx_field opcodes */
+
+		status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
+				 walk_state->operands[0], walk_state->operands[1],
+						  NULL, walk_state->operands[2]);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_eval_region_operands
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *              Op              - A valid region Op object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get region address and length
+ *              Called from acpi_ds_exec_end_op during op_region parse tree walk
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_eval_region_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *operand_desc;
+	struct acpi_namespace_node      *node;
+	union acpi_parse_object         *next_op;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op);
+
+
+	/*
+	 * This is where we evaluate the address and length fields of the op_region declaration
+	 */
+	node =  op->common.node;
+
+	/* next_op points to the op that holds the space_iD */
+
+	next_op = op->common.value.arg;
+
+	/* next_op points to address op */
+
+	next_op = next_op->common.next;
+
+	/* Evaluate/create the address and length operands */
+
+	status = acpi_ds_create_operands (walk_state, next_op);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Resolve the length and address operands to numbers */
+
+	status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
+			  acpi_ps_get_opcode_name (op->common.aml_opcode),
+			  1, "after acpi_ex_resolve_operands");
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/*
+	 * Get the length operand and save it
+	 * (at Top of stack)
+	 */
+	operand_desc = walk_state->operands[walk_state->num_operands - 1];
+
+	obj_desc->region.length = (u32) operand_desc->integer.value;
+	acpi_ut_remove_reference (operand_desc);
+
+	/*
+	 * Get the address and save it
+	 * (at top of stack - 1)
+	 */
+	operand_desc = walk_state->operands[walk_state->num_operands - 2];
+
+	obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value;
+	acpi_ut_remove_reference (operand_desc);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
+		obj_desc,
+		ACPI_FORMAT_UINT64 (obj_desc->region.address),
+		obj_desc->region.length));
+
+	/* Now the address and length are valid for this opregion */
+
+	obj_desc->region.flags |= AOPOBJ_DATA_VALID;
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_eval_data_object_operands
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *              Op              - A valid data_object Op object
+ *              obj_desc        - data_object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get the operands and complete the following data object types:
+ *              Buffer, Package.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_eval_data_object_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	union acpi_operand_object       *obj_desc)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *arg_desc;
+	u32                             length;
+
+
+	ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands");
+
+
+	/* The first operand (for all of these data objects) is the length */
+
+	status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ex_resolve_operands (walk_state->opcode,
+			  &(walk_state->operands [walk_state->num_operands -1]),
+			  walk_state);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Extract length operand */
+
+	arg_desc = walk_state->operands [walk_state->num_operands - 1];
+	length = (u32) arg_desc->integer.value;
+
+	/* Cleanup for length operand */
+
+	status = acpi_ds_obj_stack_pop (1, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	acpi_ut_remove_reference (arg_desc);
+
+	/*
+	 * Create the actual data object
+	 */
+	switch (op->common.aml_opcode) {
+	case AML_BUFFER_OP:
+
+		status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc);
+		break;
+
+	case AML_PACKAGE_OP:
+	case AML_VAR_PACKAGE_OP:
+
+		status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc);
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+	}
+
+	if (ACPI_SUCCESS (status)) {
+		/*
+		 * Return the object in the walk_state, unless the parent is a package --
+		 * in this case, the return object will be stored in the parse tree
+		 * for the package.
+		 */
+		if ((!op->common.parent) ||
+			((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
+			 (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) &&
+			 (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
+			walk_state->result_obj = obj_desc;
+		}
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_exec_begin_control_op
+ *
+ * PARAMETERS:  walk_list       - The list that owns the walk stack
+ *              Op              - The control Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ *              execution.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_exec_begin_control_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_generic_state        *control_state;
+
+
+	ACPI_FUNCTION_NAME ("ds_exec_begin_control_op");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
+		op->common.aml_opcode, walk_state));
+
+	switch (op->common.aml_opcode) {
+	case AML_IF_OP:
+	case AML_WHILE_OP:
+
+		/*
+		 * IF/WHILE: Create a new control state to manage these
+		 * constructs. We need to manage these as a stack, in order
+		 * to handle nesting.
+		 */
+		control_state = acpi_ut_create_control_state ();
+		if (!control_state) {
+			status = AE_NO_MEMORY;
+			break;
+		}
+		/*
+		 * Save a pointer to the predicate for multiple executions
+		 * of a loop
+		 */
+		control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1;
+		control_state->control.package_end = walk_state->parser_state.pkg_end;
+		control_state->control.opcode = op->common.aml_opcode;
+
+
+		/* Push the control state on this walk's control stack */
+
+		acpi_ut_push_generic_state (&walk_state->control_state, control_state);
+		break;
+
+	case AML_ELSE_OP:
+
+		/* Predicate is in the state object */
+		/* If predicate is true, the IF was executed, ignore ELSE part */
+
+		if (walk_state->last_predicate) {
+			status = AE_CTRL_TRUE;
+		}
+
+		break;
+
+	case AML_RETURN_OP:
+
+		break;
+
+	default:
+		break;
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_exec_end_control_op
+ *
+ * PARAMETERS:  walk_list       - The list that owns the walk stack
+ *              Op              - The control Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ *              execution.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_exec_end_control_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_generic_state        *control_state;
+
+
+	ACPI_FUNCTION_NAME ("ds_exec_end_control_op");
+
+
+	switch (op->common.aml_opcode) {
+	case AML_IF_OP:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
+
+		/*
+		 * Save the result of the predicate in case there is an
+		 * ELSE to come
+		 */
+		walk_state->last_predicate =
+			(u8) walk_state->control_state->common.value;
+
+		/*
+		 * Pop the control state that was created at the start
+		 * of the IF and free it
+		 */
+		control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
+		acpi_ut_delete_generic_state (control_state);
+		break;
+
+
+	case AML_ELSE_OP:
+
+		break;
+
+
+	case AML_WHILE_OP:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
+
+		if (walk_state->control_state->common.value) {
+			/* Predicate was true, go back and evaluate it again! */
+
+			status = AE_CTRL_PENDING;
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op));
+
+		/* Pop this control state and free it */
+
+		control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
+
+		walk_state->aml_last_while = control_state->control.aml_predicate_start;
+		acpi_ut_delete_generic_state (control_state);
+		break;
+
+
+	case AML_RETURN_OP:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg));
+
+		/*
+		 * One optional operand -- the return value
+		 * It can be either an immediate operand or a result that
+		 * has been bubbled up the tree
+		 */
+		if (op->common.value.arg) {
+			/* Since we have a real Return(), delete any implicit return */
+
+			acpi_ds_clear_implicit_return (walk_state);
+
+			/* Return statement has an immediate operand */
+
+			status = acpi_ds_create_operands (walk_state, op->common.value.arg);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			/*
+			 * If value being returned is a Reference (such as
+			 * an arg or local), resolve it now because it may
+			 * cease to exist at the end of the method.
+			 */
+			status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			/*
+			 * Get the return value and save as the last result
+			 * value.  This is the only place where walk_state->return_desc
+			 * is set to anything other than zero!
+			 */
+			walk_state->return_desc = walk_state->operands[0];
+		}
+		else if ((walk_state->results) &&
+				 (walk_state->results->results.num_results > 0)) {
+			/* Since we have a real Return(), delete any implicit return */
+
+			acpi_ds_clear_implicit_return (walk_state);
+
+			/*
+			 * The return value has come from a previous calculation.
+			 *
+			 * If value being returned is a Reference (such as
+			 * an arg or local), resolve it now because it may
+			 * cease to exist at the end of the method.
+			 *
+			 * Allow references created by the Index operator to return unchanged.
+			 */
+			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])->reference.opcode != AML_INDEX_OP)) {
+				status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
+				if (ACPI_FAILURE (status)) {
+					return (status);
+				}
+			}
+
+			walk_state->return_desc = walk_state->results->results.obj_desc [0];
+		}
+		else {
+			/* No return operand */
+
+			if (walk_state->num_operands) {
+				acpi_ut_remove_reference (walk_state->operands [0]);
+			}
+
+			walk_state->operands [0]    = NULL;
+			walk_state->num_operands    = 0;
+			walk_state->return_desc     = NULL;
+		}
+
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"Completed RETURN_OP State=%p, ret_val=%p\n",
+			walk_state, walk_state->return_desc));
+
+		/* End the control method execution right now */
+
+		status = AE_CTRL_TERMINATE;
+		break;
+
+
+	case AML_NOOP_OP:
+
+		/* Just do nothing! */
+		break;
+
+
+	case AML_BREAK_POINT_OP:
+
+		/* Call up to the OS service layer to handle this */
+
+		status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
+
+		/* If and when it returns, all done. */
+
+		break;
+
+
+	case AML_BREAK_OP:
+	case AML_CONTINUE_OP: /* ACPI 2.0 */
+
+
+		/* Pop and delete control states until we find a while */
+
+		while (walk_state->control_state &&
+				(walk_state->control_state->control.opcode != AML_WHILE_OP)) {
+			control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
+			acpi_ut_delete_generic_state (control_state);
+		}
+
+		/* No while found? */
+
+		if (!walk_state->control_state) {
+			return (AE_AML_NO_WHILE);
+		}
+
+		/* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
+
+		walk_state->aml_last_while = walk_state->control_state->control.package_end;
+
+		/* Return status depending on opcode */
+
+		if (op->common.aml_opcode == AML_BREAK_OP) {
+			status = AE_CTRL_BREAK;
+		}
+		else {
+			status = AE_CTRL_CONTINUE;
+		}
+		break;
+
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
+			op->common.aml_opcode, op));
+
+		status = AE_AML_BAD_OPCODE;
+		break;
+	}
+
+	return (status);
+}
+
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
new file mode 100644
index 0000000..462c5d8
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -0,0 +1,744 @@
+/*******************************************************************************
+ *
+ * Module Name: dsutils - Dispatcher utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdebug.h>
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_clear_implicit_return
+ *
+ * PARAMETERS:  walk_state          - Current State
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Clear and remove a reference on an implicit return value.  Used
+ *              to delete "stale" return values (if enabled, the return value
+ *              from every operator is saved at least momentarily, in case the
+ *              parent method exits.)
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_clear_implicit_return (
+	struct acpi_walk_state          *walk_state)
+{
+	ACPI_FUNCTION_NAME ("ds_clear_implicit_return");
+
+
+	/*
+	 * Slack must be enabled for this feature
+	 */
+	if (!acpi_gbl_enable_interpreter_slack) {
+		return;
+	}
+
+	if (walk_state->implicit_return_obj) {
+		/*
+		 * Delete any "stale" implicit return. However, in
+		 * complex statements, the implicit return value can be
+		 * bubbled up several levels.
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"Removing reference on stale implicit return obj %p\n",
+			walk_state->implicit_return_obj));
+
+		acpi_ut_remove_reference (walk_state->implicit_return_obj);
+		walk_state->implicit_return_obj = NULL;
+	}
+}
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_do_implicit_return
+ *
+ * PARAMETERS:  return_desc         - The return value
+ *              walk_state          - Current State
+ *              add_reference       - True if a reference should be added to the
+ *                                    return object
+ *
+ * RETURN:      TRUE if implicit return enabled, FALSE otherwise
+ *
+ * DESCRIPTION: Implements the optional "implicit return".  We save the result
+ *              of every ASL operator and control method invocation in case the
+ *              parent method exit.  Before storing a new return value, we
+ *              delete the previous return value.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ds_do_implicit_return (
+	union acpi_operand_object       *return_desc,
+	struct acpi_walk_state          *walk_state,
+	u8                              add_reference)
+{
+	ACPI_FUNCTION_NAME ("ds_do_implicit_return");
+
+
+	/*
+	 * Slack must be enabled for this feature, and we must
+	 * have a valid return object
+	 */
+	if ((!acpi_gbl_enable_interpreter_slack) ||
+		(!return_desc)) {
+		return (FALSE);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"Result %p will be implicitly returned; Prev=%p\n",
+			return_desc,
+			walk_state->implicit_return_obj));
+
+	/*
+	 * Delete any "stale" implicit return value first. However, in
+	 * complex statements, the implicit return value can be
+	 * bubbled up several levels, so we don't clear the value if it
+	 * is the same as the return_desc.
+	 */
+	if (walk_state->implicit_return_obj) {
+		if (walk_state->implicit_return_obj == return_desc) {
+			return (TRUE);
+		}
+		acpi_ds_clear_implicit_return (walk_state);
+	}
+
+	/* Save the implicit return value, add a reference if requested */
+
+	walk_state->implicit_return_obj = return_desc;
+	if (add_reference) {
+		acpi_ut_add_reference (return_desc);
+	}
+
+	return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_is_result_used
+ *
+ * PARAMETERS:  Op                  - Current Op
+ *              walk_state          - Current State
+ *
+ * RETURN:      TRUE if result is used, FALSE otherwise
+ *
+ * DESCRIPTION: Check if a result object will be used by the parent
+ *
+ ******************************************************************************/
+
+u8
+acpi_ds_is_result_used (
+	union acpi_parse_object         *op,
+	struct acpi_walk_state          *walk_state)
+{
+	const struct acpi_opcode_info   *parent_info;
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op);
+
+
+	/* Must have both an Op and a Result Object */
+
+	if (!op) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
+		return_VALUE (TRUE);
+	}
+
+	/*
+	 * We know that this operator is not a
+	 * Return() operator (would not come here.) The following code is the
+	 * optional support for a so-called "implicit return". Some AML code
+	 * assumes that the last value of the method is "implicitly" returned
+	 * to the caller. Just save the last result as the return value.
+	 * NOTE: this is optional because the ASL language does not actually
+	 * support this behavior.
+	 */
+	acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
+
+	/*
+	 * Now determine if the parent will use the result
+	 *
+	 * If there is no parent, or the parent is a scope_op, we are executing
+	 * at the method level. An executing method typically has no parent,
+	 * since each method is parsed separately.  A method invoked externally
+	 * via execute_control_method has a scope_op as the parent.
+	 */
+	if ((!op->common.parent) ||
+		(op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
+		/* No parent, the return value cannot possibly be used */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "At Method level, result of [%s] not used\n",
+				acpi_ps_get_opcode_name (op->common.aml_opcode)));
+		return_VALUE (FALSE);
+	}
+
+	/* Get info on the parent. The root_op is AML_SCOPE */
+
+	parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
+	if (parent_info->class == AML_CLASS_UNKNOWN) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op));
+		return_VALUE (FALSE);
+	}
+
+	/*
+	 * Decide what to do with the result based on the parent.  If
+	 * the parent opcode will not use the result, delete the object.
+	 * Otherwise leave it as is, it will be deleted when it is used
+	 * as an operand later.
+	 */
+	switch (parent_info->class) {
+	case AML_CLASS_CONTROL:
+
+		switch (op->common.parent->common.aml_opcode) {
+		case AML_RETURN_OP:
+
+			/* Never delete the return value associated with a return opcode */
+
+			goto result_used;
+
+		case AML_IF_OP:
+		case AML_WHILE_OP:
+
+			/*
+			 * If we are executing the predicate AND this is the predicate op,
+			 * we will use the return value
+			 */
+			if ((walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING) &&
+				(walk_state->control_state->control.predicate_op == op)) {
+				goto result_used;
+			}
+			break;
+
+		default:
+			/* Ignore other control opcodes */
+			break;
+		}
+
+		/* The general control opcode returns no result */
+
+		goto result_not_used;
+
+
+	case AML_CLASS_CREATE:
+
+		/*
+		 * These opcodes allow term_arg(s) as operands and therefore
+		 * the operands can be method calls.  The result is used.
+		 */
+		goto result_used;
+
+
+	case AML_CLASS_NAMED_OBJECT:
+
+		if ((op->common.parent->common.aml_opcode == AML_REGION_OP)      ||
+			(op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
+			(op->common.parent->common.aml_opcode == AML_PACKAGE_OP)     ||
+			(op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
+			(op->common.parent->common.aml_opcode == AML_BUFFER_OP)      ||
+			(op->common.parent->common.aml_opcode == AML_INT_EVAL_SUBTREE_OP)) {
+			/*
+			 * These opcodes allow term_arg(s) as operands and therefore
+			 * the operands can be method calls.  The result is used.
+			 */
+			goto result_used;
+		}
+
+		goto result_not_used;
+
+
+	default:
+
+		/*
+		 * In all other cases. the parent will actually use the return
+		 * object, so keep it.
+		 */
+		goto result_used;
+	}
+
+
+result_used:
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] used by Parent [%s] Op=%p\n",
+			acpi_ps_get_opcode_name (op->common.aml_opcode),
+			acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+
+	return_VALUE (TRUE);
+
+
+result_not_used:
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] not used by Parent [%s] Op=%p\n",
+			acpi_ps_get_opcode_name (op->common.aml_opcode),
+			acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+
+	return_VALUE (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_delete_result_if_not_used
+ *
+ * PARAMETERS:  Op              - Current parse Op
+ *              result_obj      - Result of the operation
+ *              walk_state      - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Used after interpretation of an opcode.  If there is an internal
+ *              result descriptor, check if the parent opcode will actually use
+ *              this result.  If not, delete the result now so that it will
+ *              not become orphaned.
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_delete_result_if_not_used (
+	union acpi_parse_object         *op,
+	union acpi_operand_object       *result_obj,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_delete_result_if_not_used", result_obj);
+
+
+	if (!op) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
+		return_VOID;
+	}
+
+	if (!result_obj) {
+		return_VOID;
+	}
+
+	if (!acpi_ds_is_result_used (op, walk_state)) {
+		/* Must pop the result stack (obj_desc should be equal to result_obj) */
+
+		status = acpi_ds_result_pop (&obj_desc, walk_state);
+		if (ACPI_SUCCESS (status)) {
+			acpi_ut_remove_reference (result_obj);
+		}
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_resolve_operands
+ *
+ * PARAMETERS:  walk_state          - Current walk state with operands on stack
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Resolve all operands to their values.  Used to prepare
+ *              arguments to a control method invocation (a call from one
+ *              method to another.)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_resolve_operands (
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             i;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_resolve_operands", walk_state);
+
+
+	/*
+	 * Attempt to resolve each of the valid operands
+	 * Method arguments are passed by reference, not by value.  This means
+	 * that the actual objects are passed, not copies of the objects.
+	 */
+	for (i = 0; i < walk_state->num_operands; i++) {
+		status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state);
+		if (ACPI_FAILURE (status)) {
+			break;
+		}
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_clear_operands
+ *
+ * PARAMETERS:  walk_state          - Current walk state with operands on stack
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Clear all operands on the current walk state operand stack.
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_clear_operands (
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state);
+
+
+	/* Remove a reference on each operand on the stack */
+
+	for (i = 0; i < walk_state->num_operands; i++) {
+		/*
+		 * Remove a reference to all operands, including both
+		 * "Arguments" and "Targets".
+		 */
+		acpi_ut_remove_reference (walk_state->operands[i]);
+		walk_state->operands[i] = NULL;
+	}
+
+	walk_state->num_operands = 0;
+	return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_operand
+ *
+ * PARAMETERS:  walk_state      - Current walk state
+ *              Arg             - Parse object for the argument
+ *              arg_index       - Which argument (zero based)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a parse tree object that is an argument to an AML
+ *              opcode to the equivalent interpreter object.  This may include
+ *              looking up a name or entering a new name into the internal
+ *              namespace.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_create_operand (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *arg,
+	u32                             arg_index)
+{
+	acpi_status                     status = AE_OK;
+	char                            *name_string;
+	u32                             name_length;
+	union acpi_operand_object       *obj_desc;
+	union acpi_parse_object         *parent_op;
+	u16                             opcode;
+	acpi_interpreter_mode           interpreter_mode;
+	const struct acpi_opcode_info   *op_info;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_create_operand", arg);
+
+
+	/* A valid name must be looked up in the namespace */
+
+	if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
+		(arg->common.value.string)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", arg));
+
+		/* Get the entire name string from the AML stream */
+
+		status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->common.value.buffer,
+				  &name_string, &name_length);
+
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* All prefixes have been handled, and the name is in name_string */
+
+		/*
+		 * Special handling for buffer_field declarations. This is a deferred
+		 * opcode that unfortunately defines the field name as the last
+		 * parameter instead of the first.  We get here when we are performing
+		 * the deferred execution, so the actual name of the field is already
+		 * in the namespace.  We don't want to attempt to look it up again
+		 * because we may be executing in a different scope than where the
+		 * actual opcode exists.
+		 */
+		if ((walk_state->deferred_node) &&
+			(walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
+			(arg_index != 0)) {
+			obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node);
+			status = AE_OK;
+		}
+		else    /* All other opcodes */ {
+			/*
+			 * Differentiate between a namespace "create" operation
+			 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
+			 * IMODE_EXECUTE) in order to support the creation of
+			 * namespace objects during the execution of control methods.
+			 */
+			parent_op = arg->common.parent;
+			op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode);
+			if ((op_info->flags & AML_NSNODE) &&
+				(parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) &&
+				(parent_op->common.aml_opcode != AML_REGION_OP) &&
+				(parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) {
+				/* Enter name into namespace if not found */
+
+				interpreter_mode = ACPI_IMODE_LOAD_PASS2;
+			}
+			else {
+				/* Return a failure if name not found */
+
+				interpreter_mode = ACPI_IMODE_EXECUTE;
+			}
+
+			status = acpi_ns_lookup (walk_state->scope_info, name_string,
+					 ACPI_TYPE_ANY, interpreter_mode,
+					 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+					 walk_state,
+					 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc));
+			/*
+			 * The only case where we pass through (ignore) a NOT_FOUND
+			 * error is for the cond_ref_of opcode.
+			 */
+			if (status == AE_NOT_FOUND) {
+				if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) {
+					/*
+					 * For the Conditional Reference op, it's OK if
+					 * the name is not found;  We just need a way to
+					 * indicate this to the interpreter, set the
+					 * object to the root
+					 */
+					obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node);
+					status = AE_OK;
+				}
+				else {
+					/*
+					 * We just plain didn't find it -- which is a
+					 * very serious error at this point
+					 */
+					status = AE_AML_NAME_NOT_FOUND;
+				}
+			}
+
+			if (ACPI_FAILURE (status)) {
+				ACPI_REPORT_NSERROR (name_string, status);
+			}
+		}
+
+		/* Free the namestring created above */
+
+		ACPI_MEM_FREE (name_string);
+
+		/* Check status from the lookup */
+
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* Put the resulting object onto the current object stack */
+
+		status = acpi_ds_obj_stack_push (obj_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+		ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
+	}
+	else {
+		/* Check for null name case */
+
+		if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) {
+			/*
+			 * If the name is null, this means that this is an
+			 * optional result parameter that was not specified
+			 * in the original ASL.  Create a Zero Constant for a
+			 * placeholder.  (Store to a constant is a Noop.)
+			 */
+			opcode = AML_ZERO_OP;       /* Has no arguments! */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg));
+		}
+		else {
+			opcode = arg->common.aml_opcode;
+		}
+
+		/* Get the object type of the argument */
+
+		op_info = acpi_ps_get_opcode_info (opcode);
+		if (op_info->object_type == ACPI_TYPE_INVALID) {
+			return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+		}
+
+		if (op_info->flags & AML_HAS_RETVAL) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+				"Argument previously created, already stacked \n"));
+
+			ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (
+				walk_state->operands [walk_state->num_operands - 1], walk_state));
+
+			/*
+			 * Use value that was already previously returned
+			 * by the evaluation of this argument
+			 */
+			status = acpi_ds_result_pop_from_bottom (&obj_desc, walk_state);
+			if (ACPI_FAILURE (status)) {
+				/*
+				 * Only error is underflow, and this indicates
+				 * a missing or null operand!
+				 */
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Missing or null operand, %s\n",
+					acpi_format_exception (status)));
+				return_ACPI_STATUS (status);
+			}
+		}
+		else {
+			/* Create an ACPI_INTERNAL_OBJECT for the argument */
+
+			obj_desc = acpi_ut_create_internal_object (op_info->object_type);
+			if (!obj_desc) {
+				return_ACPI_STATUS (AE_NO_MEMORY);
+			}
+
+			/* Initialize the new object */
+
+			status = acpi_ds_init_object_from_op (walk_state, arg,
+					 opcode, &obj_desc);
+			if (ACPI_FAILURE (status)) {
+				acpi_ut_delete_object_desc (obj_desc);
+				return_ACPI_STATUS (status);
+			}
+		}
+
+		/* Put the operand object on the object stack */
+
+		status = acpi_ds_obj_stack_push (obj_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_operands
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              first_arg           - First argument of a parser argument tree
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an operator's arguments from a parse tree format to
+ *              namespace objects and place those argument object on the object
+ *              stack in preparation for evaluation by the interpreter.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_create_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *first_arg)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_parse_object         *arg;
+	u32                             arg_count = 0;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_create_operands", first_arg);
+
+
+	/* For all arguments in the list... */
+
+	arg = first_arg;
+	while (arg) {
+		status = acpi_ds_create_operand (walk_state, arg, arg_count);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%d (%p) done, Arg1=%p\n",
+			arg_count, arg, first_arg));
+
+		/* Move on to next argument, if any */
+
+		arg = arg->common.next;
+		arg_count++;
+	}
+
+	return_ACPI_STATUS (status);
+
+
+cleanup:
+	/*
+	 * We must undo everything done above; meaning that we must
+	 * pop everything off of the operand stack and delete those
+	 * objects
+	 */
+	(void) acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While creating Arg %d - %s\n",
+		(arg_count + 1), acpi_format_exception (status)));
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
new file mode 100644
index 0000000..2071a0d
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -0,0 +1,751 @@
+/******************************************************************************
+ *
+ * Module Name: dswexec - Dispatcher method execution callbacks;
+ *                        dispatch to interpreter.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdebug.h>
+#include <acpi/acdisasm.h>
+
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dswexec")
+
+/*
+ * Dispatch table for opcode classes
+ */
+static ACPI_EXECUTE_OP      acpi_gbl_op_type_dispatch [] = {
+			  acpi_ex_opcode_0A_0T_1R,
+			  acpi_ex_opcode_1A_0T_0R,
+			  acpi_ex_opcode_1A_0T_1R,
+			  acpi_ex_opcode_1A_1T_0R,
+			  acpi_ex_opcode_1A_1T_1R,
+			  acpi_ex_opcode_2A_0T_0R,
+			  acpi_ex_opcode_2A_0T_1R,
+			  acpi_ex_opcode_2A_1T_1R,
+			  acpi_ex_opcode_2A_2T_1R,
+			  acpi_ex_opcode_3A_0T_0R,
+			  acpi_ex_opcode_3A_1T_1R,
+			  acpi_ex_opcode_6A_0T_1R};
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_get_predicate_value
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get the result of a predicate evaluation
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_get_predicate_value (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *result_obj) {
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *local_obj_desc = NULL;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_get_predicate_value", walk_state);
+
+
+	walk_state->control_state->common.state = 0;
+
+	if (result_obj) {
+		status = acpi_ds_result_pop (&obj_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not get result from predicate evaluation, %s\n",
+				acpi_format_exception (status)));
+
+			return_ACPI_STATUS (status);
+		}
+	}
+	else {
+		status = acpi_ds_create_operand (walk_state, walk_state->op, 0);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		obj_desc = walk_state->operands [0];
+	}
+
+	if (!obj_desc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No predicate obj_desc=%p State=%p\n",
+			obj_desc, walk_state));
+
+		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+	}
+
+	/*
+	 * Result of predicate evaluation must be an Integer
+	 * object. Implicitly convert the argument if necessary.
+	 */
+	status = acpi_ex_convert_to_integer (obj_desc, &local_obj_desc, 16);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (local_obj_desc) != ACPI_TYPE_INTEGER) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
+			obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc)));
+
+		status = AE_AML_OPERAND_TYPE;
+		goto cleanup;
+	}
+
+	/* Truncate the predicate to 32-bits if necessary */
+
+	acpi_ex_truncate_for32bit_table (local_obj_desc);
+
+	/*
+	 * Save the result of the predicate evaluation on
+	 * the control stack
+	 */
+	if (local_obj_desc->integer.value) {
+		walk_state->control_state->common.value = TRUE;
+	}
+	else {
+		/*
+		 * Predicate is FALSE, we will just toss the
+		 * rest of the package
+		 */
+		walk_state->control_state->common.value = FALSE;
+		status = AE_CTRL_FALSE;
+	}
+
+
+cleanup:
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
+		walk_state->control_state->common.value, walk_state->op));
+
+	 /* Break to debugger to display result */
+
+	ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (local_obj_desc, walk_state));
+
+	/*
+	 * Delete the predicate result object (we know that
+	 * we don't need it anymore)
+	 */
+	if (local_obj_desc != obj_desc) {
+		acpi_ut_remove_reference (local_obj_desc);
+	}
+	acpi_ut_remove_reference (obj_desc);
+
+	walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_exec_begin_op
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              out_op          - Return op if a new one is created
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Descending callback used during the execution of control
+ *              methods.  This is where most operators and operands are
+ *              dispatched to the interpreter.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_exec_begin_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         **out_op)
+{
+	union acpi_parse_object         *op;
+	acpi_status                     status = AE_OK;
+	u32                             opcode_class;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_exec_begin_op", walk_state);
+
+
+	op = walk_state->op;
+	if (!op) {
+		status = acpi_ds_load2_begin_op (walk_state, out_op);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		op = *out_op;
+		walk_state->op = op;
+		walk_state->opcode = op->common.aml_opcode;
+		walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+
+		if (acpi_ns_opens_scope (walk_state->op_info->object_type)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
+				acpi_ut_get_type_name (walk_state->op_info->object_type), op));
+
+			status = acpi_ds_scope_stack_pop (walk_state);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+	}
+
+	if (op == walk_state->origin) {
+		if (out_op) {
+			*out_op = op;
+		}
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * If the previous opcode was a conditional, this opcode
+	 * must be the beginning of the associated predicate.
+	 * Save this knowledge in the current scope descriptor
+	 */
+	if ((walk_state->control_state) &&
+		(walk_state->control_state->common.state ==
+			ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
+				  op, walk_state));
+
+		walk_state->control_state->common.state = ACPI_CONTROL_PREDICATE_EXECUTING;
+
+		/* Save start of predicate */
+
+		walk_state->control_state->control.predicate_op = op;
+	}
+
+
+	opcode_class = walk_state->op_info->class;
+
+	/* We want to send namepaths to the load code */
+
+	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
+		opcode_class = AML_CLASS_NAMED_OBJECT;
+	}
+
+	/*
+	 * Handle the opcode based upon the opcode type
+	 */
+	switch (opcode_class) {
+	case AML_CLASS_CONTROL:
+
+		status = acpi_ds_result_stack_push (walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		status = acpi_ds_exec_begin_control_op (walk_state, op);
+		break;
+
+
+	case AML_CLASS_NAMED_OBJECT:
+
+		if (walk_state->walk_type == ACPI_WALK_METHOD) {
+			/*
+			 * Found a named object declaration during method
+			 * execution;  we must enter this object into the
+			 * namespace.  The created object is temporary and
+			 * will be deleted upon completion of the execution
+			 * of this method.
+			 */
+			status = acpi_ds_load2_begin_op (walk_state, NULL);
+		}
+
+		if (op->common.aml_opcode == AML_REGION_OP) {
+			status = acpi_ds_result_stack_push (walk_state);
+		}
+		break;
+
+
+	case AML_CLASS_EXECUTE:
+	case AML_CLASS_CREATE:
+
+		/*
+		 * Most operators with arguments.
+		 * Start a new result/operand state
+		 */
+		status = acpi_ds_result_stack_push (walk_state);
+		break;
+
+
+	default:
+		break;
+	}
+
+	/* Nothing to do here during method execution */
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_exec_end_op
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              Op              - Op that has been just been completed in the
+ *                                walk;  Arguments have now been evaluated.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Ascending callback used during the execution of control
+ *              methods.  The only thing we really need to do here is to
+ *              notice the beginning of IF, ELSE, and WHILE blocks.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ds_exec_end_op (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_parse_object         *op;
+	acpi_status                     status = AE_OK;
+	u32                             op_type;
+	u32                             op_class;
+	union acpi_parse_object         *next_op;
+	union acpi_parse_object         *first_arg;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_exec_end_op", walk_state);
+
+
+	op      = walk_state->op;
+	op_type = walk_state->op_info->type;
+	op_class = walk_state->op_info->class;
+
+	if (op_class == AML_CLASS_UNKNOWN) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->common.aml_opcode));
+		return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+	}
+
+	first_arg = op->common.value.arg;
+
+	/* Init the walk state */
+
+	walk_state->num_operands = 0;
+	walk_state->return_desc = NULL;
+	walk_state->result_obj = NULL;
+
+	/* Call debugger for single step support (DEBUG build only) */
+
+	ACPI_DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, op_class));
+	ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return_ACPI_STATUS (status);});
+
+	/* Decode the Opcode Class */
+
+	switch (op_class) {
+	case AML_CLASS_ARGUMENT:    /* constants, literals, etc. -- do nothing */
+		break;
+
+
+	case AML_CLASS_EXECUTE:     /* most operators with arguments */
+
+		/* Build resolved operand stack */
+
+		status = acpi_ds_create_operands (walk_state, first_arg);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		/* Done with this result state (Now that operand stack is built) */
+
+		status = acpi_ds_result_stack_pop (walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		/*
+		 * All opcodes require operand resolution, with the only exceptions
+		 * being the object_type and size_of operators.
+		 */
+		if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
+			/* Resolve all operands */
+
+			status = acpi_ex_resolve_operands (walk_state->opcode,
+					  &(walk_state->operands [walk_state->num_operands -1]),
+					  walk_state);
+			if (ACPI_SUCCESS (status)) {
+				ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
+						  acpi_ps_get_opcode_name (walk_state->opcode),
+						  walk_state->num_operands, "after ex_resolve_operands");
+			}
+		}
+
+		if (ACPI_SUCCESS (status)) {
+			/*
+			 * Dispatch the request to the appropriate interpreter handler
+			 * routine.  There is one routine per opcode "type" based upon the
+			 * number of opcode arguments and return type.
+			 */
+			status = acpi_gbl_op_type_dispatch[op_type] (walk_state);
+		}
+		else {
+			/*
+			 * Treat constructs of the form "Store(local_x,local_x)" as noops when the
+			 * Local is uninitialized.
+			 */
+			if  ((status == AE_AML_UNINITIALIZED_LOCAL) &&
+				(walk_state->opcode == AML_STORE_OP) &&
+				(walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+				(walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+				(walk_state->operands[0]->reference.opcode ==
+				 walk_state->operands[1]->reference.opcode) &&
+				(walk_state->operands[0]->reference.offset ==
+				 walk_state->operands[1]->reference.offset)) {
+				status = AE_OK;
+			}
+			else {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"[%s]: Could not resolve operands, %s\n",
+					acpi_ps_get_opcode_name (walk_state->opcode),
+					acpi_format_exception (status)));
+			}
+		}
+
+		/* Always delete the argument objects and clear the operand stack */
+
+		acpi_ds_clear_operands (walk_state);
+
+		/*
+		 * If a result object was returned from above, push it on the
+		 * current result stack
+		 */
+		if (ACPI_SUCCESS (status) &&
+			walk_state->result_obj) {
+			status = acpi_ds_result_push (walk_state->result_obj, walk_state);
+		}
+
+		break;
+
+
+	default:
+
+		switch (op_type) {
+		case AML_TYPE_CONTROL:    /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
+
+			/* 1 Operand, 0 external_result, 0 internal_result */
+
+			status = acpi_ds_exec_end_control_op (walk_state, op);
+
+			/* Make sure to properly pop the result stack */
+
+			if (ACPI_SUCCESS (status)) {
+				status = acpi_ds_result_stack_pop (walk_state);
+			}
+			else if (status == AE_CTRL_PENDING) {
+				status = acpi_ds_result_stack_pop (walk_state);
+				if (ACPI_SUCCESS (status)) {
+					status = AE_CTRL_PENDING;
+				}
+			}
+			break;
+
+
+		case AML_TYPE_METHOD_CALL:
+
+			/*
+			 * If the method is referenced from within a package
+			 * declaration, it is not a invocation of the method, just
+			 * a reference to it.
+			 */
+			if ((op->asl.parent) &&
+			   ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
+				(op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method Reference in a Package, Op=%p\n", op));
+				op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
+				acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
+				return_ACPI_STATUS (AE_OK);
+			}
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op));
+
+			/*
+			 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
+			 * the method Node pointer
+			 */
+			/* next_op points to the op that holds the method name */
+
+			next_op = first_arg;
+
+			/* next_op points to first argument op */
+
+			next_op = next_op->common.next;
+
+			/*
+			 * Get the method's arguments and put them on the operand stack
+			 */
+			status = acpi_ds_create_operands (walk_state, next_op);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+
+			/*
+			 * Since the operands will be passed to another control method,
+			 * we must resolve all local references here (Local variables,
+			 * arguments to *this* method, etc.)
+			 */
+			status = acpi_ds_resolve_operands (walk_state);
+			if (ACPI_FAILURE (status)) {
+				/* On error, clear all resolved operands */
+
+				acpi_ds_clear_operands (walk_state);
+				break;
+			}
+
+			/*
+			 * Tell the walk loop to preempt this running method and
+			 * execute the new method
+			 */
+			status = AE_CTRL_TRANSFER;
+
+			/*
+			 * Return now; we don't want to disturb anything,
+			 * especially the operand count!
+			 */
+			return_ACPI_STATUS (status);
+
+
+		case AML_TYPE_CREATE_FIELD:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"Executing create_field Buffer/Index Op=%p\n", op));
+
+			status = acpi_ds_load2_end_op (walk_state);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+
+			status = acpi_ds_eval_buffer_field_operands (walk_state, op);
+			break;
+
+
+		case AML_TYPE_CREATE_OBJECT:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"Executing create_object (Buffer/Package) Op=%p\n", op));
+
+			switch (op->common.parent->common.aml_opcode) {
+			case AML_NAME_OP:
+
+				/*
+				 * Put the Node on the object stack (Contains the ACPI Name of
+				 * this object)
+				 */
+				walk_state->operands[0] = (void *) op->common.parent->common.node;
+				walk_state->num_operands = 1;
+
+				status = acpi_ds_create_node (walk_state, op->common.parent->common.node, op->common.parent);
+				if (ACPI_FAILURE (status)) {
+					break;
+				}
+
+				/* Fall through */
+				/*lint -fallthrough */
+
+			case AML_INT_EVAL_SUBTREE_OP:
+
+				status = acpi_ds_eval_data_object_operands (walk_state, op,
+						  acpi_ns_get_attached_object (op->common.parent->common.node));
+				break;
+
+			default:
+
+				status = acpi_ds_eval_data_object_operands (walk_state, op, NULL);
+				break;
+			}
+
+			/* Done with this result state (Now that operand stack is built) */
+
+			status = acpi_ds_result_stack_pop (walk_state);
+			if (ACPI_FAILURE (status)) {
+				goto cleanup;
+			}
+
+			/*
+			 * If a result object was returned from above, push it on the
+			 * current result stack
+			 */
+			if (ACPI_SUCCESS (status) &&
+				walk_state->result_obj) {
+				status = acpi_ds_result_push (walk_state->result_obj, walk_state);
+			}
+			break;
+
+
+		case AML_TYPE_NAMED_FIELD:
+		case AML_TYPE_NAMED_COMPLEX:
+		case AML_TYPE_NAMED_SIMPLE:
+		case AML_TYPE_NAMED_NO_OBJ:
+
+			status = acpi_ds_load2_end_op (walk_state);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+
+			if (op->common.aml_opcode == AML_REGION_OP) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+					"Executing op_region Address/Length Op=%p\n", op));
+
+				status = acpi_ds_eval_region_operands (walk_state, op);
+				if (ACPI_FAILURE (status)) {
+					break;
+				}
+
+				status = acpi_ds_result_stack_pop (walk_state);
+			}
+
+			break;
+
+
+		case AML_TYPE_UNDEFINED:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Undefined opcode type Op=%p\n", op));
+			return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+
+
+		case AML_TYPE_BOGUS:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+				"Internal opcode=%X type Op=%p\n",
+				walk_state->opcode, op));
+			break;
+
+
+		default:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n",
+				op_class, op_type, op->common.aml_opcode, op));
+
+			status = AE_NOT_IMPLEMENTED;
+			break;
+		}
+	}
+
+	/*
+	 * ACPI 2.0 support for 64-bit integers: Truncate numeric
+	 * result value if we are executing from a 32-bit ACPI table
+	 */
+	acpi_ex_truncate_for32bit_table (walk_state->result_obj);
+
+	/*
+	 * Check if we just completed the evaluation of a
+	 * conditional predicate
+	 */
+
+	if ((ACPI_SUCCESS (status)) &&
+		(walk_state->control_state) &&
+		(walk_state->control_state->common.state ==
+			ACPI_CONTROL_PREDICATE_EXECUTING) &&
+		(walk_state->control_state->control.predicate_op == op)) {
+		status = acpi_ds_get_predicate_value (walk_state, walk_state->result_obj);
+		walk_state->result_obj = NULL;
+	}
+
+
+cleanup:
+
+	/* Invoke exception handler on error */
+
+	if (ACPI_FAILURE (status) &&
+		acpi_gbl_exception_handler &&
+		!(status & AE_CODE_CONTROL)) {
+		acpi_ex_exit_interpreter ();
+		status = acpi_gbl_exception_handler (status,
+				 walk_state->method_node->name.integer, walk_state->opcode,
+				 walk_state->aml_offset, NULL);
+		acpi_ex_enter_interpreter ();
+	}
+
+	if (walk_state->result_obj) {
+		/* Break to debugger to display result */
+
+		ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj, walk_state));
+
+		/*
+		 * Delete the result op if and only if:
+		 * Parent will not use the result -- such as any
+		 * non-nested type2 op in a method (parent will be method)
+		 */
+		acpi_ds_delete_result_if_not_used (op, walk_state->result_obj, walk_state);
+	}
+
+#ifdef _UNDER_DEVELOPMENT
+
+	if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) {
+		acpi_db_method_end (walk_state);
+	}
+#endif
+
+	/* Always clear the object stack */
+
+	walk_state->num_operands = 0;
+
+#ifdef ACPI_DISASSEMBLER
+
+	/* On error, display method locals/args */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_dm_dump_method_info (status, walk_state, op);
+	}
+#endif
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
new file mode 100644
index 0000000..06d7586
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -0,0 +1,976 @@
+/******************************************************************************
+ *
+ * Module Name: dswload - Dispatcher namespace load callbacks
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+
+#ifdef _ACPI_ASL_COMPILER
+#include <acpi/acdisasm.h>
+#endif
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dswload")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_init_callbacks
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              pass_number     - 1, 2, or 3
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Init walk state callbacks
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_init_callbacks (
+	struct acpi_walk_state          *walk_state,
+	u32                             pass_number)
+{
+
+	switch (pass_number) {
+	case 1:
+		walk_state->parse_flags       = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
+		walk_state->descending_callback = acpi_ds_load1_begin_op;
+		walk_state->ascending_callback = acpi_ds_load1_end_op;
+		break;
+
+	case 2:
+		walk_state->parse_flags       = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
+		walk_state->descending_callback = acpi_ds_load2_begin_op;
+		walk_state->ascending_callback = acpi_ds_load2_end_op;
+		break;
+
+	case 3:
+#ifndef ACPI_NO_METHOD_EXECUTION
+		walk_state->parse_flags      |= ACPI_PARSE_EXECUTE  | ACPI_PARSE_DELETE_TREE;
+		walk_state->descending_callback = acpi_ds_exec_begin_op;
+		walk_state->ascending_callback = acpi_ds_exec_end_op;
+#endif
+		break;
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_load1_begin_op
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              Op              - Op that has been just been reached in the
+ *                                walk;  Arguments have not been evaluated yet.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Descending callback used during the loading of ACPI tables.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_load1_begin_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         **out_op)
+{
+	union acpi_parse_object         *op;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+	acpi_object_type                object_type;
+	char                            *path;
+	u32                             flags;
+
+
+	ACPI_FUNCTION_NAME ("ds_load1_begin_op");
+
+
+	op = walk_state->op;
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
+
+	/* We are only interested in opcodes that have an associated name */
+
+	if (op) {
+		if (!(walk_state->op_info->flags & AML_NAMED)) {
+#if 0
+			if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
+				(walk_state->op_info->class == AML_CLASS_CONTROL)) {
+				acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n", walk_state->op_info->name);
+				*out_op = op;
+				return (AE_CTRL_SKIP);
+			}
+#endif
+			*out_op = op;
+			return (AE_OK);
+		}
+
+		/* Check if this object has already been installed in the namespace */
+
+		if (op->common.node) {
+			*out_op = op;
+			return (AE_OK);
+		}
+	}
+
+	path = acpi_ps_get_next_namestring (&walk_state->parser_state);
+
+	/* Map the raw opcode into an internal object type */
+
+	object_type = walk_state->op_info->object_type;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name (object_type)));
+
+	switch (walk_state->opcode) {
+	case AML_SCOPE_OP:
+
+		/*
+		 * The target name of the Scope() operator must exist at this point so
+		 * that we can actually open the scope to enter new names underneath it.
+		 * Allow search-to-root for single namesegs.
+		 */
+		status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
+				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+#ifdef _ACPI_ASL_COMPILER
+		if (status == AE_NOT_FOUND) {
+			/*
+			 * Table disassembly:
+			 * Target of Scope() not found.  Generate an External for it, and
+			 * insert the name into the namespace.
+			 */
+			acpi_dm_add_to_external_list (path);
+			status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
+					   ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+		}
+#endif
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_NSERROR (path, status);
+			return (status);
+		}
+
+		/*
+		 * Check to make sure that the target is
+		 * one of the opcodes that actually opens a scope
+		 */
+		switch (node->type) {
+		case ACPI_TYPE_LOCAL_SCOPE:         /* Scope  */
+		case ACPI_TYPE_DEVICE:
+		case ACPI_TYPE_POWER:
+		case ACPI_TYPE_PROCESSOR:
+		case ACPI_TYPE_THERMAL:
+
+			/* These are acceptable types */
+			break;
+
+		case ACPI_TYPE_INTEGER:
+		case ACPI_TYPE_STRING:
+		case ACPI_TYPE_BUFFER:
+
+			/*
+			 * These types we will allow, but we will change the type.  This
+			 * enables some existing code of the form:
+			 *
+			 *  Name (DEB, 0)
+			 *  Scope (DEB) { ... }
+			 *
+			 * Note: silently change the type here.  On the second pass, we will report a warning
+			 */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
+				path, acpi_ut_get_type_name (node->type)));
+
+			node->type = ACPI_TYPE_ANY;
+			walk_state->scope_info->common.value = ACPI_TYPE_ANY;
+			break;
+
+		default:
+
+			/* All other types are an error */
+
+			ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n",
+				acpi_ut_get_type_name (node->type), path));
+
+			return (AE_AML_OPERAND_TYPE);
+		}
+		break;
+
+
+	default:
+
+		/*
+		 * For all other named opcodes, we will enter the name into the namespace.
+		 *
+		 * Setup the search flags.
+		 * Since we are entering a name into the namespace, we do not want to
+		 * enable the search-to-root upsearch.
+		 *
+		 * There are only two conditions where it is acceptable that the name
+		 * already exists:
+		 *    1) the Scope() operator can reopen a scoping object that was
+		 *       previously defined (Scope, Method, Device, etc.)
+		 *    2) Whenever we are parsing a deferred opcode (op_region, Buffer,
+		 *       buffer_field, or Package), the name of the object is already
+		 *       in the namespace.
+		 */
+		if (walk_state->deferred_node) {
+			/* This name is already in the namespace, get the node */
+
+			node = walk_state->deferred_node;
+			status = AE_OK;
+			break;
+		}
+
+		flags = ACPI_NS_NO_UPSEARCH;
+		if ((walk_state->opcode != AML_SCOPE_OP) &&
+			(!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
+			flags |= ACPI_NS_ERROR_IF_FOUND;
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
+					acpi_ut_get_type_name (object_type)));
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n",
+					acpi_ut_get_type_name (object_type)));
+		}
+
+		/*
+		 * Enter the named type into the internal namespace.  We enter the name
+		 * as we go downward in the parse tree.  Any necessary subobjects that involve
+		 * arguments to the opcode must be created as we go back up the parse tree later.
+		 */
+		status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
+				  ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node));
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_NSERROR (path, status);
+			return (status);
+		}
+		break;
+	}
+
+
+	/* Common exit */
+
+	if (!op) {
+		/* Create a new op */
+
+		op = acpi_ps_alloc_op (walk_state->opcode);
+		if (!op) {
+			return (AE_NO_MEMORY);
+		}
+	}
+
+	/* Initialize */
+
+	op->named.name = node->name.integer;
+
+#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
+	op->named.path = (u8 *) path;
+#endif
+
+
+	/*
+	 * Put the Node in the "op" object that the parser uses, so we
+	 * can get it again quickly when this scope is closed
+	 */
+	op->common.node = node;
+	acpi_ps_append_arg (acpi_ps_get_parent_scope (&walk_state->parser_state), op);
+
+	*out_op = op;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_load1_end_op
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              Op              - Op that has been just been completed in the
+ *                                walk;  Arguments have now been evaluated.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Ascending callback used during the loading of the namespace,
+ *              both control methods and everything else.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_load1_end_op (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_parse_object         *op;
+	acpi_object_type                object_type;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_NAME ("ds_load1_end_op");
+
+
+	op = walk_state->op;
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
+
+	/* We are only interested in opcodes that have an associated name */
+
+	if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
+		return (AE_OK);
+	}
+
+	/* Get the object type to determine if we should pop the scope */
+
+	object_type = walk_state->op_info->object_type;
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+	if (walk_state->op_info->flags & AML_FIELD) {
+		if (walk_state->opcode == AML_FIELD_OP         ||
+			walk_state->opcode == AML_BANK_FIELD_OP    ||
+			walk_state->opcode == AML_INDEX_FIELD_OP) {
+			status = acpi_ds_init_field_objects (op, walk_state);
+		}
+		return (status);
+	}
+
+
+	if (op->common.aml_opcode == AML_REGION_OP) {
+		status = acpi_ex_create_region (op->named.data, op->named.length,
+				   (acpi_adr_space_type) ((op->common.value.arg)->common.value.integer), walk_state);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+#endif
+
+	if (op->common.aml_opcode == AML_NAME_OP) {
+		/* For Name opcode, get the object type from the argument */
+
+		if (op->common.value.arg) {
+			object_type = (acpi_ps_get_opcode_info ((op->common.value.arg)->common.aml_opcode))->object_type;
+			op->common.node->type = (u8) object_type;
+		}
+	}
+
+	if (op->common.aml_opcode == AML_METHOD_OP) {
+		/*
+		 * method_op pkg_length name_string method_flags term_list
+		 *
+		 * Note: We must create the method node/object pair as soon as we
+		 * see the method declaration.  This allows later pass1 parsing
+		 * of invocations of the method (need to know the number of
+		 * arguments.)
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"LOADING-Method: State=%p Op=%p named_obj=%p\n",
+			walk_state, op, op->named.node));
+
+		if (!acpi_ns_get_attached_object (op->named.node)) {
+			walk_state->operands[0] = (void *) op->named.node;
+			walk_state->num_operands = 1;
+
+			status = acpi_ds_create_operands (walk_state, op->common.value.arg);
+			if (ACPI_SUCCESS (status)) {
+				status = acpi_ex_create_method (op->named.data,
+						   op->named.length, walk_state);
+			}
+			walk_state->operands[0] = NULL;
+			walk_state->num_operands = 0;
+
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+		}
+	}
+
+	/* Pop the scope stack */
+
+	if (acpi_ns_opens_scope (object_type)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
+			acpi_ut_get_type_name (object_type), op));
+
+		status = acpi_ds_scope_stack_pop (walk_state);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_load2_begin_op
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              Op              - Op that has been just been reached in the
+ *                                walk;  Arguments have not been evaluated yet.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Descending callback used during the loading of ACPI tables.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_load2_begin_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         **out_op)
+{
+	union acpi_parse_object         *op;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+	acpi_object_type                object_type;
+	char                            *buffer_ptr;
+
+
+	ACPI_FUNCTION_TRACE ("ds_load2_begin_op");
+
+
+	op = walk_state->op;
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
+
+	if (op) {
+		/* We only care about Namespace opcodes here */
+
+		if ((!(walk_state->op_info->flags & AML_NSOPCODE) && (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
+			(!(walk_state->op_info->flags & AML_NAMED))) {
+			return_ACPI_STATUS (AE_OK);
+		}
+
+		/*
+		 * Get the name we are going to enter or lookup in the namespace
+		 */
+		if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
+			/* For Namepath op, get the path string */
+
+			buffer_ptr = op->common.value.string;
+			if (!buffer_ptr) {
+				/* No name, just exit */
+
+				return_ACPI_STATUS (AE_OK);
+			}
+		}
+		else {
+			/* Get name from the op */
+
+			buffer_ptr = (char *) &op->named.name;
+		}
+	}
+	else {
+		/* Get the namestring from the raw AML */
+
+		buffer_ptr = acpi_ps_get_next_namestring (&walk_state->parser_state);
+	}
+
+	/* Map the opcode into an internal object type */
+
+	object_type = walk_state->op_info->object_type;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"State=%p Op=%p Type=%X\n", walk_state, op, object_type));
+
+
+	switch (walk_state->opcode) {
+	case AML_FIELD_OP:
+	case AML_BANK_FIELD_OP:
+	case AML_INDEX_FIELD_OP:
+
+		node = NULL;
+		status = AE_OK;
+		break;
+
+	case AML_INT_NAMEPATH_OP:
+
+		/*
+		 * The name_path is an object reference to an existing object. Don't enter the
+		 * name into the namespace, but look it up for use later
+		 */
+		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
+				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+		break;
+
+	case AML_SCOPE_OP:
+
+		/*
+		 * The Path is an object reference to an existing object.  Don't enter the
+		 * name into the namespace, but look it up for use later
+		 */
+		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
+				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+		if (ACPI_FAILURE (status)) {
+#ifdef _ACPI_ASL_COMPILER
+			if (status == AE_NOT_FOUND) {
+				status = AE_OK;
+			}
+			else {
+				ACPI_REPORT_NSERROR (buffer_ptr, status);
+			}
+#else
+			ACPI_REPORT_NSERROR (buffer_ptr, status);
+#endif
+			return_ACPI_STATUS (status);
+		}
+		/*
+		 * We must check to make sure that the target is
+		 * one of the opcodes that actually opens a scope
+		 */
+		switch (node->type) {
+		case ACPI_TYPE_LOCAL_SCOPE:         /* Scope */
+		case ACPI_TYPE_DEVICE:
+		case ACPI_TYPE_POWER:
+		case ACPI_TYPE_PROCESSOR:
+		case ACPI_TYPE_THERMAL:
+
+			/* These are acceptable types */
+			break;
+
+		case ACPI_TYPE_INTEGER:
+		case ACPI_TYPE_STRING:
+		case ACPI_TYPE_BUFFER:
+
+			/*
+			 * These types we will allow, but we will change the type.  This
+			 * enables some existing code of the form:
+			 *
+			 *  Name (DEB, 0)
+			 *  Scope (DEB) { ... }
+			 */
+
+			ACPI_REPORT_WARNING (("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
+				buffer_ptr, acpi_ut_get_type_name (node->type)));
+
+			node->type = ACPI_TYPE_ANY;
+			walk_state->scope_info->common.value = ACPI_TYPE_ANY;
+			break;
+
+		default:
+
+			/* All other types are an error */
+
+			ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s]\n",
+				acpi_ut_get_type_name (node->type), buffer_ptr));
+
+			return (AE_AML_OPERAND_TYPE);
+		}
+		break;
+
+	default:
+
+		/* All other opcodes */
+
+		if (op && op->common.node) {
+			/* This op/node was previously entered into the namespace */
+
+			node = op->common.node;
+
+			if (acpi_ns_opens_scope (object_type)) {
+				status = acpi_ds_scope_stack_push (node, object_type, walk_state);
+				if (ACPI_FAILURE (status)) {
+					return_ACPI_STATUS (status);
+				}
+
+			}
+			return_ACPI_STATUS (AE_OK);
+		}
+
+		/*
+		 * Enter the named type into the internal namespace.  We enter the name
+		 * as we go downward in the parse tree.  Any necessary subobjects that involve
+		 * arguments to the opcode must be created as we go back up the parse tree later.
+		 *
+		 * Note: Name may already exist if we are executing a deferred opcode.
+		 */
+		if (walk_state->deferred_node) {
+			/* This name is already in the namespace, get the node */
+
+			node = walk_state->deferred_node;
+			status = AE_OK;
+			break;
+		}
+
+		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
+				  ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, walk_state, &(node));
+		break;
+	}
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_NSERROR (buffer_ptr, status);
+		return_ACPI_STATUS (status);
+	}
+
+
+	if (!op) {
+		/* Create a new op */
+
+		op = acpi_ps_alloc_op (walk_state->opcode);
+		if (!op) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Initialize the new op */
+
+		if (node) {
+			op->named.name = node->name.integer;
+		}
+		if (out_op) {
+			*out_op = op;
+		}
+	}
+
+	/*
+	 * Put the Node in the "op" object that the parser uses, so we
+	 * can get it again quickly when this scope is closed
+	 */
+	op->common.node = node;
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_load2_end_op
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              Op              - Op that has been just been completed in the
+ *                                walk;  Arguments have now been evaluated.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Ascending callback used during the loading of the namespace,
+ *              both control methods and everything else.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_load2_end_op (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_parse_object         *op;
+	acpi_status                     status = AE_OK;
+	acpi_object_type                object_type;
+	struct acpi_namespace_node      *node;
+	union acpi_parse_object         *arg;
+	struct acpi_namespace_node      *new_node;
+#ifndef ACPI_NO_METHOD_EXECUTION
+	u32                             i;
+#endif
+
+
+	ACPI_FUNCTION_TRACE ("ds_load2_end_op");
+
+	op = walk_state->op;
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
+			walk_state->op_info->name, op, walk_state));
+
+	/* Only interested in opcodes that have namespace objects */
+
+	if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	if (op->common.aml_opcode == AML_SCOPE_OP) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"Ending scope Op=%p State=%p\n", op, walk_state));
+	}
+
+
+	object_type = walk_state->op_info->object_type;
+
+	/*
+	 * Get the Node/name from the earlier lookup
+	 * (It was saved in the *op structure)
+	 */
+	node = op->common.node;
+
+	/*
+	 * Put the Node on the object stack (Contains the ACPI Name of
+	 * this object)
+	 */
+	walk_state->operands[0] = (void *) node;
+	walk_state->num_operands = 1;
+
+	/* Pop the scope stack */
+
+	if (acpi_ns_opens_scope (object_type) && (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
+			acpi_ut_get_type_name (object_type), op));
+
+		status = acpi_ds_scope_stack_pop (walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+	}
+
+	/*
+	 * Named operations are as follows:
+	 *
+	 * AML_ALIAS
+	 * AML_BANKFIELD
+	 * AML_CREATEBITFIELD
+	 * AML_CREATEBYTEFIELD
+	 * AML_CREATEDWORDFIELD
+	 * AML_CREATEFIELD
+	 * AML_CREATEQWORDFIELD
+	 * AML_CREATEWORDFIELD
+	 * AML_DATA_REGION
+	 * AML_DEVICE
+	 * AML_EVENT
+	 * AML_FIELD
+	 * AML_INDEXFIELD
+	 * AML_METHOD
+	 * AML_METHODCALL
+	 * AML_MUTEX
+	 * AML_NAME
+	 * AML_NAMEDFIELD
+	 * AML_OPREGION
+	 * AML_POWERRES
+	 * AML_PROCESSOR
+	 * AML_SCOPE
+	 * AML_THERMALZONE
+	 */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"Create-Load [%s] State=%p Op=%p named_obj=%p\n",
+		acpi_ps_get_opcode_name (op->common.aml_opcode), walk_state, op, node));
+
+	/* Decode the opcode */
+
+	arg = op->common.value.arg;
+
+	switch (walk_state->op_info->type) {
+#ifndef ACPI_NO_METHOD_EXECUTION
+
+	case AML_TYPE_CREATE_FIELD:
+
+		/*
+		 * Create the field object, but the field buffer and index must
+		 * be evaluated later during the execution phase
+		 */
+		status = acpi_ds_create_buffer_field (op, walk_state);
+		break;
+
+
+	 case AML_TYPE_NAMED_FIELD:
+
+		switch (op->common.aml_opcode) {
+		case AML_INDEX_FIELD_OP:
+
+			status = acpi_ds_create_index_field (op, (acpi_handle) arg->common.node,
+					   walk_state);
+			break;
+
+		case AML_BANK_FIELD_OP:
+
+			status = acpi_ds_create_bank_field (op, arg->common.node, walk_state);
+			break;
+
+		case AML_FIELD_OP:
+
+			status = acpi_ds_create_field (op, arg->common.node, walk_state);
+			break;
+
+		default:
+			/* All NAMED_FIELD opcodes must be handled above */
+			break;
+		}
+		break;
+
+
+	 case AML_TYPE_NAMED_SIMPLE:
+
+		status = acpi_ds_create_operands (walk_state, arg);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		switch (op->common.aml_opcode) {
+		case AML_PROCESSOR_OP:
+
+			status = acpi_ex_create_processor (walk_state);
+			break;
+
+		case AML_POWER_RES_OP:
+
+			status = acpi_ex_create_power_resource (walk_state);
+			break;
+
+		case AML_MUTEX_OP:
+
+			status = acpi_ex_create_mutex (walk_state);
+			break;
+
+		case AML_EVENT_OP:
+
+			status = acpi_ex_create_event (walk_state);
+			break;
+
+		case AML_DATA_REGION_OP:
+
+			status = acpi_ex_create_table_region (walk_state);
+			break;
+
+		case AML_ALIAS_OP:
+
+			status = acpi_ex_create_alias (walk_state);
+			break;
+
+		default:
+			/* Unknown opcode */
+
+			status = AE_OK;
+			goto cleanup;
+		}
+
+		/* Delete operands */
+
+		for (i = 1; i < walk_state->num_operands; i++) {
+			acpi_ut_remove_reference (walk_state->operands[i]);
+			walk_state->operands[i] = NULL;
+		}
+
+		break;
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+	case AML_TYPE_NAMED_COMPLEX:
+
+		switch (op->common.aml_opcode) {
+#ifndef ACPI_NO_METHOD_EXECUTION
+		case AML_REGION_OP:
+			/*
+			 * The op_region is not fully parsed at this time. Only valid argument is the space_id.
+			 * (We must save the address of the AML of the address and length operands)
+			 */
+			/*
+			 * If we have a valid region, initialize it
+			 * Namespace is NOT locked at this point.
+			 */
+			status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node), FALSE);
+			if (ACPI_FAILURE (status)) {
+				/*
+				 *  If AE_NOT_EXIST is returned, it is not fatal
+				 *  because many regions get created before a handler
+				 *  is installed for said region.
+				 */
+				if (AE_NOT_EXIST == status) {
+					status = AE_OK;
+				}
+			}
+			break;
+
+
+		case AML_NAME_OP:
+
+			status = acpi_ds_create_node (walk_state, node, op);
+			break;
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+
+		default:
+			/* All NAMED_COMPLEX opcodes must be handled above */
+			/* Note: Method objects were already created in Pass 1 */
+			break;
+		}
+		break;
+
+
+	case AML_CLASS_INTERNAL:
+
+		/* case AML_INT_NAMEPATH_OP: */
+		break;
+
+
+	case AML_CLASS_METHOD_CALL:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"RESOLVING-method_call: State=%p Op=%p named_obj=%p\n",
+			walk_state, op, node));
+
+		/*
+		 * Lookup the method name and save the Node
+		 */
+		status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
+				  ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
+				  ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+				  walk_state, &(new_node));
+		if (ACPI_SUCCESS (status)) {
+			/*
+			 * Make sure that what we found is indeed a method
+			 * We didn't search for a method on purpose, to see if the name would resolve
+			 */
+			if (new_node->type != ACPI_TYPE_METHOD) {
+				status = AE_AML_OPERAND_TYPE;
+			}
+
+			/* We could put the returned object (Node) on the object stack for later, but
+			 * for now, we will put it in the "op" object that the parser uses, so we
+			 * can get it again at the end of this scope
+			 */
+			op->common.node = new_node;
+		}
+		else {
+			ACPI_REPORT_NSERROR (arg->common.value.string, status);
+		}
+		break;
+
+
+	default:
+		break;
+	}
+
+cleanup:
+
+	/* Remove the Node pushed at the very beginning */
+
+	walk_state->operands[0] = NULL;
+	walk_state->num_operands = 0;
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
new file mode 100644
index 0000000..65f4561
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -0,0 +1,229 @@
+/******************************************************************************
+ *
+ * Module Name: dswscope - Scope stack manipulation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dswscope")
+
+
+#define STACK_POP(head) head
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_scope_stack_clear
+ *
+ * PARAMETERS:  None
+ *
+ * DESCRIPTION: Pop (and free) everything on the scope stack except the
+ *              root scope object (which remains at the stack top.)
+ *
+ ***************************************************************************/
+
+void
+acpi_ds_scope_stack_clear (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *scope_info;
+
+	ACPI_FUNCTION_NAME ("ds_scope_stack_clear");
+
+
+	while (walk_state->scope_info) {
+		/* Pop a scope off the stack */
+
+		scope_info = walk_state->scope_info;
+		walk_state->scope_info = scope_info->scope.next;
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Popped object type (%s)\n", acpi_ut_get_type_name (scope_info->common.value)));
+		acpi_ut_delete_generic_state (scope_info);
+	}
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_scope_stack_push
+ *
+ * PARAMETERS:  *Node,              - Name to be made current
+ *              Type,               - Type of frame being pushed
+ *
+ * DESCRIPTION: Push the current scope on the scope stack, and make the
+ *              passed Node current.
+ *
+ ***************************************************************************/
+
+acpi_status
+acpi_ds_scope_stack_push (
+	struct acpi_namespace_node      *node,
+	acpi_object_type                type,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *scope_info;
+	union acpi_generic_state        *old_scope_info;
+
+
+	ACPI_FUNCTION_TRACE ("ds_scope_stack_push");
+
+
+	if (!node) {
+		/* Invalid scope   */
+
+		ACPI_REPORT_ERROR (("ds_scope_stack_push: null scope passed\n"));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Make sure object type is valid */
+
+	if (!acpi_ut_valid_object_type (type)) {
+		ACPI_REPORT_WARNING (("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
+	}
+
+	/* Allocate a new scope object */
+
+	scope_info = acpi_ut_create_generic_state ();
+	if (!scope_info) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Init new scope object */
+
+	scope_info->common.data_type = ACPI_DESC_TYPE_STATE_WSCOPE;
+	scope_info->scope.node      = node;
+	scope_info->common.value    = (u16) type;
+
+	walk_state->scope_depth++;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"[%.2d] Pushed scope ", (u32) walk_state->scope_depth));
+
+	old_scope_info = walk_state->scope_info;
+	if (old_scope_info) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+			"[%4.4s] (%s)",
+			acpi_ut_get_node_name (old_scope_info->scope.node),
+			acpi_ut_get_type_name (old_scope_info->common.value)));
+	}
+	else {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+			"[\\___] (%s)", "ROOT"));
+	}
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+		", New scope -> [%4.4s] (%s)\n",
+		acpi_ut_get_node_name (scope_info->scope.node),
+		acpi_ut_get_type_name (scope_info->common.value)));
+
+	/* Push new scope object onto stack */
+
+	acpi_ut_push_generic_state (&walk_state->scope_info, scope_info);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    acpi_ds_scope_stack_pop
+ *
+ * PARAMETERS:  Type                - The type of frame to be found
+ *
+ * DESCRIPTION: Pop the scope stack until a frame of the requested type
+ *              is found.
+ *
+ * RETURN:      Count of frames popped.  If no frame of the requested type
+ *              was found, the count is returned as a negative number and
+ *              the scope stack is emptied (which sets the current scope
+ *              to the root).  If the scope stack was empty at entry, the
+ *              function is a no-op and returns 0.
+ *
+ ***************************************************************************/
+
+acpi_status
+acpi_ds_scope_stack_pop (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *scope_info;
+	union acpi_generic_state        *new_scope_info;
+
+
+	ACPI_FUNCTION_TRACE ("ds_scope_stack_pop");
+
+
+	/*
+	 * Pop scope info object off the stack.
+	 */
+	scope_info = acpi_ut_pop_generic_state (&walk_state->scope_info);
+	if (!scope_info) {
+		return_ACPI_STATUS (AE_STACK_UNDERFLOW);
+	}
+
+	walk_state->scope_depth--;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
+		(u32) walk_state->scope_depth,
+		acpi_ut_get_node_name (scope_info->scope.node),
+		acpi_ut_get_type_name (scope_info->common.value)));
+
+	new_scope_info = walk_state->scope_info;
+	if (new_scope_info) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+			"[%4.4s] (%s)\n",
+			acpi_ut_get_node_name (new_scope_info->scope.node),
+			acpi_ut_get_type_name (new_scope_info->common.value)));
+	}
+	else {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+			"[\\___] (ROOT)\n"));
+	}
+
+	acpi_ut_delete_generic_state (scope_info);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
new file mode 100644
index 0000000..e555b3f
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -0,0 +1,1100 @@
+/******************************************************************************
+ *
+ * Module Name: dswstate - Dispatcher parse tree walk management routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dswstate")
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_insert
+ *
+ * PARAMETERS:  Object              - Object to push
+ *              Index               - Where to insert the object
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Insert an object onto this walk's result stack
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_insert (
+	void                            *object,
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_NAME ("ds_result_insert");
+
+
+	state = walk_state->results;
+	if (!state) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
+			walk_state));
+		return (AE_NOT_EXIST);
+	}
+
+	if (index >= ACPI_OBJ_NUM_OPERANDS) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Index out of range: %X Obj=%p State=%p Num=%X\n",
+			index, object, walk_state, state->results.num_results));
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (!object) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null Object! Index=%X Obj=%p State=%p Num=%X\n",
+			index, object, walk_state, state->results.num_results));
+		return (AE_BAD_PARAMETER);
+	}
+
+	state->results.obj_desc [index] = object;
+	state->results.num_results++;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"Obj=%p [%s] State=%p Num=%X Cur=%X\n",
+		object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
+		walk_state, state->results.num_results, walk_state->current_result));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_remove
+ *
+ * PARAMETERS:  Object              - Where to return the popped object
+ *              Index               - Where to extract the object
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
+ *              other words, this is a FIFO.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_remove (
+	union acpi_operand_object       **object,
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_NAME ("ds_result_remove");
+
+
+	state = walk_state->results;
+	if (!state) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
+			walk_state));
+		return (AE_NOT_EXIST);
+	}
+
+	if (index >= ACPI_OBJ_MAX_OPERAND) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Index out of range: %X State=%p Num=%X\n",
+			index, walk_state, state->results.num_results));
+	}
+
+	/* Check for a valid result object */
+
+	if (!state->results.obj_desc [index]) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null operand! State=%p #Ops=%X, Index=%X\n",
+			walk_state, state->results.num_results, index));
+		return (AE_AML_NO_RETURN_VALUE);
+	}
+
+	/* Remove the object */
+
+	state->results.num_results--;
+
+	*object = state->results.obj_desc [index];
+	state->results.obj_desc [index] = NULL;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"Obj=%p [%s] Index=%X State=%p Num=%X\n",
+		*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
+		index, walk_state, state->results.num_results));
+
+	return (AE_OK);
+}
+
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_pop
+ *
+ * PARAMETERS:  Object              - Where to return the popped object
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
+ *              other words, this is a FIFO.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_pop (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_native_uint                index;
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_NAME ("ds_result_pop");
+
+
+	state = walk_state->results;
+	if (!state) {
+		return (AE_OK);
+	}
+
+	if (!state->results.num_results) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack is empty! State=%p\n",
+			walk_state));
+		return (AE_AML_NO_RETURN_VALUE);
+	}
+
+	/* Remove top element */
+
+	state->results.num_results--;
+
+	for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
+		/* Check for a valid result object */
+
+		if (state->results.obj_desc [index -1]) {
+			*object = state->results.obj_desc [index -1];
+			state->results.obj_desc [index -1] = NULL;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
+				*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
+				(u32) index -1, walk_state, state->results.num_results));
+
+			return (AE_OK);
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
+	return (AE_AML_NO_RETURN_VALUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_pop_from_bottom
+ *
+ * PARAMETERS:  Object              - Where to return the popped object
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
+ *              other words, this is a FIFO.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_pop_from_bottom (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_native_uint                index;
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_NAME ("ds_result_pop_from_bottom");
+
+
+	state = walk_state->results;
+	if (!state) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Warning: No result object pushed! State=%p\n", walk_state));
+		return (AE_NOT_EXIST);
+	}
+
+	if (!state->results.num_results) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
+		return (AE_AML_NO_RETURN_VALUE);
+	}
+
+	/* Remove Bottom element */
+
+	*object = state->results.obj_desc [0];
+
+	/* Push entire stack down one element */
+
+	for (index = 0; index < state->results.num_results; index++) {
+		state->results.obj_desc [index] = state->results.obj_desc [index + 1];
+	}
+
+	state->results.num_results--;
+
+	/* Check for a valid result object */
+
+	if (!*object) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n",
+			walk_state, state->results.num_results, (u32) index));
+		return (AE_AML_NO_RETURN_VALUE);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n",
+		*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
+		state, walk_state));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_push
+ *
+ * PARAMETERS:  Object              - Where to return the popped object
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Push an object onto the current result stack
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_push (
+	union acpi_operand_object       *object,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_NAME ("ds_result_push");
+
+
+	state = walk_state->results;
+	if (!state) {
+		ACPI_REPORT_ERROR (("No result stack frame during push\n"));
+		return (AE_AML_INTERNAL);
+	}
+
+	if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Result stack overflow: Obj=%p State=%p Num=%X\n",
+			object, walk_state, state->results.num_results));
+		return (AE_STACK_OVERFLOW);
+	}
+
+	if (!object) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%X\n",
+			object, walk_state, state->results.num_results));
+		return (AE_BAD_PARAMETER);
+	}
+
+	state->results.obj_desc [state->results.num_results] = object;
+	state->results.num_results++;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
+		object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
+		walk_state, state->results.num_results, walk_state->current_result));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_stack_push
+ *
+ * PARAMETERS:  walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Push an object onto the walk_state result stack.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_stack_push (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *state;
+
+	ACPI_FUNCTION_NAME ("ds_result_stack_push");
+
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return (AE_NO_MEMORY);
+	}
+
+	state->common.data_type = ACPI_DESC_TYPE_STATE_RESULT;
+	acpi_ut_push_generic_state (&walk_state->results, state);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
+		state, walk_state));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_stack_pop
+ *
+ * PARAMETERS:  walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop an object off of the walk_state result stack.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_stack_pop (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *state;
+
+	ACPI_FUNCTION_NAME ("ds_result_stack_pop");
+
+
+	/* Check for stack underflow */
+
+	if (walk_state->results == NULL) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%p\n",
+			walk_state));
+		return (AE_AML_NO_OPERAND);
+	}
+
+	state = acpi_ut_pop_generic_state (&walk_state->results);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"Result=%p remaining_results=%X State=%p\n",
+		state, state->results.num_results, walk_state));
+
+	acpi_ut_delete_generic_state (state);
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_delete_all
+ *
+ * PARAMETERS:  walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
+ *              Should be used with great care, if at all!
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_ds_obj_stack_delete_all (
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
+
+
+	/* The stack size is configurable, but fixed */
+
+	for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
+		if (walk_state->operands[i]) {
+			acpi_ut_remove_reference (walk_state->operands[i]);
+			walk_state->operands[i] = NULL;
+		}
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_push
+ *
+ * PARAMETERS:  Object              - Object to push
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Push an object onto this walk's object/operand stack
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_push (
+	void                            *object,
+	struct acpi_walk_state          *walk_state)
+{
+	ACPI_FUNCTION_NAME ("ds_obj_stack_push");
+
+
+	/* Check for stack overflow */
+
+	if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"overflow! Obj=%p State=%p #Ops=%X\n",
+			object, walk_state, walk_state->num_operands));
+		return (AE_STACK_OVERFLOW);
+	}
+
+	/* Put the object onto the stack */
+
+	walk_state->operands [walk_state->num_operands] = object;
+	walk_state->num_operands++;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
+			  object, acpi_ut_get_object_type_name ((union acpi_operand_object *) object),
+			  walk_state, walk_state->num_operands));
+
+	return (AE_OK);
+}
+
+
+#if 0
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_pop_object
+ *
+ * PARAMETERS:  pop_count           - Number of objects/entries to pop
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
+ *              deleted by this routine.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_pop_object (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state)
+{
+	ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
+
+
+	/* Check for stack underflow */
+
+	if (walk_state->num_operands == 0) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Missing operand/stack empty! State=%p #Ops=%X\n",
+			walk_state, walk_state->num_operands));
+		*object = NULL;
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Pop the stack */
+
+	walk_state->num_operands--;
+
+	/* Check for a valid operand */
+
+	if (!walk_state->operands [walk_state->num_operands]) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null operand! State=%p #Ops=%X\n",
+			walk_state, walk_state->num_operands));
+		*object = NULL;
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Get operand and set stack entry to null */
+
+	*object = walk_state->operands [walk_state->num_operands];
+	walk_state->operands [walk_state->num_operands] = NULL;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
+			  *object, acpi_ut_get_object_type_name (*object),
+			  walk_state, walk_state->num_operands));
+
+	return (AE_OK);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_pop
+ *
+ * PARAMETERS:  pop_count           - Number of objects/entries to pop
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
+ *              deleted by this routine.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_pop (
+	u32                             pop_count,
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             i;
+
+	ACPI_FUNCTION_NAME ("ds_obj_stack_pop");
+
+
+	for (i = 0; i < pop_count; i++) {
+		/* Check for stack underflow */
+
+		if (walk_state->num_operands == 0) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Underflow! Count=%X State=%p #Ops=%X\n",
+				pop_count, walk_state, walk_state->num_operands));
+			return (AE_STACK_UNDERFLOW);
+		}
+
+		/* Just set the stack entry to null */
+
+		walk_state->num_operands--;
+		walk_state->operands [walk_state->num_operands] = NULL;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
+			  pop_count, walk_state, walk_state->num_operands));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_pop_and_delete
+ *
+ * PARAMETERS:  pop_count           - Number of objects/entries to pop
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop this walk's object stack and delete each object that is
+ *              popped off.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_pop_and_delete (
+	u32                             pop_count,
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             i;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete");
+
+
+	for (i = 0; i < pop_count; i++) {
+		/* Check for stack underflow */
+
+		if (walk_state->num_operands == 0) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Underflow! Count=%X State=%p #Ops=%X\n",
+				pop_count, walk_state, walk_state->num_operands));
+			return (AE_STACK_UNDERFLOW);
+		}
+
+		/* Pop the stack and delete an object if present in this stack entry */
+
+		walk_state->num_operands--;
+		obj_desc = walk_state->operands [walk_state->num_operands];
+		if (obj_desc) {
+			acpi_ut_remove_reference (walk_state->operands [walk_state->num_operands]);
+			walk_state->operands [walk_state->num_operands] = NULL;
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
+			  pop_count, walk_state, walk_state->num_operands));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_get_value
+ *
+ * PARAMETERS:  Index               - Stack index whose value is desired.  Based
+ *                                    on the top of the stack (index=0 == top)
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve an object from this walk's object stack.  Index must
+ *              be within the range of the current stack pointer.
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+void *
+acpi_ds_obj_stack_get_value (
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
+
+
+	/* Can't do it if the stack is empty */
+
+	if (walk_state->num_operands == 0) {
+		return_PTR (NULL);
+	}
+
+	/* or if the index is past the top of the stack */
+
+	if (index > (walk_state->num_operands - (u32) 1)) {
+		return_PTR (NULL);
+	}
+
+	return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
+			  index]);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_get_current_walk_state
+ *
+ * PARAMETERS:  Thread          - Get current active state for this Thread
+ *
+ * RETURN:      Pointer to the current walk state
+ *
+ * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
+ *              walk state.)
+ *
+ ******************************************************************************/
+
+struct acpi_walk_state *
+acpi_ds_get_current_walk_state (
+	struct acpi_thread_state        *thread)
+
+{
+	ACPI_FUNCTION_NAME ("ds_get_current_walk_state");
+
+
+	if (!thread) {
+		return (NULL);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current walk_state %p\n",
+		thread->walk_state_list));
+
+	return (thread->walk_state_list);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_push_walk_state
+ *
+ * PARAMETERS:  walk_state      - State to push
+ *              walk_list       - The list that owns the walk stack
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Place the walk_state at the head of the state list.
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_push_walk_state (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_thread_state        *thread)
+{
+	ACPI_FUNCTION_TRACE ("ds_push_walk_state");
+
+
+	walk_state->next      = thread->walk_state_list;
+	thread->walk_state_list = walk_state;
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_pop_walk_state
+ *
+ * PARAMETERS:  walk_list       - The list that owns the walk stack
+ *
+ * RETURN:      A walk_state object popped from the stack
+ *
+ * DESCRIPTION: Remove and return the walkstate object that is at the head of
+ *              the walk stack for the given walk list.  NULL indicates that
+ *              the list is empty.
+ *
+ ******************************************************************************/
+
+struct acpi_walk_state *
+acpi_ds_pop_walk_state (
+	struct acpi_thread_state        *thread)
+{
+	struct acpi_walk_state          *walk_state;
+
+
+	ACPI_FUNCTION_TRACE ("ds_pop_walk_state");
+
+
+	walk_state = thread->walk_state_list;
+
+	if (walk_state) {
+		/* Next walk state becomes the current walk state */
+
+		thread->walk_state_list = walk_state->next;
+
+		/*
+		 * Don't clear the NEXT field, this serves as an indicator
+		 * that there is a parent WALK STATE
+		 *     NO: walk_state->Next = NULL;
+		 */
+	}
+
+	return_PTR (walk_state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_create_walk_state
+ *
+ * PARAMETERS:  Origin          - Starting point for this walk
+ *              Thread          - Current thread state
+ *
+ * RETURN:      Pointer to the new walk state.
+ *
+ * DESCRIPTION: Allocate and initialize a new walk state.  The current walk
+ *              state is set to this new state.
+ *
+ ******************************************************************************/
+
+struct acpi_walk_state *
+acpi_ds_create_walk_state (
+	acpi_owner_id                   owner_id,
+	union acpi_parse_object         *origin,
+	union acpi_operand_object       *mth_desc,
+	struct acpi_thread_state        *thread)
+{
+	struct acpi_walk_state          *walk_state;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ds_create_walk_state");
+
+
+	walk_state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_WALK);
+	if (!walk_state) {
+		return_PTR (NULL);
+	}
+
+	walk_state->data_type       = ACPI_DESC_TYPE_WALK;
+	walk_state->owner_id        = owner_id;
+	walk_state->origin          = origin;
+	walk_state->method_desc     = mth_desc;
+	walk_state->thread          = thread;
+
+	walk_state->parser_state.start_op = origin;
+
+	/* Init the method args/local */
+
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+	acpi_ds_method_data_init (walk_state);
+#endif
+
+	/* Create an initial result stack entry */
+
+	status = acpi_ds_result_stack_push (walk_state);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
+		return_PTR (NULL);
+	}
+
+	/* Put the new state at the head of the walk list */
+
+	if (thread) {
+		acpi_ds_push_walk_state (walk_state, thread);
+	}
+
+	return_PTR (walk_state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_init_aml_walk
+ *
+ * PARAMETERS:  walk_state      - New state to be initialized
+ *              Op              - Current parse op
+ *              method_node     - Control method NS node, if any
+ *              aml_start       - Start of AML
+ *              aml_length      - Length of AML
+ *              Params          - Method args, if any
+ *              return_obj_desc - Where to store a return object, if any
+ *              pass_number     - 1, 2, or 3
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_init_aml_walk (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *method_node,
+	u8                              *aml_start,
+	u32                             aml_length,
+	struct acpi_parameter_info      *info,
+	u32                             pass_number)
+{
+	acpi_status                     status;
+	struct acpi_parse_state         *parser_state = &walk_state->parser_state;
+	union acpi_parse_object         *extra_op;
+
+
+	ACPI_FUNCTION_TRACE ("ds_init_aml_walk");
+
+
+	walk_state->parser_state.aml    =
+	walk_state->parser_state.aml_start = aml_start;
+	walk_state->parser_state.aml_end =
+	walk_state->parser_state.pkg_end = aml_start + aml_length;
+
+	/* The next_op of the next_walk will be the beginning of the method */
+
+	walk_state->next_op             = NULL;
+
+	if (info) {
+		if (info->parameter_type == ACPI_PARAM_GPE) {
+			walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info,
+					   info->parameters);
+		}
+		else {
+			walk_state->params              = info->parameters;
+			walk_state->caller_return_desc  = &info->return_object;
+		}
+	}
+
+	status = acpi_ps_init_scope (&walk_state->parser_state, op);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (method_node) {
+		walk_state->parser_state.start_node = method_node;
+		walk_state->walk_type            = ACPI_WALK_METHOD;
+		walk_state->method_node          = method_node;
+		walk_state->method_desc          = acpi_ns_get_attached_object (method_node);
+
+		/* Push start scope on scope stack and make it current  */
+
+		status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* Init the method arguments */
+
+		status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+	else {
+		/*
+		 * Setup the current scope.
+		 * Find a Named Op that has a namespace node associated with it.
+		 * search upwards from this Op.  Current scope is the first
+		 * Op with a namespace node.
+		 */
+		extra_op = parser_state->start_op;
+		while (extra_op && !extra_op->common.node) {
+			extra_op = extra_op->common.parent;
+		}
+
+		if (!extra_op) {
+			parser_state->start_node = NULL;
+		}
+		else {
+			parser_state->start_node = extra_op->common.node;
+		}
+
+		if (parser_state->start_node) {
+			/* Push start scope on scope stack and make it current  */
+
+			status = acpi_ds_scope_stack_push (parser_state->start_node,
+					  parser_state->start_node->type, walk_state);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+	}
+
+	status = acpi_ds_init_callbacks (walk_state, pass_number);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_delete_walk_state
+ *
+ * PARAMETERS:  walk_state      - State to delete
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete a walk state including all internal data structures
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_delete_walk_state (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_delete_walk_state", walk_state);
+
+
+	if (!walk_state) {
+		return;
+	}
+
+	if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n", walk_state));
+		return;
+	}
+
+	if (walk_state->parser_state.scope) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state));
+	}
+
+	/* Always must free any linked control states */
+
+	while (walk_state->control_state) {
+		state = walk_state->control_state;
+		walk_state->control_state = state->common.next;
+
+		acpi_ut_delete_generic_state (state);
+	}
+
+	/* Always must free any linked parse states */
+
+	while (walk_state->scope_info) {
+		state = walk_state->scope_info;
+		walk_state->scope_info = state->common.next;
+
+		acpi_ut_delete_generic_state (state);
+	}
+
+	/* Always must free any stacked result states */
+
+	while (walk_state->results) {
+		state = walk_state->results;
+		walk_state->results = state->common.next;
+
+		acpi_ut_delete_generic_state (state);
+	}
+
+	acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
+	return_VOID;
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_delete_walk_state_cache
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Purge the global state object cache.  Used during subsystem
+ *              termination.
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_delete_walk_state_cache (
+	void)
+{
+	ACPI_FUNCTION_TRACE ("ds_delete_walk_state_cache");
+
+
+	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK);
+	return_VOID;
+}
+#endif
+
+
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
new file mode 100644
index 0000000..fdf143b
--- /dev/null
+++ b/drivers/acpi/ec.c
@@ -0,0 +1,1024 @@
+/*
+ *  acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 38 $)
+ *
+ *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/io.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/actypes.h>
+
+#define _COMPONENT		ACPI_EC_COMPONENT
+ACPI_MODULE_NAME		("acpi_ec")
+
+#define ACPI_EC_COMPONENT		0x00100000
+#define ACPI_EC_CLASS			"embedded_controller"
+#define ACPI_EC_HID			"PNP0C09"
+#define ACPI_EC_DRIVER_NAME		"ACPI Embedded Controller Driver"
+#define ACPI_EC_DEVICE_NAME		"Embedded Controller"
+#define ACPI_EC_FILE_INFO		"info"
+
+
+#define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */
+#define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */
+#define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */
+
+#define ACPI_EC_EVENT_OBF	0x01	/* Output buffer full */
+#define ACPI_EC_EVENT_IBE	0x02	/* Input buffer empty */
+
+#define ACPI_EC_UDELAY		100	/* Poll @ 100us increments */
+#define ACPI_EC_UDELAY_COUNT	1000	/* Wait 10ms max. during EC ops */
+#define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
+
+#define ACPI_EC_COMMAND_READ	0x80
+#define ACPI_EC_COMMAND_WRITE	0x81
+#define ACPI_EC_COMMAND_QUERY	0x84
+
+static int acpi_ec_add (struct acpi_device *device);
+static int acpi_ec_remove (struct acpi_device *device, int type);
+static int acpi_ec_start (struct acpi_device *device);
+static int acpi_ec_stop (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_ec_driver = {
+	.name =		ACPI_EC_DRIVER_NAME,
+	.class =	ACPI_EC_CLASS,
+	.ids =		ACPI_EC_HID,
+	.ops =		{
+				.add =		acpi_ec_add,
+				.remove =	acpi_ec_remove,
+				.start =	acpi_ec_start,
+				.stop =		acpi_ec_stop,
+			},
+};
+
+struct acpi_ec {
+	acpi_handle			handle;
+	unsigned long			uid;
+	unsigned long			gpe_bit;
+	struct acpi_generic_address	status_addr;
+	struct acpi_generic_address	command_addr;
+	struct acpi_generic_address	data_addr;
+	unsigned long			global_lock;
+	spinlock_t			lock;
+};
+
+/* If we find an EC via the ECDT, we need to keep a ptr to its context */
+static struct acpi_ec	*ec_ecdt;
+
+/* External interfaces use first EC only, so remember */
+static struct acpi_device *first_ec;
+
+/* --------------------------------------------------------------------------
+                             Transaction Management
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_ec_wait (
+	struct acpi_ec		*ec,
+	u8			event)
+{
+	u32			acpi_ec_status = 0;
+	u32			i = ACPI_EC_UDELAY_COUNT;
+
+	if (!ec)
+		return -EINVAL;
+
+	/* Poll the EC status register waiting for the event to occur. */
+	switch (event) {
+	case ACPI_EC_EVENT_OBF:
+		do {
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
+			if (acpi_ec_status & ACPI_EC_FLAG_OBF)
+				return 0;
+			udelay(ACPI_EC_UDELAY);
+		} while (--i>0);
+		break;
+	case ACPI_EC_EVENT_IBE:
+		do {
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
+			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
+				return 0;
+			udelay(ACPI_EC_UDELAY);
+		} while (--i>0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return -ETIME;
+}
+
+
+static int
+acpi_ec_read (
+	struct acpi_ec		*ec,
+	u8			address,
+	u32			*data)
+{
+	acpi_status		status = AE_OK;
+	int			result = 0;
+	unsigned long		flags = 0;
+	u32			glk = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_read");
+
+	if (!ec || !data)
+		return_VALUE(-EINVAL);
+
+	*data = 0;
+
+	if (ec->global_lock) {
+		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+		if (ACPI_FAILURE(status))
+			return_VALUE(-ENODEV);
+	}
+	
+	spin_lock_irqsave(&ec->lock, flags);
+
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
+	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (result)
+		goto end;
+
+	acpi_hw_low_level_write(8, address, &ec->data_addr);
+	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+	if (result)
+		goto end;
+
+
+	acpi_hw_low_level_read(8, data, &ec->data_addr);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
+		*data, address));
+
+end:
+	spin_unlock_irqrestore(&ec->lock, flags);
+
+	if (ec->global_lock)
+		acpi_release_global_lock(glk);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_ec_write (
+	struct acpi_ec		*ec,
+	u8			address,
+	u8			data)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	unsigned long		flags = 0;
+	u32			glk = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_write");
+
+	if (!ec)
+		return_VALUE(-EINVAL);
+
+	if (ec->global_lock) {
+		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+		if (ACPI_FAILURE(status))
+			return_VALUE(-ENODEV);
+	}
+
+	spin_lock_irqsave(&ec->lock, flags);
+
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
+	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (result)
+		goto end;
+
+	acpi_hw_low_level_write(8, address, &ec->data_addr);
+	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (result)
+		goto end;
+
+	acpi_hw_low_level_write(8, data, &ec->data_addr);
+	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (result)
+		goto end;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
+		data, address));
+
+end:
+	spin_unlock_irqrestore(&ec->lock, flags);
+
+	if (ec->global_lock)
+		acpi_release_global_lock(glk);
+
+	return_VALUE(result);
+}
+
+/*
+ * Externally callable EC access functions. For now, assume 1 EC only
+ */
+int
+ec_read(u8 addr, u8 *val)
+{
+	struct acpi_ec *ec;
+	int err;
+	u32 temp_data;
+
+	if (!first_ec)
+		return -ENODEV;
+
+	ec = acpi_driver_data(first_ec);
+
+	err = acpi_ec_read(ec, addr, &temp_data);
+
+	if (!err) {
+		*val = temp_data;
+		return 0;
+	}
+	else
+		return err;
+}
+EXPORT_SYMBOL(ec_read);
+
+int
+ec_write(u8 addr, u8 val)
+{
+	struct acpi_ec *ec;
+	int err;
+
+	if (!first_ec)
+		return -ENODEV;
+
+	ec = acpi_driver_data(first_ec);
+
+	err = acpi_ec_write(ec, addr, val);
+
+	return err;
+}
+EXPORT_SYMBOL(ec_write);
+
+
+static int
+acpi_ec_query (
+	struct acpi_ec		*ec,
+	u32			*data)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	unsigned long		flags = 0;
+	u32			glk = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_query");
+
+	if (!ec || !data)
+		return_VALUE(-EINVAL);
+
+	*data = 0;
+
+	if (ec->global_lock) {
+		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+		if (ACPI_FAILURE(status))
+			return_VALUE(-ENODEV);
+	}
+
+	/*
+	 * Query the EC to find out which _Qxx method we need to evaluate.
+	 * Note that successful completion of the query causes the ACPI_EC_SCI
+	 * bit to be cleared (and thus clearing the interrupt source).
+	 */
+	spin_lock_irqsave(&ec->lock, flags);
+
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
+	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+	if (result)
+		goto end;
+	
+	acpi_hw_low_level_read(8, data, &ec->data_addr);
+	if (!*data)
+		result = -ENODATA;
+
+end:
+	spin_unlock_irqrestore(&ec->lock, flags);
+
+	if (ec->global_lock)
+		acpi_release_global_lock(glk);
+
+	return_VALUE(result);
+}
+
+
+/* --------------------------------------------------------------------------
+                                Event Management
+   -------------------------------------------------------------------------- */
+
+struct acpi_ec_query_data {
+	acpi_handle		handle;
+	u8			data;
+};
+
+static void
+acpi_ec_gpe_query (
+	void			*ec_cxt)
+{
+	struct acpi_ec		*ec = (struct acpi_ec *) ec_cxt;
+	u32			value = 0;
+	unsigned long		flags = 0;
+	static char		object_name[5] = {'_','Q','0','0','\0'};
+	const char		hex[] = {'0','1','2','3','4','5','6','7',
+				         '8','9','A','B','C','D','E','F'};
+
+	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
+
+	if (!ec_cxt)
+		goto end;	
+
+	spin_lock_irqsave(&ec->lock, flags);
+	acpi_hw_low_level_read(8, &value, &ec->command_addr);
+	spin_unlock_irqrestore(&ec->lock, flags);
+
+	/* TBD: Implement asynch events!
+	 * NOTE: All we care about are EC-SCI's.  Other EC events are
+	 * handled via polling (yuck!).  This is because some systems
+	 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
+	 *  a purely interrupt-driven approach (grumble, grumble).
+	 */
+	if (!(value & ACPI_EC_FLAG_SCI))
+		goto end;
+
+	if (acpi_ec_query(ec, &value))
+		goto end;
+	
+	object_name[2] = hex[((value >> 4) & 0x0F)];
+	object_name[3] = hex[(value & 0x0F)];
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
+
+	acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
+
+end:
+	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+}
+
+static u32
+acpi_ec_gpe_handler (
+	void			*data)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_ec		*ec = (struct acpi_ec *) data;
+
+	if (!ec)
+		return ACPI_INTERRUPT_NOT_HANDLED;
+
+	acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
+
+	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+		acpi_ec_gpe_query, ec);
+
+	if (status == AE_OK)
+		return ACPI_INTERRUPT_HANDLED;
+	else
+		return ACPI_INTERRUPT_NOT_HANDLED;
+}
+
+/* --------------------------------------------------------------------------
+                             Address Space Management
+   -------------------------------------------------------------------------- */
+
+static acpi_status
+acpi_ec_space_setup (
+	acpi_handle		region_handle,
+	u32			function,
+	void			*handler_context,
+	void			**return_context)
+{
+	/*
+	 * The EC object is in the handler context and is needed
+	 * when calling the acpi_ec_space_handler.
+	 */
+	if(function == ACPI_REGION_DEACTIVATE) 
+		*return_context = NULL;
+	else 
+		*return_context = handler_context;
+
+	return AE_OK;
+}
+
+
+static acpi_status
+acpi_ec_space_handler (
+	u32			function,
+	acpi_physical_address	address,
+	u32			bit_width,
+	acpi_integer		*value,
+	void			*handler_context,
+	void			*region_context)
+{
+	int			result = 0;
+	struct acpi_ec		*ec = NULL;
+	u32			temp = 0;
+	acpi_integer		f_v = 0;
+	int 			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_space_handler");
+
+	if ((address > 0xFF) || !value || !handler_context)
+		return_VALUE(AE_BAD_PARAMETER);
+
+	if(bit_width != 8) {
+		printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n");
+		if (acpi_strict)
+			return_VALUE(AE_BAD_PARAMETER);
+	}
+
+	ec = (struct acpi_ec *) handler_context;
+
+next_byte:
+	switch (function) {
+	case ACPI_READ:
+		result = acpi_ec_read(ec, (u8) address, &temp);
+		*value = (acpi_integer) temp;
+		break;
+	case ACPI_WRITE:
+		result = acpi_ec_write(ec, (u8) address, (u8) *value);
+		break;
+	default:
+		result = -EINVAL;
+		goto out;
+		break;
+	}
+
+	bit_width -= 8;
+	if(bit_width){
+
+		if(function == ACPI_READ)
+			f_v |= (acpi_integer) (*value) << 8*i;
+		if(function == ACPI_WRITE)
+			(*value) >>=8; 
+		i++;
+		goto next_byte;
+	}
+
+
+	if(function == ACPI_READ){
+		f_v |= (acpi_integer) (*value) << 8*i;
+		*value = f_v;
+	}
+
+		
+out:
+	switch (result) {
+	case -EINVAL:
+		return_VALUE(AE_BAD_PARAMETER);
+		break;
+	case -ENODEV:
+		return_VALUE(AE_NOT_FOUND);
+		break;
+	case -ETIME:
+		return_VALUE(AE_TIME);
+		break;
+	default:
+		return_VALUE(AE_OK);
+	}
+	
+
+}
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_ec_dir;
+
+
+static int
+acpi_ec_read_info (struct seq_file *seq, void *offset)
+{
+	struct acpi_ec		*ec = (struct acpi_ec *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_read_info");
+
+	if (!ec)
+		goto end;
+
+	seq_printf(seq, "gpe bit:                 0x%02x\n",
+		(u32) ec->gpe_bit);
+	seq_printf(seq, "ports:                   0x%02x, 0x%02x\n",
+		(u32) ec->status_addr.address, (u32) ec->data_addr.address);
+	seq_printf(seq, "use global lock:         %s\n",
+		ec->global_lock?"yes":"no");
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_ec_read_info, PDE(inode)->data);
+}
+
+static struct file_operations acpi_ec_info_ops = {
+	.open		= acpi_ec_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner = THIS_MODULE,
+};
+
+static int
+acpi_ec_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_ec_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+	}
+
+	entry = create_proc_entry(ACPI_EC_FILE_INFO, S_IRUGO,
+		acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+			"Unable to create '%s' fs entry\n",
+			ACPI_EC_FILE_INFO));
+	else {
+		entry->proc_fops = &acpi_ec_info_ops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_ec_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_ec_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                               Driver Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_ec_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_ec		*ec = NULL;
+	unsigned long		uid;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	if (!ec)
+		return_VALUE(-ENOMEM);
+	memset(ec, 0, sizeof(struct acpi_ec));
+
+	ec->handle = device->handle;
+	ec->uid = -1;
+	spin_lock_init(&ec->lock);
+	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
+	acpi_driver_data(device) = ec;
+
+	/* Use the global lock for all EC transactions? */
+	acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
+
+	/* If our UID matches the UID for the ECDT-enumerated EC,
+	   we now have the *real* EC info, so kill the makeshift one.*/
+	acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid);
+	if (ec_ecdt && ec_ecdt->uid == uid) {
+		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
+			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
+	
+		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
+
+		kfree(ec_ecdt);
+	}
+
+	/* Get GPE bit assignment (EC events). */
+	/* TODO: Add support for _GPE returning a package */
+	status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error obtaining GPE bit assignment\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	result = acpi_ec_add_fs(device);
+	if (result)
+		goto end;
+
+	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
+		acpi_device_name(device), acpi_device_bid(device),
+		(u32) ec->gpe_bit);
+
+	if (!first_ec)
+		first_ec = device;
+
+end:
+	if (result)
+		kfree(ec);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_ec_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	struct acpi_ec		*ec = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_remove");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	ec = acpi_driver_data(device);
+
+	acpi_ec_remove_fs(device);
+
+	kfree(ec);
+
+	return_VALUE(0);
+}
+
+
+static acpi_status
+acpi_ec_io_ports (
+	struct acpi_resource	*resource,
+	void			*context)
+{
+	struct acpi_ec		*ec = (struct acpi_ec *) context;
+	struct acpi_generic_address *addr;
+
+	if (resource->id != ACPI_RSTYPE_IO) {
+		return AE_OK;
+	}
+
+	/*
+	 * The first address region returned is the data port, and
+	 * the second address region returned is the status/command
+	 * port.
+	 */
+	if (ec->data_addr.register_bit_width == 0) {
+		addr = &ec->data_addr;
+	} else if (ec->command_addr.register_bit_width == 0) {
+		addr = &ec->command_addr;
+	} else {
+		return AE_CTRL_TERMINATE;
+	}
+
+	addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
+	addr->register_bit_width = 8;
+	addr->register_bit_offset = 0;
+	addr->address = resource->data.io.min_base_address;
+
+	return AE_OK;
+}
+
+
+static int
+acpi_ec_start (
+	struct acpi_device	*device)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_ec		*ec = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_start");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	ec = acpi_driver_data(device);
+
+	if (!ec)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * Get I/O port addresses. Convert to GAS format.
+	 */
+	status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
+		acpi_ec_io_ports, ec);
+	if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
+		return_VALUE(-ENODEV);
+	}
+
+	ec->status_addr = ec->command_addr;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
+		(u32) ec->gpe_bit, (u32) ec->command_addr.address,
+		(u32) ec->data_addr.address));
+
+	/*
+	 * Install GPE handler
+	 */
+	status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
+		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
+	if (ACPI_FAILURE(status)) {
+		return_VALUE(-ENODEV);
+	}
+	acpi_set_gpe_type (NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe (NULL, ec->gpe_bit, ACPI_NOT_ISR);
+
+	status = acpi_install_address_space_handler (ec->handle,
+			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
+			&acpi_ec_space_setup, ec);
+	if (ACPI_FAILURE(status)) {
+		acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(AE_OK);
+}
+
+
+static int
+acpi_ec_stop (
+	struct acpi_device	*device,
+	int			type)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_ec		*ec = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_stop");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	ec = acpi_driver_data(device);
+
+	status = acpi_remove_address_space_handler(ec->handle,
+		ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	status = acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	return_VALUE(0);
+}
+
+static acpi_status __init
+acpi_fake_ecdt_callback (
+	acpi_handle	handle,
+	u32		Level,
+	void		*context,
+	void		**retval)
+{
+	acpi_status	status;
+
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+		acpi_ec_io_ports, ec_ecdt);
+	if (ACPI_FAILURE(status))
+		return status;
+	ec_ecdt->status_addr = ec_ecdt->command_addr;
+
+	ec_ecdt->uid = -1;
+	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
+
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);
+	if (ACPI_FAILURE(status))
+		return status;
+	spin_lock_init(&ec_ecdt->lock);
+	ec_ecdt->global_lock = TRUE;
+	ec_ecdt->handle = handle;
+
+	printk(KERN_INFO PREFIX  "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
+		(u32) ec_ecdt->gpe_bit, (u32) ec_ecdt->command_addr.address,
+		(u32) ec_ecdt->data_addr.address);
+
+	return AE_CTRL_TERMINATE;
+}
+
+/*
+ * Some BIOS (such as some from Gateway laptops) access EC region very early
+ * such as in BAT0._INI or EC._INI before an EC device is found and
+ * do not provide an ECDT. According to ACPI spec, ECDT isn't mandatorily
+ * required, but if EC regison is accessed early, it is required.
+ * The routine tries to workaround the BIOS bug by pre-scan EC device
+ * It assumes that _CRS, _HID, _GPE, _UID methods of EC don't touch any
+ * op region (since _REG isn't invoked yet). The assumption is true for
+ * all systems found.
+ */
+static int __init
+acpi_ec_fake_ecdt(void)
+{
+	acpi_status	status;
+	int		ret = 0;
+
+	printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
+
+	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	if (!ec_ecdt) {
+		ret = -ENOMEM;
+		goto error;
+	}
+	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
+
+	status = acpi_get_devices (ACPI_EC_HID,
+				acpi_fake_ecdt_callback,
+				NULL,
+				NULL);
+	if (ACPI_FAILURE(status)) {
+		kfree(ec_ecdt);
+		ec_ecdt = NULL;
+		ret = -ENODEV;
+		goto error;
+	}
+	return 0;
+error:
+	printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
+	return ret;
+}
+
+static int __init
+acpi_ec_get_real_ecdt(void)
+{
+	acpi_status		status;
+	struct acpi_table_ecdt 	*ecdt_ptr;
+
+	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 
+		(struct acpi_table_header **) &ecdt_ptr);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	printk(KERN_INFO PREFIX "Found ECDT\n");
+
+	/*
+	 * Generate a temporary ec context to use until the namespace is scanned
+	 */
+	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	if (!ec_ecdt)
+		return -ENOMEM;
+	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
+
+	ec_ecdt->command_addr = ecdt_ptr->ec_control;
+	ec_ecdt->status_addr = ecdt_ptr->ec_control;
+	ec_ecdt->data_addr = ecdt_ptr->ec_data;
+	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
+	spin_lock_init(&ec_ecdt->lock);
+	/* use the GL just to be safe */
+	ec_ecdt->global_lock = TRUE;
+	ec_ecdt->uid = ecdt_ptr->uid;
+
+	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
+	if (ACPI_FAILURE(status)) {
+		goto error;
+	}
+
+	return 0;
+error:
+	printk(KERN_ERR PREFIX "Could not use ECDT\n");
+	kfree(ec_ecdt);
+	ec_ecdt = NULL;
+
+	return -ENODEV;
+}
+
+static int __initdata acpi_fake_ecdt_enabled;
+int __init
+acpi_ec_ecdt_probe (void)
+{
+	acpi_status		status;
+	int			ret;
+
+	ret = acpi_ec_get_real_ecdt();
+	/* Try to make a fake ECDT */
+	if (ret && acpi_fake_ecdt_enabled) {
+		ret = acpi_ec_fake_ecdt();
+	}
+
+	if (ret)
+		return 0;
+
+	/*
+	 * Install GPE handler
+	 */
+	status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
+		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
+		ec_ecdt);
+	if (ACPI_FAILURE(status)) {
+		goto error;
+	}
+	acpi_set_gpe_type (NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe (NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
+
+	status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
+			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
+			&acpi_ec_space_setup, ec_ecdt);
+	if (ACPI_FAILURE(status)) {
+		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
+			&acpi_ec_gpe_handler);
+		goto error;
+	}
+
+	return 0;
+
+error:
+	printk(KERN_ERR PREFIX "Could not use ECDT\n");
+	kfree(ec_ecdt);
+	ec_ecdt = NULL;
+
+	return -ENODEV;
+}
+
+
+static int __init acpi_ec_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_init");
+
+	if (acpi_disabled)
+		return_VALUE(0);
+
+	acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
+	if (!acpi_ec_dir)
+		return_VALUE(-ENODEV);
+
+	/* Now register the driver for the EC */
+	result = acpi_bus_register_driver(&acpi_ec_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(result);
+}
+
+subsys_initcall(acpi_ec_init);
+
+/* EC driver currently not unloadable */
+#if 0
+static void __exit
+acpi_ec_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_ec_exit");
+
+	acpi_bus_unregister_driver(&acpi_ec_driver);
+
+	remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+#endif /* 0 */
+
+static int __init acpi_fake_ecdt_setup(char *str)
+{
+	acpi_fake_ecdt_enabled = 1;
+	return 0;
+}
+__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
new file mode 100644
index 0000000..43c49f6
--- /dev/null
+++ b/drivers/acpi/event.c
@@ -0,0 +1,140 @@
+/*
+ * event.c - exporting ACPI events via procfs
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <acpi/acpi_drivers.h>
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("event")
+
+/* Global vars for handling event proc entry */
+static DEFINE_SPINLOCK(acpi_system_event_lock);
+int				event_is_open = 0;
+extern struct list_head		acpi_bus_event_list;
+extern wait_queue_head_t	acpi_bus_event_queue;
+
+static int
+acpi_system_open_event(struct inode *inode, struct file *file)
+{
+	spin_lock_irq (&acpi_system_event_lock);
+
+	if(event_is_open)
+		goto out_busy;
+
+	event_is_open = 1;
+
+	spin_unlock_irq (&acpi_system_event_lock);
+	return 0;
+
+out_busy:
+	spin_unlock_irq (&acpi_system_event_lock);
+	return -EBUSY;
+}
+
+static ssize_t
+acpi_system_read_event (
+	struct file		*file,
+	char			__user *buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	int			result = 0;
+	struct acpi_bus_event	event;
+	static char		str[ACPI_MAX_STRING];
+	static int		chars_remaining = 0;
+	static char		*ptr;
+
+
+	ACPI_FUNCTION_TRACE("acpi_system_read_event");
+
+	if (!chars_remaining) {
+		memset(&event, 0, sizeof(struct acpi_bus_event));
+
+		if ((file->f_flags & O_NONBLOCK)
+		    && (list_empty(&acpi_bus_event_list)))
+			return_VALUE(-EAGAIN);
+
+		result = acpi_bus_receive_event(&event);
+		if (result) {
+			return_VALUE(-EIO);
+		}
+
+		chars_remaining = sprintf(str, "%s %s %08x %08x\n", 
+			event.device_class?event.device_class:"<unknown>",
+			event.bus_id?event.bus_id:"<unknown>", 
+			event.type, event.data);
+		ptr = str;
+	}
+
+	if (chars_remaining < count) {
+		count = chars_remaining;
+	}
+
+	if (copy_to_user(buffer, ptr, count))
+		return_VALUE(-EFAULT);
+
+	*ppos += count;
+	chars_remaining -= count;
+	ptr += count;
+
+	return_VALUE(count);
+}
+
+static int
+acpi_system_close_event(struct inode *inode, struct file *file)
+{
+	spin_lock_irq (&acpi_system_event_lock);
+	event_is_open = 0;
+	spin_unlock_irq (&acpi_system_event_lock);
+	return 0;
+}
+
+static unsigned int
+acpi_system_poll_event(
+	struct file		*file,
+	poll_table		*wait)
+{
+	poll_wait(file, &acpi_bus_event_queue, wait);
+	if (!list_empty(&acpi_bus_event_list))
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static struct file_operations acpi_system_event_ops = {
+	.open =		acpi_system_open_event,
+	.read =		acpi_system_read_event,
+	.release =	acpi_system_close_event,
+	.poll =		acpi_system_poll_event,
+};
+
+static int __init acpi_event_init(void)
+{
+	struct proc_dir_entry	*entry;
+	int error = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_event_init");
+
+	if (acpi_disabled)
+		return_VALUE(0);
+
+	/* 'event' [R] */
+	entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_event_ops;
+	else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				  "Unable to create '%s' proc fs entry\n","event" ));
+		error = -EFAULT;
+	}
+	return_VALUE(error);
+}
+
+subsys_initcall(acpi_event_init);
diff --git a/drivers/acpi/events/Makefile b/drivers/acpi/events/Makefile
new file mode 100644
index 0000000..d29f2ee
--- /dev/null
+++ b/drivers/acpi/events/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := evevent.o  evregion.o  evsci.o    evxfevnt.o \
+	 evmisc.o   evrgnini.o  evxface.o  evxfregn.o \
+	 evgpe.o    evgpeblk.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
new file mode 100644
index 0000000..2a21360
--- /dev/null
+++ b/drivers/acpi/events/evevent.c
@@ -0,0 +1,297 @@
+/******************************************************************************
+ *
+ * Module Name: evevent - Fixed Event handling and dispatch
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evevent")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_initialize_events
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize global data structures for events.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_initialize_events (
+	void)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_initialize_events");
+
+
+	/* Make sure we have ACPI tables */
+
+	if (!acpi_gbl_DSDT) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!\n"));
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	/*
+	 * Initialize the Fixed and General Purpose Events. This is
+	 * done prior to enabling SCIs to prevent interrupts from
+	 * occurring before handers are installed.
+	 */
+	status = acpi_ev_fixed_event_initialize ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR ((
+				"Unable to initialize fixed events, %s\n",
+				acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ev_gpe_initialize ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR ((
+				"Unable to initialize general purpose events, %s\n",
+				acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_xrupt_handlers
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_xrupt_handlers (
+	void)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_install_xrupt_handlers");
+
+
+	/* Install the SCI handler */
+
+	status = acpi_ev_install_sci_handler ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR ((
+				"Unable to install System Control Interrupt Handler, %s\n",
+				acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	/* Install the handler for the Global Lock */
+
+	status = acpi_ev_init_global_lock_handler ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR ((
+				"Unable to initialize Global Lock handler, %s\n",
+				acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	acpi_gbl_events_initialized = TRUE;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_fixed_event_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_fixed_event_initialize (
+	void)
+{
+	acpi_native_uint                i;
+	acpi_status                     status;
+
+
+	/*
+	 * Initialize the structure that keeps track of fixed event handlers
+	 * and enable the fixed events.
+	 */
+	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
+		acpi_gbl_fixed_event_handlers[i].handler = NULL;
+		acpi_gbl_fixed_event_handlers[i].context = NULL;
+
+		/* Enable 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_MTX_LOCK);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_fixed_event_detect
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Checks the PM status register for fixed events
+ *
+ ******************************************************************************/
+
+u32
+acpi_ev_fixed_event_detect (
+	void)
+{
+	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
+	u32                             fixed_status;
+	u32                             fixed_enable;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_NAME ("ev_fixed_event_detect");
+
+
+	/*
+	 * Read the fixed feature status and enable registers, as all the cases
+	 * depend on their values.  Ignore errors here.
+	 */
+	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, &fixed_status);
+	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+		"Fixed Event Block: Enable %08X Status %08X\n",
+		fixed_enable, fixed_status));
+
+	/*
+	 * Check for all possible Fixed Events and dispatch those that are active
+	 */
+	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
+		/* Both the status and enable bits must be on for this event */
+
+		if ((fixed_status & acpi_gbl_fixed_event_info[i].status_bit_mask) &&
+			(fixed_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) {
+			/* Found an active (signalled) event */
+
+			int_status |= acpi_ev_fixed_event_dispatch ((u32) i);
+		}
+	}
+
+	return (int_status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_fixed_event_dispatch
+ *
+ * PARAMETERS:  Event               - Event type
+ *
+ * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Clears the status bit for the requested event, calls the
+ *              handler that previously registered for the event.
+ *
+ ******************************************************************************/
+
+u32
+acpi_ev_fixed_event_dispatch (
+	u32                             event)
+{
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Clear the status bit */
+
+	(void) acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
+			 1, ACPI_MTX_DO_NOT_LOCK);
+
+	/*
+	 * 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, ACPI_MTX_DO_NOT_LOCK);
+
+		ACPI_REPORT_ERROR (
+			("No installed handler for fixed event [%08X]\n",
+			event));
+
+		return (ACPI_INTERRUPT_NOT_HANDLED);
+	}
+
+	/* Invoke the Fixed Event handler */
+
+	return ((acpi_gbl_fixed_event_handlers[event].handler)(
+			  acpi_gbl_fixed_event_handlers[event].context));
+}
+
+
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
new file mode 100644
index 0000000..118d72a
--- /dev/null
+++ b/drivers/acpi/events/evgpe.c
@@ -0,0 +1,756 @@
+/******************************************************************************
+ *
+ * Module Name: evgpe - General Purpose Event handling and dispatch
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evgpe")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_set_gpe_type
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to set
+ *              Type                    - New type
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_set_gpe_type (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              type)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_set_gpe_type");
+
+
+	/* Validate type and update register enable masks */
+
+	switch (type) {
+	case ACPI_GPE_TYPE_WAKE:
+	case ACPI_GPE_TYPE_RUNTIME:
+	case ACPI_GPE_TYPE_WAKE_RUN:
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Disable the GPE if currently enabled */
+
+	status = acpi_ev_disable_gpe (gpe_event_info);
+
+	/* Type was validated above */
+
+	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
+	gpe_event_info->flags |= type;              /* Insert type */
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_update_gpe_enable_masks
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to update
+ *              Type                    - What to do: ACPI_GPE_DISABLE or
+ *                                        ACPI_GPE_ENABLE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Updates GPE register enable masks based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_update_gpe_enable_masks (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              type)
+{
+	struct acpi_gpe_register_info   *gpe_register_info;
+	u8                              register_bit;
+
+
+	ACPI_FUNCTION_TRACE ("ev_update_gpe_enable_masks");
+
+
+	gpe_register_info = gpe_event_info->register_info;
+	if (!gpe_register_info) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+	register_bit = gpe_event_info->register_bit;
+
+	/* 1) Disable case.  Simply clear all enable bits */
+
+	if (type == ACPI_GPE_DISABLE) {
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* 2) Enable case.  Set/Clear the appropriate enable bits */
+
+	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+	case ACPI_GPE_TYPE_WAKE:
+		ACPI_SET_BIT   (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
+		break;
+
+	case ACPI_GPE_TYPE_RUNTIME:
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_SET_BIT   (gpe_register_info->enable_for_run, register_bit);
+		break;
+
+	case ACPI_GPE_TYPE_WAKE_RUN:
+		ACPI_SET_BIT   (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_SET_BIT   (gpe_register_info->enable_for_run, register_bit);
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_enable_gpe
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to enable
+ *              write_to_hardware       - Enable now, or just mark data structs
+ *                                        (WAKE GPEs should be deferred)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable a GPE based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_enable_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              write_to_hardware)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_enable_gpe");
+
+
+	/* Make sure HW enable masks are updated */
+
+	status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_ENABLE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Mark wake-enabled or HW enable, or both */
+
+	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+	case ACPI_GPE_TYPE_WAKE:
+
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+		break;
+
+	case ACPI_GPE_TYPE_WAKE_RUN:
+
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+
+		/*lint -fallthrough */
+
+	case ACPI_GPE_TYPE_RUNTIME:
+
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
+
+		if (write_to_hardware) {
+			/* Clear the GPE (of stale events), then enable it */
+
+			status = acpi_hw_clear_gpe (gpe_event_info);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			/* Enable the requested runtime GPE */
+
+			status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
+		}
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_disable_gpe
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to disable
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable a GPE based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_disable_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_disable_gpe");
+
+
+	if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Make sure HW enable masks are updated */
+
+	status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Mark wake-disabled or HW disable, or both */
+
+	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+	case ACPI_GPE_TYPE_WAKE:
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+		break;
+
+	case ACPI_GPE_TYPE_WAKE_RUN:
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+
+		/*lint -fallthrough */
+
+	case ACPI_GPE_TYPE_RUNTIME:
+
+		/* Disable the requested runtime GPE */
+
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
+		status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_get_gpe_event_info
+ *
+ * PARAMETERS:  gpe_device          - Device node.  NULL for GPE0/GPE1
+ *              gpe_number          - Raw GPE number
+ *
+ * RETURN:      A GPE event_info struct. NULL if not a valid GPE
+ *
+ * DESCRIPTION: Returns the event_info struct associated with this GPE.
+ *              Validates the gpe_block and the gpe_number
+ *
+ *              Should be called only when the GPE lists are semaphore locked
+ *              and not subject to change.
+ *
+ ******************************************************************************/
+
+struct acpi_gpe_event_info *
+acpi_ev_get_gpe_event_info (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number)
+{
+	union acpi_operand_object       *obj_desc;
+	struct acpi_gpe_block_info      *gpe_block;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* A NULL gpe_block means use the FADT-defined GPE block(s) */
+
+	if (!gpe_device) {
+		/* Examine GPE Block 0 and 1 (These blocks are permanent) */
+
+		for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) {
+			gpe_block = acpi_gbl_gpe_fadt_blocks[i];
+			if (gpe_block) {
+				if ((gpe_number >= gpe_block->block_base_number) &&
+					(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+					return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
+				}
+			}
+		}
+
+		/* The gpe_number was not in the range of either FADT GPE block */
+
+		return (NULL);
+	}
+
+	/* A Non-NULL gpe_device means this is a GPE Block Device */
+
+	obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) gpe_device);
+	if (!obj_desc ||
+		!obj_desc->device.gpe_block) {
+		return (NULL);
+	}
+
+	gpe_block = obj_desc->device.gpe_block;
+
+	if ((gpe_number >= gpe_block->block_base_number) &&
+		(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+		return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
+	}
+
+	return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_gpe_detect
+ *
+ * PARAMETERS:  gpe_xrupt_list      - Interrupt block for this interrupt.
+ *                                    Can have multiple GPE blocks attached.
+ *
+ * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Detect if any GP events have occurred.  This function is
+ *              executed at interrupt level.
+ *
+ ******************************************************************************/
+
+u32
+acpi_ev_gpe_detect (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_list)
+{
+	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
+	u8                              enabled_status_byte;
+	struct acpi_gpe_register_info   *gpe_register_info;
+	u32                             status_reg;
+	u32                             enable_reg;
+	acpi_status                     status;
+	struct acpi_gpe_block_info      *gpe_block;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
+
+
+	ACPI_FUNCTION_NAME ("ev_gpe_detect");
+
+	/* Check for the case where there are no GPEs */
+
+	if (!gpe_xrupt_list) {
+		return (int_status);
+	}
+
+	/* Examine all GPE blocks attached to this interrupt level */
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR);
+	gpe_block = gpe_xrupt_list->gpe_block_list_head;
+	while (gpe_block) {
+		/*
+		 * Read all of the 8-bit GPE status and enable registers
+		 * in this GPE block, saving all of them.
+		 * Find all currently active GP events.
+		 */
+		for (i = 0; i < gpe_block->register_count; i++) {
+			/* Get the next status/enable pair */
+
+			gpe_register_info = &gpe_block->register_info[i];
+
+			/* Read the Status Register */
+
+			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg,
+					 &gpe_register_info->status_address);
+			if (ACPI_FAILURE (status)) {
+				goto unlock_and_exit;
+			}
+
+			/* Read the Enable Register */
+
+			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg,
+					 &gpe_register_info->enable_address);
+			if (ACPI_FAILURE (status)) {
+				goto unlock_and_exit;
+			}
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+				"Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
+				gpe_register_info->base_gpe_number, status_reg, enable_reg));
+
+			/* First check if there is anything active at all in this register */
+
+			enabled_status_byte = (u8) (status_reg & enable_reg);
+			if (!enabled_status_byte) {
+				/* No active GPEs in this register, move on */
+
+				continue;
+			}
+
+			/* Now look at the individual GPEs in this byte register */
+
+			for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+				/* Examine one GPE bit */
+
+				if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) {
+					/*
+					 * Found an active GPE. Dispatch the event to a handler
+					 * or method.
+					 */
+					int_status |= acpi_ev_gpe_dispatch (
+							  &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
+							  (u32) j + gpe_register_info->base_gpe_number);
+				}
+			}
+		}
+
+		gpe_block = gpe_block->next;
+	}
+
+unlock_and_exit:
+
+	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR);
+	return (int_status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_asynch_execute_gpe_method
+ *
+ * PARAMETERS:  Context (gpe_event_info) - Info for this GPE
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Perform the actual execution of a GPE control method.  This
+ *              function is called from an invocation of acpi_os_queue_for_execution
+ *              (and therefore does NOT execute at interrupt level) so that
+ *              the control method itself is not executed in the context of
+ *              an interrupt handler.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_asynch_execute_gpe_method (
+	void                            *context)
+{
+	struct acpi_gpe_event_info      *gpe_event_info = (void *) context;
+	u32                             gpe_number = 0;
+	acpi_status                     status;
+	struct acpi_gpe_event_info      local_gpe_event_info;
+	struct acpi_parameter_info      info;
+
+
+	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_VOID;
+	}
+
+	/* Must revalidate the gpe_number/gpe_block */
+
+	if (!acpi_ev_valid_gpe_event (gpe_event_info)) {
+		status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+		return_VOID;
+	}
+
+	/* Set the GPE flags for return to enabled state */
+
+	(void) acpi_ev_enable_gpe (gpe_event_info, FALSE);
+
+	/*
+	 * Take a snapshot of the GPE info for this level - we copy the
+	 * info to prevent a race condition with remove_handler/remove_block.
+	 */
+	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));
+
+	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_VOID;
+	}
+
+	/*
+	 * Must check for control method type dispatch one more
+	 * time to avoid race with ev_gpe_install_handler
+	 */
+	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
+		/*
+		 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
+		 * control method that corresponds to this GPE
+		 */
+		info.node = local_gpe_event_info.dispatch.method_node;
+		info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info);
+		info.parameter_type = ACPI_PARAM_GPE;
+
+		status = acpi_ns_evaluate_by_handle (&info);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR ((
+				"%s while evaluating method [%4.4s] for GPE[%2X]\n",
+				acpi_format_exception (status),
+				acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node),
+				gpe_number));
+		}
+	}
+
+	if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
+		/*
+		 * GPE is level-triggered, we clear the GPE status bit after
+		 * handling the event.
+		 */
+		status = acpi_hw_clear_gpe (&local_gpe_event_info);
+		if (ACPI_FAILURE (status)) {
+			return_VOID;
+		}
+	}
+
+	/* Enable this GPE */
+
+	(void) acpi_hw_write_gpe_enable_reg (&local_gpe_event_info);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_gpe_dispatch
+ *
+ * PARAMETERS:  gpe_event_info  - info for this GPE
+ *              gpe_number      - Number relative to the parent GPE block
+ *
+ * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
+ *              or method (e.g. _Lxx/_Exx) handler.
+ *
+ *              This function executes at interrupt level.
+ *
+ ******************************************************************************/
+
+u32
+acpi_ev_gpe_dispatch (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u32                             gpe_number)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_gpe_dispatch");
+
+
+	/*
+	 * If edge-triggered, clear the GPE status bit now.  Note that
+	 * level-triggered events are cleared after the GPE is serviced.
+	 */
+	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_EDGE_TRIGGERED) {
+		status = acpi_hw_clear_gpe (gpe_event_info);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
+				acpi_format_exception (status), gpe_number));
+			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+	}
+
+	/* Save current system state */
+
+	if (acpi_gbl_system_awake_and_running) {
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
+	}
+	else {
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
+	}
+
+	/*
+	 * Dispatch the GPE to either an installed handler, or the control
+	 * method associated with this GPE (_Lxx or _Exx).
+	 * If a handler exists, we invoke it and do not attempt to run the method.
+	 * If there is neither a handler nor a method, we disable the level to
+	 * prevent further events from coming in here.
+	 */
+	switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
+	case ACPI_GPE_DISPATCH_HANDLER:
+
+		/*
+		 * Invoke the installed handler (at interrupt level)
+		 * Ignore return status for now.  TBD: leave GPE disabled on error?
+		 */
+		(void) gpe_event_info->dispatch.handler->address (
+				  gpe_event_info->dispatch.handler->context);
+
+		/* It is now safe to clear level-triggered events. */
+
+		if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
+			status = acpi_hw_clear_gpe (gpe_event_info);
+			if (ACPI_FAILURE (status)) {
+				ACPI_REPORT_ERROR ((
+					"acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
+					acpi_format_exception (status), gpe_number));
+				return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+			}
+		}
+		break;
+
+	case ACPI_GPE_DISPATCH_METHOD:
+
+		/*
+		 * Disable GPE, so it doesn't keep firing before the method has a
+		 * chance to run.
+		 */
+		status = acpi_ev_disable_gpe (gpe_event_info);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR ((
+				"acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
+				acpi_format_exception (status), gpe_number));
+			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+
+		/*
+		 * Execute the method associated with the GPE
+		 * NOTE: Level-triggered GPEs are cleared after the method completes.
+		 */
+		status = acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
+				 acpi_ev_asynch_execute_gpe_method, gpe_event_info);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR ((
+				"acpi_ev_gpe_dispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n",
+				acpi_format_exception (status), gpe_number));
+		}
+		break;
+
+	default:
+
+		/* No handler or method to run! */
+
+		ACPI_REPORT_ERROR ((
+			"acpi_ev_gpe_dispatch: No handler or method for GPE[%2X], disabling event\n",
+			gpe_number));
+
+		/*
+		 * Disable the GPE.  The GPE will remain disabled until the ACPI
+		 * Core Subsystem is restarted, or a handler is installed.
+		 */
+		status = acpi_ev_disable_gpe (gpe_event_info);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR ((
+				"acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n",
+				acpi_format_exception (status), gpe_number));
+			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+		break;
+	}
+
+	return_VALUE (ACPI_INTERRUPT_HANDLED);
+}
+
+
+#ifdef ACPI_GPE_NOTIFY_CHECK
+
+/*******************************************************************************
+ * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
+ *
+ * FUNCTION:    acpi_ev_check_for_wake_only_gpe
+ *
+ * PARAMETERS:  gpe_event_info  - info for this GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Determine if a a GPE is "wake-only".
+ *
+ *              Called from Notify() code in interpreter when a "device_wake"
+ *              Notify comes in.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_check_for_wake_only_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_check_for_wake_only_gpe");
+
+
+	if ((gpe_event_info) &&  /* Only >0 for _Lxx/_Exx */
+	   ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */ {
+		/* This must be a wake-only GPE, disable it */
+
+		status = acpi_ev_disable_gpe (gpe_event_info);
+
+		/* Set GPE to wake-only.  Do not change wake disabled/enabled status */
+
+		acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
+
+		ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n",
+				gpe_event_info));
+
+		/* This was a wake-only GPE */
+
+		return_ACPI_STATUS (AE_WAKE_ONLY_GPE);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+#endif
+
+
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
new file mode 100644
index 0000000..00d981f
--- /dev/null
+++ b/drivers/acpi/events/evgpeblk.c
@@ -0,0 +1,1141 @@
+/******************************************************************************
+ *
+ * Module Name: evgpeblk - GPE block creation and initialization.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evgpeblk")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_valid_gpe_event
+ *
+ * PARAMETERS:  gpe_event_info              - Info for this GPE
+ *
+ * RETURN:      TRUE if the gpe_event is valid
+ *
+ * DESCRIPTION: Validate a GPE event.  DO NOT CALL FROM INTERRUPT LEVEL.
+ *              Should be called only when the GPE lists are semaphore locked
+ *              and not subject to change.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ev_valid_gpe_event (
+	struct acpi_gpe_event_info      *gpe_event_info)
+{
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_block;
+	struct acpi_gpe_block_info      *gpe_block;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* No need for spin lock since we are not changing any list elements */
+
+	/* Walk the GPE interrupt levels */
+
+	gpe_xrupt_block = acpi_gbl_gpe_xrupt_list_head;
+	while (gpe_xrupt_block) {
+		gpe_block = gpe_xrupt_block->gpe_block_list_head;
+
+		/* Walk the GPE blocks on this interrupt level */
+
+		while (gpe_block) {
+			if ((&gpe_block->event_info[0] <= gpe_event_info) &&
+				(&gpe_block->event_info[((acpi_size) gpe_block->register_count) * 8] > gpe_event_info)) {
+				return (TRUE);
+			}
+
+			gpe_block = gpe_block->next;
+		}
+
+		gpe_xrupt_block = gpe_xrupt_block->next;
+	}
+
+	return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_walk_gpe_list
+ *
+ * PARAMETERS:  gpe_walk_callback   - Routine called for each GPE block
+ *              Flags               - ACPI_NOT_ISR or ACPI_ISR
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk the GPE lists.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_walk_gpe_list (
+	ACPI_GPE_CALLBACK       gpe_walk_callback,
+	u32                             flags)
+{
+	struct acpi_gpe_block_info      *gpe_block;
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ev_walk_gpe_list");
+
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, flags);
+
+	/* Walk the interrupt level descriptor list */
+
+	gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
+	while (gpe_xrupt_info) {
+		/* Walk all Gpe Blocks attached to this interrupt level */
+
+		gpe_block = gpe_xrupt_info->gpe_block_list_head;
+		while (gpe_block) {
+			/* One callback per GPE block */
+
+			status = gpe_walk_callback (gpe_xrupt_info, gpe_block);
+			if (ACPI_FAILURE (status)) {
+				goto unlock_and_exit;
+			}
+
+			gpe_block = gpe_block->next;
+		}
+
+		gpe_xrupt_info = gpe_xrupt_info->next;
+	}
+
+unlock_and_exit:
+	acpi_os_release_lock (acpi_gbl_gpe_lock, flags);
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_delete_gpe_handlers
+ *
+ * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
+ *              gpe_block           - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
+ *              Used only prior to termination.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_delete_gpe_handlers (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	struct acpi_gpe_event_info      *gpe_event_info;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
+
+
+	ACPI_FUNCTION_TRACE ("ev_delete_gpe_handlers");
+
+
+	/* Examine each GPE Register within the block */
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		/* 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[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+
+			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
+				ACPI_MEM_FREE (gpe_event_info->dispatch.handler);
+				gpe_event_info->dispatch.handler = NULL;
+				gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;
+			}
+		}
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_save_method_info
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
+ *              control method under the _GPE portion of the namespace.
+ *              Extract the name and GPE type from the object, saving this
+ *              information for quick lookup during GPE dispatch
+ *
+ *              The name of each GPE control method is of the form:
+ *              "_Lxx" or "_Exx"
+ *              Where:
+ *                  L      - means that the GPE is level triggered
+ *                  E      - means that the GPE is edge triggered
+ *                  xx     - is the GPE number [in HEX]
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_save_method_info (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *obj_desc,
+	void                            **return_value)
+{
+	struct acpi_gpe_block_info      *gpe_block = (void *) obj_desc;
+	struct acpi_gpe_event_info      *gpe_event_info;
+	u32                             gpe_number;
+	char                            name[ACPI_NAME_SIZE + 1];
+	u8                              type;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_save_method_info");
+
+
+	/*
+	 * _Lxx and _Exx GPE method support
+	 *
+	 * 1) Extract the name from the object and convert to a string
+	 */
+	ACPI_MOVE_32_TO_32 (name,
+			   &((struct acpi_namespace_node *) obj_handle)->name.integer);
+	name[ACPI_NAME_SIZE] = 0;
+
+	/*
+	 * 2) Edge/Level determination is based on the 2nd character
+	 *    of the method name
+	 *
+	 * NOTE: Default GPE type is RUNTIME.  May be changed later to WAKE
+	 * if a _PRW object is found that points to this GPE.
+	 */
+	switch (name[1]) {
+	case 'L':
+		type = ACPI_GPE_LEVEL_TRIGGERED;
+		break;
+
+	case 'E':
+		type = ACPI_GPE_EDGE_TRIGGERED;
+		break;
+
+	default:
+		/* Unknown method type, just ignore it! */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n",
+			name));
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Convert the last two characters of the name to the GPE Number */
+
+	gpe_number = ACPI_STRTOUL (&name[2], NULL, 16);
+	if (gpe_number == ACPI_UINT32_MAX) {
+		/* Conversion failed; invalid method, just ignore it */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n",
+			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)))) {
+		/*
+		 * 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 appear under \_GPE.
+		 */
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * Now we can add this information to the gpe_event_info block
+	 * for use during dispatch of this GPE.  Default type is RUNTIME, although
+	 * this may change when the _PRW methods are executed later.
+	 */
+	gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
+
+	gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD |
+			   ACPI_GPE_TYPE_RUNTIME);
+
+	gpe_event_info->dispatch.method_node = (struct acpi_namespace_node *) obj_handle;
+
+	/* Update enable mask, but don't enable the HW GPE as of yet */
+
+	status = acpi_ev_enable_gpe (gpe_event_info, FALSE);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
+		"Registered GPE method %s as GPE number 0x%.2X\n",
+		name, gpe_number));
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_match_prw_and_gpe
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status.  NOTE: We ignore errors so that the _PRW walk is
+ *              not aborted on a single _PRW failure.
+ *
+ * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
+ *              Device.  Run the _PRW method.  If present, extract the GPE
+ *              number and mark the GPE as a WAKE GPE.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_match_prw_and_gpe (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *info,
+	void                            **return_value)
+{
+	struct acpi_gpe_walk_info       *gpe_info = (void *) info;
+	struct acpi_namespace_node      *gpe_device;
+	struct acpi_gpe_block_info      *gpe_block;
+	struct acpi_namespace_node      *target_gpe_device;
+	struct acpi_gpe_event_info      *gpe_event_info;
+	union acpi_operand_object       *pkg_desc;
+	union acpi_operand_object       *obj_desc;
+	u32                             gpe_number;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_match_prw_and_gpe");
+
+
+	/* Check for a _PRW method under this device */
+
+	status = acpi_ut_evaluate_object (obj_handle, METHOD_NAME__PRW,
+			 ACPI_BTYPE_PACKAGE, &pkg_desc);
+	if (ACPI_FAILURE (status)) {
+		/* Ignore all errors from _PRW, we don't want to abort the subsystem */
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* The returned _PRW package must have at least two elements */
+
+	if (pkg_desc->package.count < 2) {
+		goto cleanup;
+	}
+
+	/* Extract pointers from the input context */
+
+	gpe_device = gpe_info->gpe_device;
+	gpe_block = gpe_info->gpe_block;
+
+	/*
+	 * The _PRW object must return a package, we are only interested
+	 * in the first element
+	 */
+	obj_desc = pkg_desc->package.elements[0];
+
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+		/* Use FADT-defined GPE device (from definition of _PRW) */
+
+		target_gpe_device = acpi_gbl_fadt_gpe_device;
+
+		/* 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) {
+		/* 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)) {
+			goto cleanup;
+		}
+
+		/* Get GPE block reference and decode */
+
+		target_gpe_device = obj_desc->package.elements[0]->reference.node;
+		gpe_number = (u32) obj_desc->package.elements[1]->integer.value;
+	}
+	else {
+		/* Unknown type, just ignore it */
+
+		goto cleanup;
+	}
+
+	/*
+	 * Is this GPE within this block?
+	 *
+	 * TRUE iff these conditions are true:
+	 *     1) The GPE devices match.
+	 *     2) The GPE index(number) is within the range of the Gpe Block
+	 *          associated with the GPE device.
+	 */
+	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];
+
+		/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
+
+		gpe_event_info->flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
+		status = acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+		status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
+	}
+
+cleanup:
+	acpi_ut_remove_reference (pkg_desc);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_get_gpe_xrupt_block
+ *
+ * PARAMETERS:  interrupt_level     - Interrupt for a GPE block
+ *
+ * RETURN:      A GPE interrupt block
+ *
+ * DESCRIPTION: Get or Create a GPE interrupt block.  There is one interrupt
+ *              block per unique interrupt level used for GPEs.
+ *              Should be called only when the GPE lists are semaphore locked
+ *              and not subject to change.
+ *
+ ******************************************************************************/
+
+static struct acpi_gpe_xrupt_info *
+acpi_ev_get_gpe_xrupt_block (
+	u32                             interrupt_level)
+{
+	struct acpi_gpe_xrupt_info      *next_gpe_xrupt;
+	struct acpi_gpe_xrupt_info      *gpe_xrupt;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_get_gpe_xrupt_block");
+
+
+	/* No need for spin lock since we are not changing any list elements here */
+
+	next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
+	while (next_gpe_xrupt) {
+		if (next_gpe_xrupt->interrupt_level == interrupt_level) {
+			return_PTR (next_gpe_xrupt);
+		}
+
+		next_gpe_xrupt = next_gpe_xrupt->next;
+	}
+
+	/* Not found, must allocate a new xrupt descriptor */
+
+	gpe_xrupt = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_xrupt_info));
+	if (!gpe_xrupt) {
+		return_PTR (NULL);
+	}
+
+	gpe_xrupt->interrupt_level = interrupt_level;
+
+	/* Install new interrupt descriptor with spin lock */
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	if (acpi_gbl_gpe_xrupt_list_head) {
+		next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
+		while (next_gpe_xrupt->next) {
+			next_gpe_xrupt = next_gpe_xrupt->next;
+		}
+
+		next_gpe_xrupt->next = gpe_xrupt;
+		gpe_xrupt->previous = next_gpe_xrupt;
+	}
+	else {
+		acpi_gbl_gpe_xrupt_list_head = gpe_xrupt;
+	}
+	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+
+	/* Install new interrupt handler if not SCI_INT */
+
+	if (interrupt_level != acpi_gbl_FADT->sci_int) {
+		status = acpi_os_install_interrupt_handler (interrupt_level,
+				 acpi_ev_gpe_xrupt_handler, gpe_xrupt);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not install GPE interrupt handler at level 0x%X\n",
+				interrupt_level));
+			return_PTR (NULL);
+		}
+	}
+
+	return_PTR (gpe_xrupt);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_delete_gpe_xrupt
+ *
+ * PARAMETERS:  gpe_xrupt       - A GPE interrupt info block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove and free a gpe_xrupt block. Remove an associated
+ *              interrupt handler if not the SCI interrupt.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_delete_gpe_xrupt (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_delete_gpe_xrupt");
+
+
+	/* We never want to remove the SCI interrupt handler */
+
+	if (gpe_xrupt->interrupt_level == acpi_gbl_FADT->sci_int) {
+		gpe_xrupt->gpe_block_list_head = NULL;
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Disable this interrupt */
+
+	status = acpi_os_remove_interrupt_handler (gpe_xrupt->interrupt_level,
+			   acpi_ev_gpe_xrupt_handler);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Unlink the interrupt block with lock */
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	if (gpe_xrupt->previous) {
+		gpe_xrupt->previous->next = gpe_xrupt->next;
+	}
+
+	if (gpe_xrupt->next) {
+		gpe_xrupt->next->previous = gpe_xrupt->previous;
+	}
+	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+
+	/* Free the block */
+
+	ACPI_MEM_FREE (gpe_xrupt);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_gpe_block
+ *
+ * PARAMETERS:  gpe_block       - New GPE block
+ *              interrupt_level - Level to be associated with this GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install new GPE block with mutex support
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_install_gpe_block (
+	struct acpi_gpe_block_info      *gpe_block,
+	u32                             interrupt_level)
+{
+	struct acpi_gpe_block_info      *next_gpe_block;
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_block;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_install_gpe_block");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	gpe_xrupt_block = acpi_ev_get_gpe_xrupt_block (interrupt_level);
+	if (!gpe_xrupt_block) {
+		status = AE_NO_MEMORY;
+		goto unlock_and_exit;
+	}
+
+	/* Install the new block at the end of the list for this interrupt with lock */
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	if (gpe_xrupt_block->gpe_block_list_head) {
+		next_gpe_block = gpe_xrupt_block->gpe_block_list_head;
+		while (next_gpe_block->next) {
+			next_gpe_block = next_gpe_block->next;
+		}
+
+		next_gpe_block->next = gpe_block;
+		gpe_block->previous = next_gpe_block;
+	}
+	else {
+		gpe_xrupt_block->gpe_block_list_head = gpe_block;
+	}
+
+	gpe_block->xrupt_block = gpe_xrupt_block;
+	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+
+unlock_and_exit:
+	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_delete_gpe_block
+ *
+ * PARAMETERS:  gpe_block       - Existing GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a GPE block
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_delete_gpe_block (
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_install_gpe_block");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Disable all GPEs in this block */
+
+	status = acpi_hw_disable_gpe_block (gpe_block->xrupt_block, gpe_block);
+
+	if (!gpe_block->previous && !gpe_block->next) {
+		/* This is the last gpe_block on this interrupt */
+
+		status = acpi_ev_delete_gpe_xrupt (gpe_block->xrupt_block);
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+	}
+	else {
+		/* Remove the block on this interrupt with lock */
+
+		acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+		if (gpe_block->previous) {
+			gpe_block->previous->next = gpe_block->next;
+		}
+		else {
+			gpe_block->xrupt_block->gpe_block_list_head = gpe_block->next;
+		}
+
+		if (gpe_block->next) {
+			gpe_block->next->previous = gpe_block->previous;
+		}
+		acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	}
+
+	/* Free the gpe_block */
+
+	ACPI_MEM_FREE (gpe_block->register_info);
+	ACPI_MEM_FREE (gpe_block->event_info);
+	ACPI_MEM_FREE (gpe_block);
+
+unlock_and_exit:
+	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_create_gpe_info_blocks
+ *
+ * PARAMETERS:  gpe_block   - New GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create the register_info and event_info blocks for this GPE block
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_create_gpe_info_blocks (
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	struct acpi_gpe_register_info   *gpe_register_info = NULL;
+	struct acpi_gpe_event_info      *gpe_event_info = NULL;
+	struct acpi_gpe_event_info      *this_event;
+	struct acpi_gpe_register_info   *this_register;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_create_gpe_info_blocks");
+
+
+	/* Allocate the GPE register information block */
+
+	gpe_register_info = ACPI_MEM_CALLOCATE (
+			  (acpi_size) gpe_block->register_count *
+			  sizeof (struct acpi_gpe_register_info));
+	if (!gpe_register_info) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not allocate the gpe_register_info table\n"));
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * Allocate the GPE event_info block. There are eight distinct GPEs
+	 * per register.  Initialization to zeros is sufficient.
+	 */
+	gpe_event_info = ACPI_MEM_CALLOCATE (
+			   ((acpi_size) gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) *
+			   sizeof (struct acpi_gpe_event_info));
+	if (!gpe_event_info) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_event_info table\n"));
+		status = AE_NO_MEMORY;
+		goto error_exit;
+	}
+
+	/* Save the new Info arrays in the GPE block */
+
+	gpe_block->register_info = gpe_register_info;
+	gpe_block->event_info  = gpe_event_info;
+
+	/*
+	 * Initialize the GPE Register and Event structures.  A goal of these
+	 * tables is to hide the fact that there are two separate GPE register sets
+	 * in a given gpe hardware block, the status registers occupy the first half,
+	 * and the enable registers occupy the second half.
+	 */
+	this_register = gpe_register_info;
+	this_event   = gpe_event_info;
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		/* Init the register_info for this GPE register (8 GPEs) */
+
+		this_register->base_gpe_number = (u8) (gpe_block->block_base_number +
+				   (i * ACPI_GPE_REGISTER_WIDTH));
+
+		ACPI_STORE_ADDRESS (this_register->status_address.address,
+				 (gpe_block->block_address.address
+				 + i));
+
+		ACPI_STORE_ADDRESS (this_register->enable_address.address,
+				 (gpe_block->block_address.address
+				 + i
+				 + gpe_block->register_count));
+
+		this_register->status_address.address_space_id = gpe_block->block_address.address_space_id;
+		this_register->enable_address.address_space_id = gpe_block->block_address.address_space_id;
+		this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
+		this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
+		this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
+		this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
+
+		/* Init the event_info for each GPE within this register */
+
+		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+			this_event->register_bit = acpi_gbl_decode_to8bit[j];
+			this_event->register_info = this_register;
+			this_event++;
+		}
+
+		/*
+		 * Clear the status/enable registers.  Note that status registers
+		 * are cleared by writing a '1', while enable registers are cleared
+		 * by writing a '0'.
+		 */
+		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00,
+				 &this_register->enable_address);
+		if (ACPI_FAILURE (status)) {
+			goto error_exit;
+		}
+
+		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF,
+				 &this_register->status_address);
+		if (ACPI_FAILURE (status)) {
+			goto error_exit;
+		}
+
+		this_register++;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+	if (gpe_register_info) {
+		ACPI_MEM_FREE (gpe_register_info);
+	}
+	if (gpe_event_info) {
+		ACPI_MEM_FREE (gpe_event_info);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_create_gpe_block
+ *
+ * PARAMETERS:  gpe_device          - Handle to the parent GPE block
+ *              gpe_block_address   - Address and space_iD
+ *              register_count      - Number of GPE register pairs in the block
+ *              gpe_block_base_number - Starting GPE number for the block
+ *              interrupt_level     - H/W interrupt for the block
+ *              return_gpe_block    - Where the new block descriptor is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_create_gpe_block (
+	struct acpi_namespace_node      *gpe_device,
+	struct acpi_generic_address     *gpe_block_address,
+	u32                             register_count,
+	u8                              gpe_block_base_number,
+	u32                             interrupt_level,
+	struct acpi_gpe_block_info      **return_gpe_block)
+{
+	struct acpi_gpe_block_info      *gpe_block;
+	struct acpi_gpe_event_info      *gpe_event_info;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
+	u32                             wake_gpe_count;
+	u32                             gpe_enabled_count;
+	acpi_status                     status;
+	struct acpi_gpe_walk_info       gpe_info;
+
+
+	ACPI_FUNCTION_TRACE ("ev_create_gpe_block");
+
+
+	if (!register_count) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Allocate a new GPE block */
+
+	gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info));
+	if (!gpe_block) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Initialize the new GPE block */
+
+	gpe_block->register_count = register_count;
+	gpe_block->block_base_number = gpe_block_base_number;
+	gpe_block->node           = gpe_device;
+
+	ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));
+
+	/* Create the register_info and event_info sub-structures */
+
+	status = acpi_ev_create_gpe_info_blocks (gpe_block);
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (gpe_block);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Install the new block in the global list(s) */
+
+	status = acpi_ev_install_gpe_block (gpe_block, interrupt_level);
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (gpe_block);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Find all GPE methods (_Lxx, _Exx) for this block */
+
+	status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
+			  ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info,
+			  gpe_block, NULL);
+
+	/*
+	 * Runtime option: Should Wake GPEs be enabled at runtime?  The default
+	 * is No, they should only be enabled just as the machine goes to sleep.
+	 */
+	if (acpi_gbl_leave_wake_gpes_disabled) {
+		/*
+		 * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods.
+		 * (Each GPE that has one or more _PRWs that reference it is by
+		 * definition a WAKE GPE and will not be enabled while the machine
+		 * is running.)
+		 */
+		gpe_info.gpe_block = gpe_block;
+		gpe_info.gpe_device = gpe_device;
+
+		status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_match_prw_and_gpe,
+				  &gpe_info, NULL);
+	}
+
+	/*
+	 * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs,
+	 * and 2) have a corresponding _Lxx or _Exx method.  All other GPEs must
+	 * be enabled via the acpi_enable_gpe() external interface.
+	 */
+	wake_gpe_count = 0;
+	gpe_enabled_count = 0;
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		for (j = 0; j < 8; j++) {
+			/* Get the info block for this particular GPE */
+
+			gpe_event_info = &gpe_block->event_info[(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)) {
+				gpe_enabled_count++;
+			}
+
+			if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) {
+				wake_gpe_count++;
+			}
+		}
+	}
+
+	/* Dump info about this GPE block */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+		"GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
+		(u32) gpe_block->block_base_number,
+		(u32) (gpe_block->block_base_number +
+				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
+		gpe_device->name.ascii,
+		gpe_block->register_count,
+		interrupt_level));
+
+	/* Enable all valid GPEs found above */
+
+	status = acpi_hw_enable_runtime_gpe_block (NULL, gpe_block);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+			"Found %u Wake, Enabled %u Runtime GPEs in this block\n",
+			wake_gpe_count, gpe_enabled_count));
+
+	/* Return the new block */
+
+	if (return_gpe_block) {
+		(*return_gpe_block) = gpe_block;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_gpe_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the GPE data structures
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_gpe_initialize (
+	void)
+{
+	u32                             register_count0 = 0;
+	u32                             register_count1 = 0;
+	u32                             gpe_number_max = 0;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_gpe_initialize");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * 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:
+	 *
+	 * "Each register block contains two registers of equal length
+	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
+	 *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
+	 *  The length of the GPE1_STS and GPE1_EN registers is equal to
+	 *  half the GPE1_LEN. If a generic register block is not supported
+	 *  then its respective block pointer and block length values in the
+	 *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
+	 *  to be the same size."
+	 */
+
+	/*
+	 * Determine the maximum GPE number for this machine.
+	 *
+	 * Note: both GPE0 and GPE1 are optional, and either can exist without
+	 * the other.
+	 *
+	 * If EITHER the register length OR the block address are zero, then that
+	 * particular block is not supported.
+	 */
+	if (acpi_gbl_FADT->gpe0_blk_len &&
+		acpi_gbl_FADT->xgpe0_blk.address) {
+		/* GPE block 0 exists (has both length and address > 0) */
+
+		register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2);
+
+		gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
+
+		/* Install GPE Block 0 */
+
+		status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device, &acpi_gbl_FADT->xgpe0_blk,
+				 register_count0, 0, acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]);
+
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR ((
+				"Could not create GPE Block 0, %s\n",
+				acpi_format_exception (status)));
+		}
+	}
+
+	if (acpi_gbl_FADT->gpe1_blk_len &&
+		acpi_gbl_FADT->xgpe1_blk.address) {
+		/* GPE block 1 exists (has both length and address > 0) */
+
+		register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2);
+
+		/* Check for GPE0/GPE1 overlap (if both banks exist) */
+
+		if ((register_count0) &&
+			(gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
+			ACPI_REPORT_ERROR ((
+				"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
+				gpe_number_max, acpi_gbl_FADT->gpe1_base,
+				acpi_gbl_FADT->gpe1_base +
+				((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
+
+			/* Ignore GPE1 block by setting the register count to zero */
+
+			register_count1 = 0;
+		}
+		else {
+			/* Install GPE Block 1 */
+
+			status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device, &acpi_gbl_FADT->xgpe1_blk,
+					 register_count1, acpi_gbl_FADT->gpe1_base,
+					 acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[1]);
+
+			if (ACPI_FAILURE (status)) {
+				ACPI_REPORT_ERROR ((
+					"Could not create GPE Block 1, %s\n",
+					acpi_format_exception (status)));
+			}
+
+			/*
+			 * GPE0 and GPE1 do not have to be contiguous in the GPE number
+			 * space. However, GPE0 always starts at GPE number zero.
+			 */
+			gpe_number_max = acpi_gbl_FADT->gpe1_base +
+					   ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+		}
+	}
+
+	/* Exit if there are no GPE registers */
+
+	if ((register_count0 + register_count1) == 0) {
+		/* GPEs are not required by ACPI, this is OK */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+				"There are no GPE blocks defined in the FADT\n"));
+		status = AE_OK;
+		goto cleanup;
+	}
+
+	/* Check for Max GPE number out-of-range */
+
+	if (gpe_number_max > ACPI_GPE_MAX) {
+		ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
+			gpe_number_max));
+		status = AE_BAD_VALUE;
+		goto cleanup;
+	}
+
+cleanup:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
new file mode 100644
index 0000000..2548efa
--- /dev/null
+++ b/drivers/acpi/events/evmisc.c
@@ -0,0 +1,588 @@
+/******************************************************************************
+ *
+ * Module Name: evmisc - Miscellaneous event manager support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_is_notify_object
+ *
+ * PARAMETERS:  Node            - Node to check
+ *
+ * RETURN:      TRUE if notifies allowed on this object
+ *
+ * DESCRIPTION: Check type of node for a object that supports notifies.
+ *
+ *              TBD: This could be replaced by a flag bit in the node.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ev_is_notify_object (
+	struct acpi_namespace_node      *node)
+{
+	switch (node->type) {
+	case ACPI_TYPE_DEVICE:
+	case ACPI_TYPE_PROCESSOR:
+	case ACPI_TYPE_POWER:
+	case ACPI_TYPE_THERMAL:
+		/*
+		 * These are the ONLY objects that can receive ACPI notifications
+		 */
+		return (TRUE);
+
+	default:
+		return (FALSE);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_queue_notify_request
+ *
+ * PARAMETERS:  Node            - NS node for the notified object
+ *              notify_value    - Value from the Notify() request
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Dispatch a device notification event to a previously
+ *              installed handler.
+ *
+ ******************************************************************************/
+
+#ifdef ACPI_DEBUG_OUTPUT
+static const char                *acpi_notify_value_names[] =
+{
+	"Bus Check",
+	"Device Check",
+	"Device Wake",
+	"Eject request",
+	"Device Check Light",
+	"Frequency Mismatch",
+	"Bus Mode Mismatch",
+	"Power Fault"
+};
+#endif
+
+acpi_status
+acpi_ev_queue_notify_request (
+	struct acpi_namespace_node      *node,
+	u32                             notify_value)
+{
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *handler_obj = NULL;
+	union acpi_generic_state        *notify_info;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_NAME ("ev_queue_notify_request");
+
+
+	/*
+	 * For value 3 (Ejection Request), some device method may need to be run.
+	 * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need to be run.
+	 * For value 0x80 (Status Change) on the power button or sleep button,
+	 * initiate soft-off or sleep operation?
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"Dispatching Notify(%X) on node %p\n", notify_value, node));
+
+	if (notify_value <= 7) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: %s\n",
+				acpi_notify_value_names[notify_value]));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: 0x%2.2X **Device Specific**\n",
+				notify_value));
+	}
+
+	/* Get the notify object attached to the NS Node */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (obj_desc) {
+		/* We have the notify object, Get the right handler */
+
+		switch (node->type) {
+		case ACPI_TYPE_DEVICE:
+		case ACPI_TYPE_THERMAL:
+		case ACPI_TYPE_PROCESSOR:
+		case ACPI_TYPE_POWER:
+
+			if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
+				handler_obj = obj_desc->common_notify.system_notify;
+			}
+			else {
+				handler_obj = obj_desc->common_notify.device_notify;
+			}
+			break;
+
+		default:
+			/* All other types are not supported */
+			return (AE_TYPE);
+		}
+	}
+
+	/* If there is any handler to run, schedule the dispatcher */
+
+	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);
+		}
+
+		notify_info->common.data_type = ACPI_DESC_TYPE_STATE_NOTIFY;
+		notify_info->notify.node      = node;
+		notify_info->notify.value     = (u16) notify_value;
+		notify_info->notify.handler_obj = handler_obj;
+
+		status = acpi_os_queue_for_execution (OSD_PRIORITY_HIGH,
+				  acpi_ev_notify_dispatch, notify_info);
+		if (ACPI_FAILURE (status)) {
+			acpi_ut_delete_generic_state (notify_info);
+		}
+	}
+
+	if (!handler_obj) {
+		/*
+		 * There is no per-device notify handler for this device.
+		 * This may or may not be a problem.
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"No notify handler for Notify(%4.4s, %X) node %p\n",
+			acpi_ut_get_node_name (node), notify_value, node));
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_notify_dispatch
+ *
+ * PARAMETERS:  Context         - To be passsed to the notify handler
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Dispatch a device notification event to a previously
+ *              installed handler.
+ *
+ ******************************************************************************/
+
+void ACPI_SYSTEM_XFACE
+acpi_ev_notify_dispatch (
+	void                            *context)
+{
+	union acpi_generic_state        *notify_info = (union acpi_generic_state *) context;
+	acpi_notify_handler             global_handler = NULL;
+	void                            *global_context = NULL;
+	union acpi_operand_object       *handler_obj;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * We will invoke a global notify handler if installed.
+	 * This is done _before_ we invoke the per-device handler attached to the device.
+	 */
+	if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
+		/* Global system notification handler */
+
+		if (acpi_gbl_system_notify.handler) {
+			global_handler = acpi_gbl_system_notify.handler;
+			global_context = acpi_gbl_system_notify.context;
+		}
+	}
+	else {
+		/* Global driver notification handler */
+
+		if (acpi_gbl_device_notify.handler) {
+			global_handler = acpi_gbl_device_notify.handler;
+			global_context = acpi_gbl_device_notify.context;
+		}
+	}
+
+	/* Invoke the system handler first, if present */
+
+	if (global_handler) {
+		global_handler (notify_info->notify.node, notify_info->notify.value, global_context);
+	}
+
+	/* Now invoke the per-device handler, if present */
+
+	handler_obj = notify_info->notify.handler_obj;
+	if (handler_obj) {
+		handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value,
+				  handler_obj->notify.context);
+	}
+
+	/* All done with the info object */
+
+	acpi_ut_delete_generic_state (notify_info);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_global_lock_thread
+ *
+ * PARAMETERS:  Context         - From thread interface, not used
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the
+ *              Global Lock.  Simply signal all threads that are waiting
+ *              for the lock.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_global_lock_thread (
+	void                            *context)
+{
+	acpi_status                     status;
+
+
+	/* Signal threads that are waiting for the lock */
+
+	if (acpi_gbl_global_lock_thread_count) {
+		/* Send sufficient units to the semaphore */
+
+		status = acpi_os_signal_semaphore (acpi_gbl_global_lock_semaphore,
+				 acpi_gbl_global_lock_thread_count);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Could not signal Global Lock semaphore\n"));
+		}
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_global_lock_handler
+ *
+ * PARAMETERS:  Context         - From thread interface, not used
+ *
+ * RETURN:      ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Invoked directly from the SCI handler when a global lock
+ *              release interrupt occurs.  Grab the global lock and queue
+ *              the global lock thread for execution
+ *
+ ******************************************************************************/
+
+static u32
+acpi_ev_global_lock_handler (
+	void                            *context)
+{
+	u8                              acquired = FALSE;
+	acpi_status                     status;
+
+
+	/*
+	 * Attempt to get the lock
+	 * If we don't get it now, it will be marked pending and we will
+	 * take another interrupt when it becomes free.
+	 */
+	ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired);
+	if (acquired) {
+		/* Got the lock, now wake all threads waiting for it */
+
+		acpi_gbl_global_lock_acquired = TRUE;
+
+		/* Run the Global Lock thread which will signal all waiting threads */
+
+		status = acpi_os_queue_for_execution (OSD_PRIORITY_HIGH,
+				  acpi_ev_global_lock_thread, context);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Could not queue Global Lock thread, %s\n",
+				acpi_format_exception (status)));
+
+			return (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+	}
+
+	return (ACPI_INTERRUPT_HANDLED);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_init_global_lock_handler
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for the global lock release event
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_init_global_lock_handler (void)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_init_global_lock_handler");
+
+
+	acpi_gbl_global_lock_present = TRUE;
+	status = acpi_install_fixed_event_handler (ACPI_EVENT_GLOBAL,
+			  acpi_ev_global_lock_handler, NULL);
+
+	/*
+	 * If the global lock does not exist on this platform, the attempt
+	 * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick)
+	 * Map to AE_OK, but mark global lock as not present.
+	 * Any attempt to actually use the global lock will be flagged
+	 * with an error.
+	 */
+	if (status == AE_NO_HARDWARE_RESPONSE) {
+		acpi_gbl_global_lock_present = FALSE;
+		status = AE_OK;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_acquire_global_lock
+ *
+ * PARAMETERS:  Timeout         - Max time to wait for the lock, in millisec.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Attempt to gain ownership of the Global Lock.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_ev_acquire_global_lock (
+	u16                             timeout)
+{
+	acpi_status                     status = AE_OK;
+	u8                              acquired = FALSE;
+
+
+	ACPI_FUNCTION_TRACE ("ev_acquire_global_lock");
+
+
+#ifndef ACPI_APPLICATION
+	/* Make sure that we actually have a global lock */
+
+	if (!acpi_gbl_global_lock_present) {
+		return_ACPI_STATUS (AE_NO_GLOBAL_LOCK);
+	}
+#endif
+
+	/* One more thread wants the global lock */
+
+	acpi_gbl_global_lock_thread_count++;
+
+	/* If we (OS side vs. BIOS side) have the hardware lock already, we are done */
+
+	if (acpi_gbl_global_lock_acquired) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* We must acquire the actual hardware lock */
+
+	ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired);
+	if (acquired) {
+	   /* We got the lock */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired the HW Global Lock\n"));
+
+		acpi_gbl_global_lock_acquired = TRUE;
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * Did not get the lock.  The pending bit was set above, and we must now
+	 * wait until we get the global lock released interrupt.
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n"));
+
+	/*
+	 * Acquire the global lock semaphore first.
+	 * Since this wait will block, we must release the interpreter
+	 */
+	status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore,
+			  timeout);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_release_global_lock
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Releases ownership of the Global Lock.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_release_global_lock (void)
+{
+	u8                              pending = FALSE;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ev_release_global_lock");
+
+
+	if (!acpi_gbl_global_lock_thread_count) {
+		ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n"));
+		return_ACPI_STATUS (AE_NOT_ACQUIRED);
+	}
+
+	/* One fewer thread has the global lock */
+
+	acpi_gbl_global_lock_thread_count--;
+	if (acpi_gbl_global_lock_thread_count) {
+		/* There are still some threads holding the lock, cannot release */
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * No more threads holding lock, we can do the actual hardware
+	 * release
+	 */
+	ACPI_RELEASE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, pending);
+	acpi_gbl_global_lock_acquired = FALSE;
+
+	/*
+	 * If the pending bit was set, we must write GBL_RLS to the control
+	 * register
+	 */
+	if (pending) {
+		status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE, 1, ACPI_MTX_LOCK);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_terminate
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Disable events and free memory allocated for table storage.
+ *
+ ******************************************************************************/
+
+void
+acpi_ev_terminate (void)
+{
+	acpi_native_uint                i;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_terminate");
+
+
+	if (acpi_gbl_events_initialized) {
+		/*
+		 * Disable all event-related functionality.
+		 * In all cases, on error, print a message but obviously we don't abort.
+		 */
+
+		/* Disable all fixed events */
+
+		for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
+			status = acpi_disable_event ((u32) i, 0);
+			if (ACPI_FAILURE (status)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable fixed event %d\n", (u32) i));
+			}
+		}
+
+		/* Disable all GPEs in all GPE blocks */
+
+		status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, ACPI_NOT_ISR);
+
+		/* Remove SCI handler */
+
+		status = acpi_ev_remove_sci_handler ();
+		if (ACPI_FAILURE(status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n"));
+		}
+	}
+
+	/* Deallocate all handler objects installed within GPE info structs */
+
+	status = acpi_ev_walk_gpe_list (acpi_ev_delete_gpe_handlers, ACPI_NOT_ISR);
+
+	/* Return to original mode if necessary */
+
+	if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
+		status = acpi_disable ();
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_disable failed\n"));
+		}
+	}
+	return_VOID;
+}
+
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
new file mode 100644
index 0000000..7723427
--- /dev/null
+++ b/drivers/acpi/events/evregion.c
@@ -0,0 +1,1067 @@
+/******************************************************************************
+ *
+ * Module Name: evregion - ACPI address_space (op_region) handler dispatch
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evregion")
+
+#define ACPI_NUM_DEFAULT_SPACES     4
+
+static u8                   acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
+			 ACPI_ADR_SPACE_SYSTEM_MEMORY,
+			 ACPI_ADR_SPACE_SYSTEM_IO,
+			 ACPI_ADR_SPACE_PCI_CONFIG,
+			 ACPI_ADR_SPACE_DATA_TABLE};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_region_handlers
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Installs the core subsystem default address space handlers.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_region_handlers (
+	void) {
+	acpi_status                     status;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("ev_install_region_handlers");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * All address spaces (PCI Config, EC, SMBus) are scope dependent
+	 * and registration must occur for a specific device.
+	 *
+	 * In the case of the system memory and IO address spaces there is currently
+	 * no device associated with the address space.  For these we use the root.
+	 *
+	 * We install the default PCI config space handler at the root so
+	 * that this space is immediately available even though the we have
+	 * not enumerated all the PCI Root Buses yet.  This is to conform
+	 * to the ACPI specification which states that the PCI config
+	 * space must be always available -- even though we are nowhere
+	 * near ready to find the PCI root buses at this point.
+	 *
+	 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
+	 * has already been installed (via acpi_install_address_space_handler).
+	 * Similar for AE_SAME_HANDLER.
+	 */
+	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
+		status = acpi_ev_install_space_handler (acpi_gbl_root_node,
+				  acpi_gbl_default_address_spaces[i],
+				  ACPI_DEFAULT_HANDLER, NULL, NULL);
+		switch (status) {
+		case AE_OK:
+		case AE_SAME_HANDLER:
+		case AE_ALREADY_EXISTS:
+
+			/* These exceptions are all OK */
+
+			status = AE_OK;
+			break;
+
+		default:
+
+			goto unlock_and_exit;
+		}
+	}
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_initialize_op_regions
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute _REG methods for all Operation Regions that have
+ *              an installed default region handler.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_initialize_op_regions (
+	void)
+{
+	acpi_status                     status;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("ev_initialize_op_regions");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Run the _REG methods for op_regions in each default address space
+	 */
+	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
+		/* TBD: Make sure handler is the DEFAULT handler, otherwise
+		 * _REG will have already been run.
+		 */
+		status = acpi_ev_execute_reg_methods (acpi_gbl_root_node,
+				  acpi_gbl_default_address_spaces[i]);
+	}
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_execute_reg_method
+ *
+ * PARAMETERS:  region_obj          - Object structure
+ *              Function            - Passed to _REG:  On (1) or Off (0)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute _REG method for a region
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_execute_reg_method (
+	union acpi_operand_object       *region_obj,
+	u32                             function)
+{
+	struct acpi_parameter_info      info;
+	union acpi_operand_object       *params[3];
+	union acpi_operand_object       *region_obj2;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_execute_reg_method");
+
+
+	region_obj2 = acpi_ns_get_secondary_object (region_obj);
+	if (!region_obj2) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	if (region_obj2->extra.method_REG == NULL) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * The _REG method has two arguments:
+	 *
+	 * Arg0, Integer: Operation region space ID
+	 *          Same value as region_obj->Region.space_id
+	 * Arg1, Integer: connection status
+	 *          1 for connecting the handler,
+	 *          0 for disconnecting the handler
+	 *          Passed as a parameter
+	 */
+	params[0] = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!params[0]) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	params[1] = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!params[1]) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/* Setup the parameter objects */
+
+	params[0]->integer.value = region_obj->region.space_id;
+	params[1]->integer.value = function;
+	params[2] = NULL;
+
+	info.node = region_obj2->extra.method_REG;
+	info.parameters = params;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
+	/* Execute the method, no return value */
+
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (
+			   ACPI_TYPE_METHOD, info.node, NULL));
+	status = acpi_ns_evaluate_by_handle (&info);
+
+	acpi_ut_remove_reference (params[1]);
+
+cleanup:
+	acpi_ut_remove_reference (params[0]);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_address_space_dispatch
+ *
+ * PARAMETERS:  region_obj          - Internal region object
+ *              Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, 32, or 64)
+ *              Value               - Pointer to in or out value
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Dispatch an address space or operation region access to
+ *              a previously installed handler.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_address_space_dispatch (
+	union acpi_operand_object       *region_obj,
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	void                            *value)
+{
+	acpi_status                     status;
+	acpi_status                     status2;
+	acpi_adr_space_handler          handler;
+	acpi_adr_space_setup            region_setup;
+	union acpi_operand_object       *handler_desc;
+	union acpi_operand_object       *region_obj2;
+	void                            *region_context = NULL;
+
+
+	ACPI_FUNCTION_TRACE ("ev_address_space_dispatch");
+
+
+	region_obj2 = acpi_ns_get_secondary_object (region_obj);
+	if (!region_obj2) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/* Ensure that there is a handler associated with this region */
+
+	handler_desc = region_obj->region.handler;
+	if (!handler_desc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"No handler for Region [%4.4s] (%p) [%s]\n",
+			acpi_ut_get_node_name (region_obj->region.node),
+			region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
+
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/*
+	 * It may be the case that the region has never been initialized
+	 * Some types of regions require special init code
+	 */
+	if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
+		/*
+		 * This region has not been initialized yet, do it
+		 */
+		region_setup = handler_desc->address_space.setup;
+		if (!region_setup) {
+			/* No initialization routine, exit with error */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
+				region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
+			return_ACPI_STATUS (AE_NOT_EXIST);
+		}
+
+		/*
+		 * We must exit the interpreter because the region setup will potentially
+		 * execute control methods (e.g., _REG method for this region)
+		 */
+		acpi_ex_exit_interpreter ();
+
+		status = region_setup (region_obj, ACPI_REGION_ACTIVATE,
+				  handler_desc->address_space.context, &region_context);
+
+		/* Re-enter the interpreter */
+
+		status2 = acpi_ex_enter_interpreter ();
+		if (ACPI_FAILURE (status2)) {
+			return_ACPI_STATUS (status2);
+		}
+
+		/* Check for failure of the Region Setup */
+
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
+				acpi_format_exception (status),
+				acpi_ut_get_region_name (region_obj->region.space_id)));
+			return_ACPI_STATUS (status);
+		}
+
+		/*
+		 * Region initialization may have been completed by region_setup
+		 */
+		if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
+			region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
+
+			if (region_obj2->extra.region_context) {
+				/* The handler for this region was already installed */
+
+				ACPI_MEM_FREE (region_context);
+			}
+			else {
+				/*
+				 * Save the returned context for use in all accesses to
+				 * this particular region
+				 */
+				region_obj2->extra.region_context = region_context;
+			}
+		}
+	}
+
+	/* We have everything we need, we can invoke the address space handler */
+
+	handler = handler_desc->address_space.handler;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+		"Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
+		&region_obj->region.handler->address_space, handler,
+		ACPI_FORMAT_UINT64 (address),
+		acpi_ut_get_region_name (region_obj->region.space_id)));
+
+	if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+		/*
+		 * For handlers other than the default (supplied) handlers, we must
+		 * exit the interpreter because the handler *might* block -- we don't
+		 * know what it will do, so we can't hold the lock on the intepreter.
+		 */
+		acpi_ex_exit_interpreter();
+	}
+
+	/* Call the handler */
+
+	status = handler (function, address, bit_width, value,
+			 handler_desc->address_space.context,
+			 region_obj2->extra.region_context);
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Handler for [%s] returned %s\n",
+			acpi_ut_get_region_name (region_obj->region.space_id),
+			acpi_format_exception (status)));
+	}
+
+	if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+		/*
+		 * We just returned from a non-default handler, we must re-enter the
+		 * interpreter
+		 */
+		status2 = acpi_ex_enter_interpreter ();
+		if (ACPI_FAILURE (status2)) {
+			return_ACPI_STATUS (status2);
+		}
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_detach_region
+ *
+ * PARAMETERS:  region_obj          - Region Object
+ *              acpi_ns_is_locked   - Namespace Region Already Locked?
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Break the association between the handler and the region
+ *              this is a two way association.
+ *
+ ******************************************************************************/
+
+void
+acpi_ev_detach_region(
+	union acpi_operand_object       *region_obj,
+	u8                              acpi_ns_is_locked)
+{
+	union acpi_operand_object       *handler_obj;
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       **last_obj_ptr;
+	acpi_adr_space_setup            region_setup;
+	void                            **region_context;
+	union acpi_operand_object       *region_obj2;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_detach_region");
+
+
+	region_obj2 = acpi_ns_get_secondary_object (region_obj);
+	if (!region_obj2) {
+		return_VOID;
+	}
+	region_context = &region_obj2->extra.region_context;
+
+	/* Get the address handler from the region object */
+
+	handler_obj = region_obj->region.handler;
+	if (!handler_obj) {
+		/* This region has no handler, all done */
+
+		return_VOID;
+	}
+
+	/* Find this region in the handler's list */
+
+	obj_desc = handler_obj->address_space.region_list;
+	last_obj_ptr = &handler_obj->address_space.region_list;
+
+	while (obj_desc) {
+		/* Is this the correct Region? */
+
+		if (obj_desc == region_obj) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+				"Removing Region %p from address handler %p\n",
+				region_obj, handler_obj));
+
+			/* This is it, remove it from the handler's list */
+
+			*last_obj_ptr = obj_desc->region.next;
+			obj_desc->region.next = NULL;           /* Must clear field */
+
+			if (acpi_ns_is_locked) {
+				status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+				if (ACPI_FAILURE (status)) {
+					return_VOID;
+				}
+			}
+
+			/* Now stop region accesses by executing the _REG method */
+
+			status = acpi_ev_execute_reg_method (region_obj, 0);
+			if (ACPI_FAILURE (status)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",
+					acpi_format_exception (status),
+					acpi_ut_get_region_name (region_obj->region.space_id)));
+			}
+
+			if (acpi_ns_is_locked) {
+				status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+				if (ACPI_FAILURE (status)) {
+					return_VOID;
+				}
+			}
+
+			/* Call the setup handler with the deactivate notification */
+
+			region_setup = handler_obj->address_space.setup;
+			status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
+					  handler_obj->address_space.context, region_context);
+
+			/* Init routine may fail, Just ignore errors */
+
+			if (ACPI_FAILURE (status)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",
+					acpi_format_exception (status),
+					acpi_ut_get_region_name (region_obj->region.space_id)));
+			}
+
+			region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
+
+			/*
+			 * Remove handler reference in the region
+			 *
+			 * NOTE: this doesn't mean that the region goes away
+			 * The region is just inaccessible as indicated to
+			 * the _REG method
+			 *
+			 * If the region is on the handler's list
+			 * this better be the region's handler
+			 */
+			region_obj->region.handler = NULL;
+			acpi_ut_remove_reference (handler_obj);
+
+			return_VOID;
+		}
+
+		/* Walk the linked list of handlers */
+
+		last_obj_ptr = &obj_desc->region.next;
+		obj_desc = obj_desc->region.next;
+	}
+
+	/* If we get here, the region was not in the handler's region list */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+		"Cannot remove region %p from address handler %p\n",
+		region_obj, handler_obj));
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_attach_region
+ *
+ * PARAMETERS:  handler_obj         - Handler Object
+ *              region_obj          - Region Object
+ *              acpi_ns_is_locked   - Namespace Region Already Locked?
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create the association between the handler and the region
+ *              this is a two way association.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_attach_region (
+	union acpi_operand_object       *handler_obj,
+	union acpi_operand_object       *region_obj,
+	u8                              acpi_ns_is_locked)
+{
+
+	ACPI_FUNCTION_TRACE ("ev_attach_region");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+		"Adding Region [%4.4s] %p to address handler %p [%s]\n",
+		acpi_ut_get_node_name (region_obj->region.node),
+		region_obj, handler_obj,
+		acpi_ut_get_region_name (region_obj->region.space_id)));
+
+	/* Link this region to the front of the handler's list */
+
+	region_obj->region.next = handler_obj->address_space.region_list;
+	handler_obj->address_space.region_list = region_obj;
+
+	/* Install the region's handler */
+
+	if (region_obj->region.handler) {
+		return_ACPI_STATUS (AE_ALREADY_EXISTS);
+	}
+
+	region_obj->region.handler = handler_obj;
+	acpi_ut_add_reference (handler_obj);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_handler
+ *
+ * PARAMETERS:  walk_namespace callback
+ *
+ * DESCRIPTION: This routine installs an address handler into objects that are
+ *              of type Region or Device.
+ *
+ *              If the Object is a Device, and the device has a handler of
+ *              the same type then the search is terminated in that branch.
+ *
+ *              This is because the existing handler is closer in proximity
+ *              to any more regions than the one we are trying to install.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_handler (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value)
+{
+	union acpi_operand_object       *handler_obj;
+	union acpi_operand_object       *next_handler_obj;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_NAME ("ev_install_handler");
+
+
+	handler_obj = (union acpi_operand_object   *) context;
+
+	/* Parameter validation */
+
+	if (!handler_obj) {
+		return (AE_OK);
+	}
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!node) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * We only care about regions.and objects
+	 * that are allowed to have address space handlers
+	 */
+	if ((node->type != ACPI_TYPE_DEVICE) &&
+		(node->type != ACPI_TYPE_REGION) &&
+		(node != acpi_gbl_root_node)) {
+		return (AE_OK);
+	}
+
+	/* Check for an existing internal object */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		/* No object, just exit */
+
+		return (AE_OK);
+	}
+
+	/* Devices are handled different than regions */
+
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
+		/* Check if this Device already has a handler for this address space */
+
+		next_handler_obj = obj_desc->device.handler;
+		while (next_handler_obj) {
+			/* Found a handler, is it for the same address space? */
+
+			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",
+					acpi_ut_get_region_name (handler_obj->address_space.space_id),
+					obj_desc, next_handler_obj, handler_obj));
+
+				/*
+				 * Since the object we found it on was a device, then it
+				 * means that someone has already installed a handler for
+				 * the branch of the namespace from this device on.  Just
+				 * bail out telling the walk routine to not traverse this
+				 * branch.  This preserves the scoping rule for handlers.
+				 */
+				return (AE_CTRL_DEPTH);
+			}
+
+			/* Walk the linked list of handlers attached to this device */
+
+			next_handler_obj = next_handler_obj->address_space.next;
+		}
+
+		/*
+		 * As long as the device didn't have a handler for this
+		 * space we don't care about it.  We just ignore it and
+		 * proceed.
+		 */
+		return (AE_OK);
+	}
+
+	/* Object is a Region */
+
+	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
+		/*
+		 * This region is for a different address space
+		 * -- just ignore it
+		 */
+		return (AE_OK);
+	}
+
+	/*
+	 * Now we have a region and it is for the handler's address
+	 * space type.
+	 *
+	 * First disconnect region for any previous handler (if any)
+	 */
+	acpi_ev_detach_region (obj_desc, FALSE);
+
+	/* Connect the region to the new handler */
+
+	status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_space_handler
+ *
+ * PARAMETERS:  Node            - Namespace node for the device
+ *              space_id        - The address space ID
+ *              Handler         - Address of the handler
+ *              Setup           - Address of the setup function
+ *              Context         - Value passed to the handler on each access
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for all op_regions of a given space_id.
+ *              Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_space_handler (
+	struct acpi_namespace_node      *node,
+	acpi_adr_space_type             space_id,
+	acpi_adr_space_handler          handler,
+	acpi_adr_space_setup            setup,
+	void                            *context)
+{
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *handler_obj;
+	acpi_status                     status;
+	acpi_object_type                type;
+	u16                             flags = 0;
+
+
+	ACPI_FUNCTION_TRACE ("ev_install_space_handler");
+
+
+	/*
+	 * This registration is valid for only the types below
+	 * and the root.  This is where the default handlers
+	 * get placed.
+	 */
+	if ((node->type != ACPI_TYPE_DEVICE)     &&
+		(node->type != ACPI_TYPE_PROCESSOR)  &&
+		(node->type != ACPI_TYPE_THERMAL)    &&
+		(node != acpi_gbl_root_node)) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	if (handler == ACPI_DEFAULT_HANDLER) {
+		flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
+
+		switch (space_id) {
+		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+			handler = acpi_ex_system_memory_space_handler;
+			setup   = acpi_ev_system_memory_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_SYSTEM_IO:
+			handler = acpi_ex_system_io_space_handler;
+			setup   = acpi_ev_io_space_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_PCI_CONFIG:
+			handler = acpi_ex_pci_config_space_handler;
+			setup   = acpi_ev_pci_config_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_CMOS:
+			handler = acpi_ex_cmos_space_handler;
+			setup   = acpi_ev_cmos_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_PCI_BAR_TARGET:
+			handler = acpi_ex_pci_bar_space_handler;
+			setup   = acpi_ev_pci_bar_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_DATA_TABLE:
+			handler = acpi_ex_data_table_space_handler;
+			setup   = NULL;
+			break;
+
+		default:
+			status = AE_BAD_PARAMETER;
+			goto unlock_and_exit;
+		}
+	}
+
+	/* If the caller hasn't specified a setup routine, use the default */
+
+	if (!setup) {
+		setup = acpi_ev_default_region_setup;
+	}
+
+	/* Check for an existing internal object */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (obj_desc) {
+		/*
+		 * The attached device object already exists.
+		 * Make sure the handler is not already installed.
+		 */
+		handler_obj = obj_desc->device.handler;
+
+		/* Walk the handler list for this device */
+
+		while (handler_obj) {
+			/* Same space_id indicates a handler already installed */
+
+			if (handler_obj->address_space.space_id == space_id) {
+				if (handler_obj->address_space.handler == handler) {
+					/*
+					 * It is (relatively) OK to attempt to install the SAME
+					 * handler twice. This can easily happen with PCI_Config space.
+					 */
+					status = AE_SAME_HANDLER;
+					goto unlock_and_exit;
+				}
+				else {
+					/* A handler is already installed */
+
+					status = AE_ALREADY_EXISTS;
+				}
+				goto unlock_and_exit;
+			}
+
+			/* Walk the linked list of handlers */
+
+			handler_obj = handler_obj->address_space.next;
+		}
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+			"Creating object on Device %p while installing handler\n", node));
+
+		/* obj_desc does not exist, create one */
+
+		if (node->type == ACPI_TYPE_ANY) {
+			type = ACPI_TYPE_DEVICE;
+		}
+		else {
+			type = node->type;
+		}
+
+		obj_desc = acpi_ut_create_internal_object (type);
+		if (!obj_desc) {
+			status = AE_NO_MEMORY;
+			goto unlock_and_exit;
+		}
+
+		/* Init new descriptor */
+
+		obj_desc->common.type = (u8) type;
+
+		/* Attach the new object to the Node */
+
+		status = acpi_ns_attach_object (node, obj_desc, type);
+
+		/* Remove local reference to the object */
+
+		acpi_ut_remove_reference (obj_desc);
+
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+		"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+		acpi_ut_get_region_name (space_id), space_id,
+		acpi_ut_get_node_name (node), node, obj_desc));
+
+	/*
+	 * Install the handler
+	 *
+	 * At this point there is no existing handler.
+	 * Just allocate the object for the handler and link it
+	 * into the list.
+	 */
+	handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
+	if (!handler_obj) {
+		status = AE_NO_MEMORY;
+		goto unlock_and_exit;
+	}
+
+	/* Init handler obj */
+
+	handler_obj->address_space.space_id  = (u8) space_id;
+	handler_obj->address_space.hflags    = flags;
+	handler_obj->address_space.region_list = NULL;
+	handler_obj->address_space.node      = node;
+	handler_obj->address_space.handler   = handler;
+	handler_obj->address_space.context   = context;
+	handler_obj->address_space.setup     = setup;
+
+	/* Install at head of Device.address_space list */
+
+	handler_obj->address_space.next      = obj_desc->device.handler;
+
+	/*
+	 * The Device object is the first reference on the handler_obj.
+	 * Each region that uses the handler adds a reference.
+	 */
+	obj_desc->device.handler = handler_obj;
+
+	/*
+	 * Walk the namespace finding all of the regions this
+	 * handler will manage.
+	 *
+	 * Start at the device and search the branch toward
+	 * the leaf nodes until either the leaf is encountered or
+	 * a device is detected that has an address handler of the
+	 * same type.
+	 *
+	 * In either case, back up and search down the remainder
+	 * of the branch
+	 */
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+			  ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
+			  handler_obj, NULL);
+
+unlock_and_exit:
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_execute_reg_methods
+ *
+ * PARAMETERS:  Node            - Namespace node for the device
+ *              space_id        - The address space ID
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Run all _REG methods for the input Space ID;
+ *              Note: assumes namespace is locked, or system init time.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_execute_reg_methods (
+	struct acpi_namespace_node      *node,
+	acpi_adr_space_type             space_id)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_execute_reg_methods");
+
+
+	/*
+	 * Run all _REG methods for all Operation Regions for this
+	 * space ID.  This is a separate walk in order to handle any
+	 * interdependencies between regions and _REG methods.  (i.e. handlers
+	 * must be installed for all regions of this Space ID before we
+	 * can run any _REG methods)
+	 */
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+			  ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
+			  &space_id, NULL);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_reg_run
+ *
+ * PARAMETERS:  walk_namespace callback
+ *
+ * DESCRIPTION: Run _REg method for region objects of the requested space_iD
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_reg_run (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value)
+{
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	acpi_adr_space_type             space_id;
+	acpi_status                     status;
+
+
+	space_id = *ACPI_CAST_PTR (acpi_adr_space_type, context);
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!node) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * We only care about regions.and objects
+	 * that are allowed to have address space handlers
+	 */
+	if ((node->type != ACPI_TYPE_REGION) &&
+		(node != acpi_gbl_root_node)) {
+		return (AE_OK);
+	}
+
+	/* Check for an existing internal object */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		/* No object, just exit */
+
+		return (AE_OK);
+	}
+
+	/* Object is a Region */
+
+	if (obj_desc->region.space_id != space_id) {
+		/*
+		 * This region is for a different address space
+		 * -- just ignore it
+		 */
+		return (AE_OK);
+	}
+
+	status = acpi_ev_execute_reg_method (obj_desc, 1);
+	return (status);
+}
+
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
new file mode 100644
index 0000000..4983a33
--- /dev/null
+++ b/drivers/acpi/events/evrgnini.c
@@ -0,0 +1,580 @@
+/******************************************************************************
+ *
+ * Module Name: evrgnini- ACPI address_space (op_region) init
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evrgnini")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_system_memory_region_setup
+ *
+ * PARAMETERS:  Handle              - Region we are interested in
+ *              Function            - Start or stop
+ *              handler_context     - Address space handler context
+ *              region_context      - Region specific context
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Do any prep work for region handling, a nop for now
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_system_memory_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context)
+{
+	union acpi_operand_object       *region_desc = (union acpi_operand_object *) handle;
+	struct acpi_mem_space_context   *local_region_context;
+
+
+	ACPI_FUNCTION_TRACE ("ev_system_memory_region_setup");
+
+
+	if (function == ACPI_REGION_DEACTIVATE) {
+		if (*region_context) {
+			ACPI_MEM_FREE (*region_context);
+			*region_context = NULL;
+		}
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Create a new context */
+
+	local_region_context = ACPI_MEM_CALLOCATE (sizeof (struct acpi_mem_space_context));
+	if (!(local_region_context)) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Save the region length and address for use in the handler */
+
+	local_region_context->length = region_desc->region.length;
+	local_region_context->address = region_desc->region.address;
+
+	*region_context = local_region_context;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_io_space_region_setup
+ *
+ * PARAMETERS:  Handle              - Region we are interested in
+ *              Function            - Start or stop
+ *              handler_context     - Address space handler context
+ *              region_context      - Region specific context
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_io_space_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context)
+{
+	ACPI_FUNCTION_TRACE ("ev_io_space_region_setup");
+
+
+	if (function == ACPI_REGION_DEACTIVATE) {
+		*region_context = NULL;
+	}
+	else {
+		*region_context = handler_context;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_pci_config_region_setup
+ *
+ * PARAMETERS:  Handle             - Region we are interested in
+ *              Function            - Start or stop
+ *              handler_context     - Address space handler context
+ *              region_context      - Region specific context
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ * MUTEX:       Assumes namespace is not locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_pci_config_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context)
+{
+	acpi_status                     status = AE_OK;
+	acpi_integer                    pci_value;
+	struct acpi_pci_id              *pci_id = *region_context;
+	union acpi_operand_object       *handler_obj;
+	struct acpi_namespace_node      *parent_node;
+	struct acpi_namespace_node      *pci_root_node;
+	union acpi_operand_object       *region_obj = (union acpi_operand_object   *) handle;
+	struct acpi_device_id           object_hID;
+
+
+	ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");
+
+
+	handler_obj = region_obj->region.handler;
+	if (!handler_obj) {
+		/*
+		 * No installed handler. This shouldn't happen because the dispatch
+		 * routine checks before we get here, but we check again just in case.
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+			"Attempting to init a region %p, with no handler\n", region_obj));
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	*region_context = NULL;
+	if (function == ACPI_REGION_DEACTIVATE) {
+		if (pci_id) {
+			ACPI_MEM_FREE (pci_id);
+		}
+		return_ACPI_STATUS (status);
+	}
+
+	parent_node = acpi_ns_get_parent_node (region_obj->region.node);
+
+	/*
+	 * Get the _SEG and _BBN values from the device upon which the handler
+	 * is installed.
+	 *
+	 * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
+	 * This is the device the handler has been registered to handle.
+	 */
+
+	/*
+	 * If the address_space.Node is still pointing to the root, we need
+	 * to scan upward for a PCI Root bridge and re-associate the op_region
+	 * handlers with that device.
+	 */
+	if (handler_obj->address_space.node == acpi_gbl_root_node) {
+		/* Start search from the parent object */
+
+		pci_root_node = parent_node;
+		while (pci_root_node != acpi_gbl_root_node) {
+			status = acpi_ut_execute_HID (pci_root_node, &object_hID);
+			if (ACPI_SUCCESS (status)) {
+				/* Got a valid _HID, check if this is a PCI root */
+
+				if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING,
+						   sizeof (PCI_ROOT_HID_STRING)))) {
+					/* Install a handler for this PCI root bridge */
+
+					status = acpi_install_address_space_handler ((acpi_handle) pci_root_node,
+							   ACPI_ADR_SPACE_PCI_CONFIG,
+							   ACPI_DEFAULT_HANDLER, NULL, NULL);
+					if (ACPI_FAILURE (status)) {
+						if (status == AE_SAME_HANDLER) {
+							/*
+							 * It is OK if the handler is already installed on the root
+							 * bridge.  Still need to return a context object for the
+							 * new PCI_Config operation region, however.
+							 */
+							status = AE_OK;
+						}
+						else {
+							ACPI_REPORT_ERROR ((
+								"Could not install pci_config handler for Root Bridge %4.4s, %s\n",
+								acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status)));
+						}
+					}
+					break;
+				}
+			}
+
+			pci_root_node = acpi_ns_get_parent_node (pci_root_node);
+		}
+
+		/* PCI root bridge not found, use namespace root node */
+	}
+	else {
+		pci_root_node = handler_obj->address_space.node;
+	}
+
+	/*
+	 * If this region is now initialized, we are done.
+	 * (install_address_space_handler could have initialized it)
+	 */
+	if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Region is still not initialized. Create a new context */
+
+	pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
+	if (!pci_id) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * For PCI_Config space access, we need the segment, bus,
+	 * device and function numbers.  Acquire them here.
+	 */
+
+	/*
+	 * 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, parent_node, &pci_value);
+
+	/*
+	 * The default is zero, and since the allocation above zeroed
+	 * the data, just do nothing on failure.
+	 */
+	if (ACPI_SUCCESS (status)) {
+		pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (pci_value));
+		pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value));
+	}
+
+	/* The PCI segment number comes from the _SEG method */
+
+	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);
+	if (ACPI_SUCCESS (status)) {
+		pci_id->bus = ACPI_LOWORD (pci_value);
+	}
+
+	/* Complete this device's pci_id */
+
+	acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id);
+
+	*region_context = pci_id;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_pci_bar_region_setup
+ *
+ * PARAMETERS:  Handle              - Region we are interested in
+ *              Function            - Start or stop
+ *              handler_context     - Address space handler context
+ *              region_context      - Region specific context
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ * MUTEX:       Assumes namespace is not locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_pci_bar_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context)
+{
+	ACPI_FUNCTION_TRACE ("ev_pci_bar_region_setup");
+
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_cmos_region_setup
+ *
+ * PARAMETERS:  Handle              - Region we are interested in
+ *              Function            - Start or stop
+ *              handler_context     - Address space handler context
+ *              region_context      - Region specific context
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ * MUTEX:       Assumes namespace is not locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_cmos_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context)
+{
+	ACPI_FUNCTION_TRACE ("ev_cmos_region_setup");
+
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_default_region_setup
+ *
+ * PARAMETERS:  Handle              - Region we are interested in
+ *              Function            - Start or stop
+ *              handler_context     - Address space handler context
+ *              region_context      - Region specific context
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Do any prep work for region handling
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_default_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context)
+{
+	ACPI_FUNCTION_TRACE ("ev_default_region_setup");
+
+
+	if (function == ACPI_REGION_DEACTIVATE) {
+		*region_context = NULL;
+	}
+	else {
+		*region_context = handler_context;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_initialize_region
+ *
+ * PARAMETERS:  region_obj      - Region we are initializing
+ *              acpi_ns_locked  - Is namespace locked?
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
+ *              for execution at a later time
+ *
+ *              Get the appropriate address space handler for a newly
+ *              created region.
+ *
+ *              This also performs address space specific initialization.  For
+ *              example, PCI regions must have an _ADR object that contains
+ *              a PCI address in the scope of the definition.  This address is
+ *              required to perform an access to PCI config space.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_initialize_region (
+	union acpi_operand_object       *region_obj,
+	u8                              acpi_ns_locked)
+{
+	union acpi_operand_object       *handler_obj;
+	union acpi_operand_object       *obj_desc;
+	acpi_adr_space_type             space_id;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+	struct acpi_namespace_node      *method_node;
+	acpi_name                       *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
+	union acpi_operand_object       *region_obj2;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ev_initialize_region", acpi_ns_locked);
+
+
+	if (!region_obj) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	region_obj2 = acpi_ns_get_secondary_object (region_obj);
+	if (!region_obj2) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	node = acpi_ns_get_parent_node (region_obj->region.node);
+	space_id = region_obj->region.space_id;
+
+	/* Setup defaults */
+
+	region_obj->region.handler = NULL;
+	region_obj2->extra.method_REG = NULL;
+	region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
+	region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
+
+	/* Find any "_REG" method associated with this region definition */
+
+	status = acpi_ns_search_node (*reg_name_ptr, node,
+			  ACPI_TYPE_METHOD, &method_node);
+	if (ACPI_SUCCESS (status)) {
+		/*
+		 * The _REG method is optional and there can be only one per region
+		 * definition.  This will be executed when the handler is attached
+		 * or removed
+		 */
+		region_obj2->extra.method_REG = method_node;
+	}
+
+	/*
+	 * The following loop depends upon the root Node having no parent
+	 * ie: acpi_gbl_root_node->parent_entry being set to NULL
+	 */
+	while (node) {
+		/* Check to see if a handler exists */
+
+		handler_obj = NULL;
+		obj_desc = acpi_ns_get_attached_object (node);
+		if (obj_desc) {
+			/* Can only be a handler if the object exists */
+
+			switch (node->type) {
+			case ACPI_TYPE_DEVICE:
+
+				handler_obj = obj_desc->device.handler;
+				break;
+
+			case ACPI_TYPE_PROCESSOR:
+
+				handler_obj = obj_desc->processor.handler;
+				break;
+
+			case ACPI_TYPE_THERMAL:
+
+				handler_obj = obj_desc->thermal_zone.handler;
+				break;
+
+			default:
+				/* Ignore other objects */
+				break;
+			}
+
+			while (handler_obj) {
+				/* Is this handler of the correct type? */
+
+				if (handler_obj->address_space.space_id == space_id) {
+					/* Found correct handler */
+
+					ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+						"Found handler %p for region %p in obj %p\n",
+						handler_obj, region_obj, obj_desc));
+
+					status = acpi_ev_attach_region (handler_obj, region_obj,
+							 acpi_ns_locked);
+
+					/*
+					 * Tell all users that this region is usable by running the _REG
+					 * method
+					 */
+					if (acpi_ns_locked) {
+						status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+						if (ACPI_FAILURE (status)) {
+							return_ACPI_STATUS (status);
+						}
+					}
+
+					status = acpi_ev_execute_reg_method (region_obj, 1);
+
+					if (acpi_ns_locked) {
+						status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+						if (ACPI_FAILURE (status)) {
+							return_ACPI_STATUS (status);
+						}
+					}
+
+					return_ACPI_STATUS (AE_OK);
+				}
+
+				/* Try next handler in the list */
+
+				handler_obj = handler_obj->address_space.next;
+			}
+		}
+
+		/*
+		 * This node does not have the handler we need;
+		 * Pop up one level
+		 */
+		node = acpi_ns_get_parent_node (node);
+	}
+
+	/* If we get here, there is no handler for this region */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+		"No handler for region_type %s(%X) (region_obj %p)\n",
+		acpi_ut_get_region_name (space_id), space_id, region_obj));
+
+	return_ACPI_STATUS (AE_NOT_EXIST);
+}
+
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
new file mode 100644
index 0000000..46b3199
--- /dev/null
+++ b/drivers/acpi/events/evsci.c
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ *
+ * Module Name: evsci - System Control Interrupt configuration and
+ *                      legacy to ACPI mode state transition functions
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evsci")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_sci_xrupt_handler
+ *
+ * PARAMETERS:  Context   - Calling Context
+ *
+ * RETURN:      Status code indicates whether interrupt was handled.
+ *
+ * DESCRIPTION: Interrupt handler that will figure out what function or
+ *              control method to call to deal with a SCI.
+ *
+ ******************************************************************************/
+
+static u32 ACPI_SYSTEM_XFACE
+acpi_ev_sci_xrupt_handler (
+	void                            *context)
+{
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_list = context;
+	u32                             interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
+
+
+	ACPI_FUNCTION_TRACE("ev_sci_xrupt_handler");
+
+
+	/*
+	 * We are guaranteed by the ACPI CA initialization/shutdown code that
+	 * if this interrupt handler is installed, ACPI is enabled.
+	 */
+
+	/*
+	 * Fixed Events:
+	 * Check for and dispatch any Fixed Events that have occurred
+	 */
+	interrupt_handled |= acpi_ev_fixed_event_detect ();
+
+	/*
+	 * General Purpose Events:
+	 * Check for and dispatch any GPEs that have occurred
+	 */
+	interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list);
+
+	return_VALUE (interrupt_handled);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_gpe_xrupt_handler
+ *
+ * PARAMETERS:  Context   - Calling Context
+ *
+ * RETURN:      Status code indicates whether interrupt was handled.
+ *
+ * DESCRIPTION: Handler for GPE Block Device interrupts
+ *
+ ******************************************************************************/
+
+u32 ACPI_SYSTEM_XFACE
+acpi_ev_gpe_xrupt_handler (
+	void                            *context)
+{
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_list = context;
+	u32                             interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
+
+
+	ACPI_FUNCTION_TRACE("ev_gpe_xrupt_handler");
+
+
+	/*
+	 * We are guaranteed by the ACPI CA initialization/shutdown code that
+	 * if this interrupt handler is installed, ACPI is enabled.
+	 */
+
+	/*
+	 * GPEs:
+	 * Check for and dispatch any GPEs that have occurred
+	 */
+	interrupt_handled |= acpi_ev_gpe_detect (gpe_xrupt_list);
+
+	return_VALUE (interrupt_handled);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_sci_handler
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Installs SCI handler.
+ *
+ ******************************************************************************/
+
+u32
+acpi_ev_install_sci_handler (void)
+{
+	u32                             status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ev_install_sci_handler");
+
+
+	status = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
+			   acpi_ev_sci_xrupt_handler, acpi_gbl_gpe_xrupt_list_head);
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_remove_sci_handler
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      E_OK if handler uninstalled OK, E_ERROR if handler was not
+ *              installed to begin with
+ *
+ * DESCRIPTION: Remove the SCI interrupt handler.  No further SCIs will be
+ *              taken.
+ *
+ * Note:  It doesn't seem important to disable all events or set the event
+ *        enable registers to their original values.  The OS should disable
+ *        the SCI interrupt level when the handler is removed, so no more
+ *        events will come in.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_remove_sci_handler (void)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_remove_sci_handler");
+
+
+	/* Just let the OS remove the handler and disable the level */
+
+	status = acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int,
+			   acpi_ev_sci_xrupt_handler);
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
new file mode 100644
index 0000000..0bfec10
--- /dev/null
+++ b/drivers/acpi/events/evxface.c
@@ -0,0 +1,834 @@
+/******************************************************************************
+ *
+ * Module Name: evxface - External interfaces for ACPI events
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/acinterp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_exception_handler
+ *
+ * PARAMETERS:  Handler         - Pointer to the handler function for the
+ *                                event
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_install_exception_handler (
+	acpi_exception_handler          handler)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_install_exception_handler");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Don't allow two handlers. */
+
+	if (acpi_gbl_exception_handler) {
+		status = AE_ALREADY_EXISTS;
+		goto cleanup;
+	}
+
+	/* Install the handler */
+
+	acpi_gbl_exception_handler = handler;
+
+cleanup:
+	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return_ACPI_STATUS (status);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_fixed_event_handler
+ *
+ * PARAMETERS:  Event           - Event type to enable.
+ *              Handler         - Pointer to the handler function for the
+ *                                event
+ *              Context         - Value passed to the handler on each GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function and then enables the
+ *              event.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_install_fixed_event_handler (
+	u32                             event,
+	acpi_event_handler              handler,
+	void                            *context)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_install_fixed_event_handler");
+
+
+	/* Parameter validation */
+
+	if (event > ACPI_EVENT_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Don't allow two handlers. */
+
+	if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
+		status = AE_ALREADY_EXISTS;
+		goto cleanup;
+	}
+
+	/* Install the handler before enabling the event */
+
+	acpi_gbl_fixed_event_handlers[event].handler = handler;
+	acpi_gbl_fixed_event_handlers[event].context = context;
+
+	status = acpi_clear_event (event);
+	if (ACPI_SUCCESS(status))
+		status = acpi_enable_event (event, 0);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
+
+		/* Remove the handler */
+
+		acpi_gbl_fixed_event_handlers[event].handler = NULL;
+		acpi_gbl_fixed_event_handlers[event].context = NULL;
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"Enabled fixed event %X, Handler=%p\n", event, handler));
+	}
+
+
+cleanup:
+	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_install_fixed_event_handler);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_remove_fixed_event_handler
+ *
+ * PARAMETERS:  Event           - Event type to disable.
+ *              Handler         - Address of the handler
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disables the event and unregisters the event handler.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_remove_fixed_event_handler (
+	u32                             event,
+	acpi_event_handler              handler)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_remove_fixed_event_handler");
+
+
+	/* Parameter validation */
+
+	if (event > ACPI_EVENT_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Disable the event before removing the handler */
+
+	status = acpi_disable_event (event, 0);
+
+	/* Always Remove the handler */
+
+	acpi_gbl_fixed_event_handlers[event].handler = NULL;
+	acpi_gbl_fixed_event_handlers[event].context = NULL;
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
+			"Could not write to fixed event enable register.\n"));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", event));
+	}
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_remove_fixed_event_handler);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_notify_handler
+ *
+ * PARAMETERS:  Device          - The device for which notifies will be handled
+ *              handler_type    - The type of handler:
+ *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
+ *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
+ *                                  ACPI_ALL_NOTIFY:  both system and device
+ *              Handler         - Address of the handler
+ *              Context         - Value passed to the handler on each GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for notifies on an ACPI device
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_install_notify_handler (
+	acpi_handle                     device,
+	u32                             handler_type,
+	acpi_notify_handler             handler,
+	void                            *context)
+{
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *notify_obj;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_install_notify_handler");
+
+
+	/* Parameter validation */
+
+	if ((!device)  ||
+		(!handler) ||
+		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_map_handle_to_node (device);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/*
+	 * Root Object:
+	 * Registering a notify handler on the root object indicates that the
+	 * caller wishes to receive notifications for all objects.  Note that
+	 * only one <external> global handler can be regsitered (per notify type).
+	 */
+	if (device == ACPI_ROOT_OBJECT) {
+		/* Make sure the handler is not already installed */
+
+		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
+				acpi_gbl_system_notify.handler)     ||
+			((handler_type & ACPI_DEVICE_NOTIFY) &&
+				acpi_gbl_device_notify.handler)) {
+			status = AE_ALREADY_EXISTS;
+			goto unlock_and_exit;
+		}
+
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
+			acpi_gbl_system_notify.node  = node;
+			acpi_gbl_system_notify.handler = handler;
+			acpi_gbl_system_notify.context = context;
+		}
+
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
+			acpi_gbl_device_notify.node  = node;
+			acpi_gbl_device_notify.handler = handler;
+			acpi_gbl_device_notify.context = context;
+		}
+
+		/* Global notify handler installed */
+	}
+
+	/*
+	 * All Other Objects:
+	 * Caller will only receive notifications specific to the target object.
+	 * Note that only certain object types can receive notifications.
+	 */
+	else {
+		/* Notifies allowed on this object? */
+
+		if (!acpi_ev_is_notify_object (node)) {
+			status = AE_TYPE;
+			goto unlock_and_exit;
+		}
+
+		/* Check for an existing internal object */
+
+		obj_desc = acpi_ns_get_attached_object (node);
+		if (obj_desc) {
+			/* Object exists - make sure there's no handler */
+
+			if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
+					obj_desc->common_notify.system_notify) ||
+				((handler_type & ACPI_DEVICE_NOTIFY) &&
+					obj_desc->common_notify.device_notify)) {
+				status = AE_ALREADY_EXISTS;
+				goto unlock_and_exit;
+			}
+		}
+		else {
+			/* Create a new object */
+
+			obj_desc = acpi_ut_create_internal_object (node->type);
+			if (!obj_desc) {
+				status = AE_NO_MEMORY;
+				goto unlock_and_exit;
+			}
+
+			/* Attach new object to the Node */
+
+			status = acpi_ns_attach_object (device, obj_desc, node->type);
+
+			/* Remove local reference to the object */
+
+			acpi_ut_remove_reference (obj_desc);
+			if (ACPI_FAILURE (status)) {
+				goto unlock_and_exit;
+			}
+		}
+
+		/* Install the handler */
+
+		notify_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_NOTIFY);
+		if (!notify_obj) {
+			status = AE_NO_MEMORY;
+			goto unlock_and_exit;
+		}
+
+		notify_obj->notify.node   = node;
+		notify_obj->notify.handler = handler;
+		notify_obj->notify.context = context;
+
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
+			obj_desc->common_notify.system_notify = notify_obj;
+		}
+
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
+			obj_desc->common_notify.device_notify = notify_obj;
+		}
+
+		if (handler_type == ACPI_ALL_NOTIFY) {
+			/* Extra ref if installed in both */
+
+			acpi_ut_add_reference (notify_obj);
+		}
+	}
+
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_install_notify_handler);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_remove_notify_handler
+ *
+ * PARAMETERS:  Device          - The device for which notifies will be handled
+ *              handler_type    - The type of handler:
+ *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
+ *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
+ *                                  ACPI_ALL_NOTIFY:  both system and device
+ *              Handler         - Address of the handler
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a handler for notifies on an ACPI device
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_remove_notify_handler (
+	acpi_handle                     device,
+	u32                             handler_type,
+	acpi_notify_handler             handler)
+{
+	union acpi_operand_object       *notify_obj;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_remove_notify_handler");
+
+
+	/* Parameter validation */
+
+	if ((!device)  ||
+		(!handler) ||
+		(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_map_handle_to_node (device);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Root Object */
+
+	if (device == ACPI_ROOT_OBJECT) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
+
+		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
+			  !acpi_gbl_system_notify.handler)      ||
+			((handler_type & ACPI_DEVICE_NOTIFY) &&
+			  !acpi_gbl_device_notify.handler)) {
+			status = AE_NOT_EXIST;
+			goto unlock_and_exit;
+		}
+
+		/* Make sure all deferred tasks are completed */
+
+		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		acpi_os_wait_events_complete(NULL);
+		status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+ 		}
+
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
+			acpi_gbl_system_notify.node  = NULL;
+			acpi_gbl_system_notify.handler = NULL;
+			acpi_gbl_system_notify.context = NULL;
+		}
+
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
+			acpi_gbl_device_notify.node  = NULL;
+			acpi_gbl_device_notify.handler = NULL;
+			acpi_gbl_device_notify.context = NULL;
+		}
+	}
+
+	/* All Other Objects */
+
+	else {
+		/* Notifies allowed on this object? */
+
+		if (!acpi_ev_is_notify_object (node)) {
+			status = AE_TYPE;
+			goto unlock_and_exit;
+		}
+
+		/* Check for an existing internal object */
+
+		obj_desc = acpi_ns_get_attached_object (node);
+		if (!obj_desc) {
+			status = AE_NOT_EXIST;
+			goto unlock_and_exit;
+		}
+
+		/* Object exists - make sure there's an existing handler */
+
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
+			notify_obj = obj_desc->common_notify.system_notify;
+			if ((!notify_obj) ||
+				 (notify_obj->notify.handler != handler)) {
+				status = AE_BAD_PARAMETER;
+				goto unlock_and_exit;
+			}
+			/* Make sure all deferred tasks are completed */
+
+			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+			acpi_os_wait_events_complete(NULL);
+			status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+ 			}
+
+			/* Remove the handler */
+			obj_desc->common_notify.system_notify = NULL;
+			acpi_ut_remove_reference (notify_obj);
+		}
+
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
+			notify_obj = obj_desc->common_notify.device_notify;
+			if ((!notify_obj) ||
+				 (notify_obj->notify.handler != handler)) {
+				status = AE_BAD_PARAMETER;
+				goto unlock_and_exit;
+			}
+			/* Make sure all deferred tasks are completed */
+
+			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+			acpi_os_wait_events_complete(NULL);
+			status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+ 			}
+
+			/* Remove the handler */
+			obj_desc->common_notify.device_notify = NULL;
+			acpi_ut_remove_reference (notify_obj);
+		}
+	}
+
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_remove_notify_handler);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_gpe_handler
+ *
+ * PARAMETERS:  gpe_number      - The GPE number within the GPE block
+ *              gpe_block       - GPE block (NULL == FADT GPEs)
+ *              Type            - Whether this GPE should be treated as an
+ *                                edge- or level-triggered interrupt.
+ *              Address         - Address of the handler
+ *              Context         - Value passed to the handler on each GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for a General Purpose Event.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_install_gpe_handler (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	u32                             type,
+	acpi_event_handler              address,
+	void                            *context)
+{
+	struct acpi_gpe_event_info      *gpe_event_info;
+	struct acpi_handler_info        *handler;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
+
+
+	/* Parameter validation */
+
+	if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Make sure that there isn't a handler there already */
+
+	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
+		status = AE_ALREADY_EXISTS;
+		goto unlock_and_exit;
+	}
+
+	/* Allocate and init handler object */
+
+	handler = ACPI_MEM_CALLOCATE (sizeof (struct acpi_handler_info));
+	if (!handler) {
+		status = AE_NO_MEMORY;
+		goto unlock_and_exit;
+	}
+
+	handler->address    = address;
+	handler->context    = context;
+	handler->method_node = gpe_event_info->dispatch.method_node;
+
+	/* Disable the GPE before installing the handler */
+
+	status = acpi_ev_disable_gpe (gpe_event_info);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
+	/* Install the handler */
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	gpe_event_info->dispatch.handler = handler;
+
+	/* 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 |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
+
+	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_install_gpe_handler);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_remove_gpe_handler
+ *
+ * PARAMETERS:  gpe_number      - The event to remove a handler
+ *              gpe_block       - GPE block (NULL == FADT GPEs)
+ *              Address         - Address of the handler
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_remove_gpe_handler (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	acpi_event_handler              address)
+{
+	struct acpi_gpe_event_info      *gpe_event_info;
+	struct acpi_handler_info        *handler;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
+
+
+	/* Parameter validation */
+
+	if (!address) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Make sure that a handler is indeed installed */
+
+	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) {
+		status = AE_NOT_EXIST;
+		goto unlock_and_exit;
+	}
+
+	/* Make sure that the installed handler is the same */
+
+	if (gpe_event_info->dispatch.handler->address != address) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Disable the GPE before removing the handler */
+
+	status = acpi_ev_disable_gpe (gpe_event_info);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
+	/* Make sure all deferred tasks are completed */
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	acpi_os_wait_events_complete(NULL);
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+ 	}
+
+	/* Remove the handler */
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	handler = gpe_event_info->dispatch.handler;
+
+	/* Restore Method node (if any), set dispatch flags */
+
+	gpe_event_info->dispatch.method_node = handler->method_node;
+	gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
+	if (handler->method_node) {
+		gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
+	}
+	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+
+	/* Now we can free the handler object */
+
+	ACPI_MEM_FREE (handler);
+
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_remove_gpe_handler);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_acquire_global_lock
+ *
+ * PARAMETERS:  Timeout         - How long the caller is willing to wait
+ *              out_handle      - A handle to the lock if acquired
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire the ACPI Global Lock
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_acquire_global_lock (
+	u16                             timeout,
+	u32                             *handle)
+{
+	acpi_status                     status;
+
+
+	if (!handle) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ex_enter_interpreter ();
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	status = acpi_ev_acquire_global_lock (timeout);
+	acpi_ex_exit_interpreter ();
+
+	if (ACPI_SUCCESS (status)) {
+		acpi_gbl_global_lock_handle++;
+		*handle = acpi_gbl_global_lock_handle;
+	}
+
+	return (status);
+}
+EXPORT_SYMBOL(acpi_acquire_global_lock);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_release_global_lock
+ *
+ * PARAMETERS:  Handle      - Returned from acpi_acquire_global_lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release the ACPI Global Lock
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_release_global_lock (
+	u32                             handle)
+{
+	acpi_status                     status;
+
+
+	if (handle != acpi_gbl_global_lock_handle) {
+		return (AE_NOT_ACQUIRED);
+	}
+
+	status = acpi_ev_release_global_lock ();
+	return (status);
+}
+EXPORT_SYMBOL(acpi_release_global_lock);
+
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
new file mode 100644
index 0000000..fa8d5f2
--- /dev/null
+++ b/drivers/acpi/events/evxfevnt.c
@@ -0,0 +1,778 @@
+/******************************************************************************
+ *
+ * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evxfevnt")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_enable
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Transfers the system into ACPI mode.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enable (void)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enable");
+
+
+	/* Make sure we have the FADT*/
+
+	if (!acpi_gbl_FADT) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
+	}
+	else {
+		/* Transition to ACPI mode */
+
+		status = acpi_hw_set_mode (ACPI_SYS_MODE_ACPI);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n"));
+			return_ACPI_STATUS (status);
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n"));
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_disable
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Transfers the system into LEGACY mode.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_disable (void)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_disable");
+
+
+	if (!acpi_gbl_FADT) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n"));
+	}
+	else {
+		/* Transition to LEGACY mode */
+
+		status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY);
+
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not exit ACPI mode to legacy mode"));
+			return_ACPI_STATUS (status);
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n"));
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_enable_event
+ *
+ * PARAMETERS:  Event           - The fixed eventto be enabled
+ *              Flags           - Reserved
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enable_event (
+	u32                             event,
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+	u32                             value;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enable_event");
+
+
+	/* Decode the Fixed Event */
+
+	if (event > ACPI_EVENT_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Enable the requested fixed event (by writing a one to the
+	 * enable register bit)
+	 */
+	status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+			 1, ACPI_MTX_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Make sure that the hardware responded */
+
+	status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+			  &value, ACPI_MTX_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (value != 1) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not enable %s event\n", acpi_ut_get_event_name (event)));
+		return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+	}
+
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_enable_event);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_set_gpe_type
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device
+ *              gpe_number      - GPE level within the GPE block
+ *              Type            - New GPE type
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_set_gpe_type (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	u8                              type)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_gpe_event_info      *gpe_event_info;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_set_gpe_type");
+
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Set the new type (will disable GPE if currently enabled) */
+
+	status = acpi_ev_set_gpe_type (gpe_event_info, type);
+
+unlock_and_exit:
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_set_gpe_type);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_enable_gpe
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device
+ *              gpe_number      - GPE level within the GPE block
+ *              Flags           - Just enable, or also wake enable?
+ *                                Called from ISR or not
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enable_gpe (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_gpe_event_info      *gpe_event_info;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
+
+
+	/* Use semaphore lock if not executing at interrupt level */
+
+	if (flags & ACPI_NOT_ISR) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Perform the enable */
+
+	status = acpi_ev_enable_gpe (gpe_event_info, TRUE);
+
+unlock_and_exit:
+	if (flags & ACPI_NOT_ISR) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	}
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_enable_gpe);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_disable_gpe
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device
+ *              gpe_number      - GPE level within the GPE block
+ *              Flags           - Just disable, or also wake disable?
+ *                                Called from ISR or not
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_disable_gpe (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_gpe_event_info      *gpe_event_info;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_disable_gpe");
+
+
+	/* Use semaphore lock if not executing at interrupt level */
+
+	if (flags & ACPI_NOT_ISR) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	status = acpi_ev_disable_gpe (gpe_event_info);
+
+unlock_and_exit:
+	if (flags & ACPI_NOT_ISR) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_disable_event
+ *
+ * PARAMETERS:  Event           - The fixed eventto be enabled
+ *              Flags           - Reserved
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_disable_event (
+	u32                             event,
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+	u32                             value;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_disable_event");
+
+
+	/* Decode the Fixed Event */
+
+	if (event > ACPI_EVENT_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Disable the requested fixed event (by writing a zero to the
+	 * enable register bit)
+	 */
+	status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+			 0, ACPI_MTX_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+			 &value, ACPI_MTX_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (value != 0) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not disable %s events\n", acpi_ut_get_event_name (event)));
+		return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+	}
+
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_disable_event);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_clear_event
+ *
+ * PARAMETERS:  Event           - The fixed event to be cleared
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_clear_event (
+	u32                             event)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_clear_event");
+
+
+	/* Decode the Fixed Event */
+
+	if (event > ACPI_EVENT_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Clear the requested fixed event (By writing a one to the
+	 * status register bit)
+	 */
+	status = acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
+			1, ACPI_MTX_LOCK);
+
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_clear_event);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_clear_gpe
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device
+ *              gpe_number      - GPE level within the GPE block
+ *              Flags           - Called from an ISR or not
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_clear_gpe (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_gpe_event_info      *gpe_event_info;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_clear_gpe");
+
+
+	/* Use semaphore lock if not executing at interrupt level */
+
+	if (flags & ACPI_NOT_ISR) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	status = acpi_hw_clear_gpe (gpe_event_info);
+
+unlock_and_exit:
+	if (flags & ACPI_NOT_ISR) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_event_status
+ *
+ * PARAMETERS:  Event           - The fixed event
+ *              Event Status    - Where the current status of the event will
+ *                                be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtains and returns the current status of the event
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_event_status (
+	u32                             event,
+	acpi_event_status               *event_status)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_event_status");
+
+
+	if (!event_status) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Decode the Fixed Event */
+
+	if (event > ACPI_EVENT_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Get the status of the requested fixed event */
+
+	status = acpi_get_register (acpi_gbl_fixed_event_info[event].status_register_id,
+			  event_status, ACPI_MTX_LOCK);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_gpe_status
+ *
+ * PARAMETERS:  gpe_device      - Parent GPE Device
+ *              gpe_number      - GPE level within the GPE block
+ *              Flags           - Called from an ISR or not
+ *              Event Status    - Where the current status of the event will
+ *                                be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get status of an event (general purpose)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_gpe_status (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	u32                             flags,
+	acpi_event_status               *event_status)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_gpe_event_info      *gpe_event_info;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_gpe_status");
+
+
+	/* Use semaphore lock if not executing at interrupt level */
+
+	if (flags & ACPI_NOT_ISR) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Ensure that we have a valid GPE number */
+
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Obtain status on the requested GPE number */
+
+	status = acpi_hw_get_gpe_status (gpe_event_info, event_status);
+
+unlock_and_exit:
+	if (flags & ACPI_NOT_ISR) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	}
+	return_ACPI_STATUS (status);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_gpe_block
+ *
+ * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
+ *              gpe_block_address   - Address and space_iD
+ *              register_count      - Number of GPE register pairs in the block
+ *              interrupt_level     - H/W interrupt for the block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_install_gpe_block (
+	acpi_handle                     gpe_device,
+	struct acpi_generic_address     *gpe_block_address,
+	u32                             register_count,
+	u32                             interrupt_level)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	struct acpi_gpe_block_info      *gpe_block;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_install_gpe_block");
+
+
+	if ((!gpe_device)      ||
+		(!gpe_block_address) ||
+		(!register_count)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	node = acpi_ns_map_handle_to_node (gpe_device);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/*
+	 * For user-installed GPE Block Devices, the gpe_block_base_number
+	 * is always zero
+	 */
+	status = acpi_ev_create_gpe_block (node, gpe_block_address, register_count,
+			  0, interrupt_level, &gpe_block);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
+	/* Get the device_object attached to the node */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		/* No object, create a new one */
+
+		obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_DEVICE);
+		if (!obj_desc) {
+			status = AE_NO_MEMORY;
+			goto unlock_and_exit;
+		}
+
+		status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE);
+
+		/* Remove local reference to the object */
+
+		acpi_ut_remove_reference (obj_desc);
+
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+	}
+
+	/* Install the GPE block in the device_object */
+
+	obj_desc->device.gpe_block = gpe_block;
+
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_install_gpe_block);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_remove_gpe_block
+ *
+ * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a previously installed block of GPE registers
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_remove_gpe_block (
+	acpi_handle                     gpe_device)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_remove_gpe_block");
+
+
+	if (!gpe_device) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	node = acpi_ns_map_handle_to_node (gpe_device);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Get the device_object attached to the node */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc ||
+		!obj_desc->device.gpe_block) {
+		return_ACPI_STATUS (AE_NULL_OBJECT);
+	}
+
+	/* Delete the GPE block (but not the device_object) */
+
+	status = acpi_ev_delete_gpe_block (obj_desc->device.gpe_block);
+	if (ACPI_SUCCESS (status)) {
+		obj_desc->device.gpe_block = NULL;
+	}
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_remove_gpe_block);
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
new file mode 100644
index 0000000..d058587
--- /dev/null
+++ b/drivers/acpi/events/evxfregn.c
@@ -0,0 +1,247 @@
+/******************************************************************************
+ *
+ * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
+ *                         Address Spaces.
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evxfregn")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_address_space_handler
+ *
+ * PARAMETERS:  Device          - Handle for the device
+ *              space_id        - The address space ID
+ *              Handler         - Address of the handler
+ *              Setup           - Address of the setup function
+ *              Context         - Value passed to the handler on each access
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for all op_regions of a given space_id.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_install_address_space_handler (
+	acpi_handle                     device,
+	acpi_adr_space_type             space_id,
+	acpi_adr_space_handler          handler,
+	acpi_adr_space_setup            setup,
+	void                            *context)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_install_address_space_handler");
+
+
+	/* Parameter validation */
+
+	if (!device) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_map_handle_to_node (device);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Install the handler for all Regions for this Space ID */
+
+	status = acpi_ev_install_space_handler (node, space_id, handler, setup, context);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
+	/* Run all _REG methods for this address space */
+
+	status = acpi_ev_execute_reg_methods (node, space_id);
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_install_address_space_handler);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_remove_address_space_handler
+ *
+ * PARAMETERS:  Device          - Handle for the device
+ *              space_id        - The address space ID
+ *              Handler         - Address of the handler
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a previously installed handler.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_remove_address_space_handler (
+	acpi_handle                     device,
+	acpi_adr_space_type             space_id,
+	acpi_adr_space_handler          handler)
+{
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *handler_obj;
+	union acpi_operand_object       *region_obj;
+	union acpi_operand_object       **last_obj_ptr;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_remove_address_space_handler");
+
+
+	/* Parameter validation */
+
+	if (!device) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_map_handle_to_node (device);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Make sure the internal object exists */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		status = AE_NOT_EXIST;
+		goto unlock_and_exit;
+	}
+
+	/* Find the address handler the user requested */
+
+	handler_obj = obj_desc->device.handler;
+	last_obj_ptr = &obj_desc->device.handler;
+	while (handler_obj) {
+		/* We have a handler, see if user requested this one */
+
+		if (handler_obj->address_space.space_id == space_id) {
+			/* 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",
+				handler_obj, handler, acpi_ut_get_region_name (space_id),
+				node, obj_desc));
+
+			region_obj = handler_obj->address_space.region_list;
+
+			/* Walk the handler's region list */
+
+			while (region_obj) {
+				/*
+				 * First disassociate the handler from the region.
+				 *
+				 * NOTE: this doesn't mean that the region goes away
+				 * The region is just inaccessible as indicated to
+				 * the _REG method
+				 */
+				acpi_ev_detach_region (region_obj, TRUE);
+
+				/*
+				 * Walk the list: Just grab the head because the
+				 * detach_region removed the previous head.
+				 */
+				region_obj = handler_obj->address_space.region_list;
+
+			}
+
+			/* Remove this Handler object from the list */
+
+			*last_obj_ptr = handler_obj->address_space.next;
+
+			/* Now we can delete the handler object */
+
+			acpi_ut_remove_reference (handler_obj);
+			goto unlock_and_exit;
+		}
+
+		/* Walk the linked list of handlers */
+
+		last_obj_ptr = &handler_obj->address_space.next;
+		handler_obj = handler_obj->address_space.next;
+	}
+
+	/* The handler does not exist */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+		"Unable to remove address handler %p for %s(%X), dev_node %p, obj %p\n",
+		handler, acpi_ut_get_region_name (space_id), space_id, node, obj_desc));
+
+	status = AE_NOT_EXIST;
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_remove_address_space_handler);
+
diff --git a/drivers/acpi/executer/Makefile b/drivers/acpi/executer/Makefile
new file mode 100644
index 0000000..e09998a
--- /dev/null
+++ b/drivers/acpi/executer/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := exconfig.o  exfield.o  exnames.o   exoparg6.o  exresolv.o  exstorob.o\
+	 exconvrt.o  exfldio.o  exoparg1.o  exprep.o    exresop.o   exsystem.o\
+	 excreate.o  exmisc.o   exoparg2.o  exregion.o  exstore.o   exutils.o \
+	 exdump.o    exmutex.o  exoparg3.o  exresnte.o  exstoren.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
new file mode 100644
index 0000000..ac3c061
--- /dev/null
+++ b/drivers/acpi/executer/exconfig.c
@@ -0,0 +1,487 @@
+/******************************************************************************
+ *
+ * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/actables.h>
+#include <acpi/acdispat.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exconfig")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_add_table
+ *
+ * PARAMETERS:  Table               - Pointer to raw table
+ *              parent_node         - Where to load the table (scope)
+ *              ddb_handle          - Where to return the table handle.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Common function to Install and Load an ACPI table with a
+ *              returned table handle.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_add_table (
+	struct acpi_table_header        *table,
+	struct acpi_namespace_node      *parent_node,
+	union acpi_operand_object       **ddb_handle)
+{
+	acpi_status                     status;
+	struct acpi_table_desc          table_info;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE ("ex_add_table");
+
+
+	/* Create an object to be the table handle */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Install the new table into the local data structures */
+
+	ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
+
+	table_info.type        = ACPI_TABLE_SSDT;
+	table_info.pointer     = table;
+	table_info.length      = (acpi_size) table->length;
+	table_info.allocation  = ACPI_MEM_ALLOCATED;
+
+	status = acpi_tb_install_table (&table_info);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Add the table to the namespace */
+
+	status = acpi_ns_load_table (table_info.installed_desc, parent_node);
+	if (ACPI_FAILURE (status)) {
+		/* Uninstall table on error */
+
+		(void) acpi_tb_uninstall_table (table_info.installed_desc);
+		goto cleanup;
+	}
+
+	/* Init the table handle */
+
+	obj_desc->reference.opcode = AML_LOAD_OP;
+	obj_desc->reference.object = table_info.installed_desc;
+	*ddb_handle = obj_desc;
+	return_ACPI_STATUS (AE_OK);
+
+
+cleanup:
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_load_table_op
+ *
+ * PARAMETERS:  walk_state          - Current state with operands
+ *              return_desc         - Where to store the return object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load an ACPI table
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_load_table_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       **return_desc)
+{
+	acpi_status                     status;
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	struct acpi_table_header        *table;
+	struct acpi_namespace_node      *parent_node;
+	struct acpi_namespace_node      *start_node;
+	struct acpi_namespace_node      *parameter_node = NULL;
+	union acpi_operand_object       *ddb_handle;
+
+
+	ACPI_FUNCTION_TRACE ("ex_load_table_op");
+
+
+#if 0
+	/*
+	 * Make sure that the signature does not match one of the tables that
+	 * is already loaded.
+	 */
+	status = acpi_tb_match_signature (operand[0]->string.pointer, NULL);
+	if (status == AE_OK) {
+		/* Signature matched -- don't allow override */
+
+		return_ACPI_STATUS (AE_ALREADY_EXISTS);
+	}
+#endif
+
+	/* Find the ACPI table */
+
+	status = acpi_tb_find_table (operand[0]->string.pointer,
+			   operand[1]->string.pointer,
+			   operand[2]->string.pointer, &table);
+	if (ACPI_FAILURE (status)) {
+		if (status != AE_NOT_FOUND) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* Table not found, return an Integer=0 and AE_OK */
+
+		ddb_handle = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!ddb_handle) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		ddb_handle->integer.value = 0;
+		*return_desc = ddb_handle;
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Default nodes */
+
+	start_node = walk_state->scope_info->scope.node;
+	parent_node = acpi_gbl_root_node;
+
+	/* root_path (optional parameter) */
+
+	if (operand[3]->string.length > 0) {
+		/*
+		 * Find the node referenced by the root_path_string. This is the
+		 * location within the namespace where the table will be loaded.
+		 */
+		status = acpi_ns_get_node_by_path (operand[3]->string.pointer, start_node,
+				   ACPI_NS_SEARCH_PARENT, &parent_node);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* parameter_path (optional parameter) */
+
+	if (operand[4]->string.length > 0) {
+		if ((operand[4]->string.pointer[0] != '\\') &&
+			(operand[4]->string.pointer[0] != '^')) {
+			/*
+			 * Path is not absolute, so it will be relative to the node
+			 * referenced by the root_path_string (or the NS root if omitted)
+			 */
+			start_node = parent_node;
+		}
+
+		/*
+		 * Find the node referenced by the parameter_path_string
+		 */
+		status = acpi_ns_get_node_by_path (operand[4]->string.pointer, start_node,
+				   ACPI_NS_SEARCH_PARENT, &parameter_node);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Load the table into the namespace */
+
+	status = acpi_ex_add_table (table, parent_node, &ddb_handle);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Parameter Data (optional) */
+
+	if (parameter_node) {
+		/* Store the parameter data into the optional parameter object */
+
+		status = acpi_ex_store (operand[5], ACPI_CAST_PTR (union acpi_operand_object, parameter_node),
+				 walk_state);
+		if (ACPI_FAILURE (status)) {
+			(void) acpi_ex_unload_table (ddb_handle);
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	*return_desc = ddb_handle;
+	return_ACPI_STATUS  (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_load_op
+ *
+ * PARAMETERS:  obj_desc        - Region or Field where the table will be
+ *                                obtained
+ *              Target          - Where a handle to the table will be stored
+ *              walk_state      - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load an ACPI table from a field or operation region
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_load_op (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *target,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *ddb_handle;
+	union acpi_operand_object       *buffer_desc = NULL;
+	struct acpi_table_header        *table_ptr = NULL;
+	acpi_physical_address           address;
+	struct acpi_table_header        table_header;
+	u32                             i;
+
+	ACPI_FUNCTION_TRACE ("ex_load_op");
+
+
+	/* Object can be either an op_region or a Field */
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_REGION:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n",
+			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
+
+		/*
+		 * If the Region Address and Length have not been previously evaluated,
+		 * evaluate them now and save the results.
+		 */
+		if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+			status = acpi_ds_get_region_arguments (obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+
+		/* Get the base physical address of the region */
+
+		address = obj_desc->region.address;
+
+		/* Get the table length from the table header */
+
+		table_header.length = 0;
+		for (i = 0; i < 8; i++) {
+			status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
+					   (acpi_physical_address) (i + address), 8,
+					   ((u8 *) &table_header) + i);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+
+		/* Sanity check the table length */
+
+		if (table_header.length < sizeof (struct acpi_table_header)) {
+			return_ACPI_STATUS (AE_BAD_HEADER);
+		}
+
+		/* Allocate a buffer for the entire table */
+
+		table_ptr = ACPI_MEM_ALLOCATE (table_header.length);
+		if (!table_ptr) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Get the entire table from the op region */
+
+		for (i = 0; i < table_header.length; i++) {
+			status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
+					   (acpi_physical_address) (i + address), 8,
+					   ((u8 *) table_ptr + i));
+			if (ACPI_FAILURE (status)) {
+				goto cleanup;
+			}
+		}
+		break;
+
+
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Field %p %s\n",
+			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
+
+		/*
+		 * The length of the field must be at least as large as the table.
+		 * Read the entire field and thus the entire table.  Buffer is
+		 * allocated during the read.
+		 */
+		status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer);
+
+		 /* Sanity check the table length */
+
+		if (table_ptr->length < sizeof (struct acpi_table_header)) {
+			return_ACPI_STATUS (AE_BAD_HEADER);
+		}
+		break;
+
+
+	default:
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+	}
+
+	/* The table must be either an SSDT or a PSDT */
+
+	if ((!ACPI_STRNCMP (table_ptr->signature,
+			  acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
+			  acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
+		(!ACPI_STRNCMP (table_ptr->signature,
+				 acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
+				 acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
+			table_ptr->signature));
+		status = AE_BAD_SIGNATURE;
+		goto cleanup;
+	}
+
+	/* Install the new table into the local data structures */
+
+	status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Store the ddb_handle into the Target operand */
+
+	status = acpi_ex_store (ddb_handle, target, walk_state);
+	if (ACPI_FAILURE (status)) {
+		(void) acpi_ex_unload_table (ddb_handle);
+	}
+
+	return_ACPI_STATUS (status);
+
+
+cleanup:
+
+	if (buffer_desc) {
+		acpi_ut_remove_reference (buffer_desc);
+	}
+	else {
+		ACPI_MEM_FREE (table_ptr);
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_unload_table
+ *
+ * PARAMETERS:  ddb_handle          - Handle to a previously loaded table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Unload an ACPI table
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_unload_table (
+	union acpi_operand_object       *ddb_handle)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *table_desc = ddb_handle;
+	struct acpi_table_desc          *table_info;
+
+
+	ACPI_FUNCTION_TRACE ("ex_unload_table");
+
+
+	/*
+	 * Validate the handle
+	 * Although the handle is partially validated in acpi_ex_reconfiguration(),
+	 * when it calls acpi_ex_resolve_operands(), the handle is more completely
+	 * validated here.
+	 */
+	if ((!ddb_handle) ||
+		(ACPI_GET_DESCRIPTOR_TYPE (ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
+		(ACPI_GET_OBJECT_TYPE (ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Get the actual table descriptor from the ddb_handle */
+
+	table_info = (struct acpi_table_desc *) table_desc->reference.object;
+
+	/*
+	 * Delete the entire namespace under this table Node
+	 * (Offset contains the table_id)
+	 */
+	acpi_ns_delete_namespace_by_owner (table_info->table_id);
+
+	/* Delete the table itself */
+
+	(void) acpi_tb_uninstall_table (table_info->installed_desc);
+
+	/* Delete the table descriptor (ddb_handle) */
+
+	acpi_ut_remove_reference (table_desc);
+	return_ACPI_STATUS (status);
+}
+
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
new file mode 100644
index 0000000..df7ba12
--- /dev/null
+++ b/drivers/acpi/executer/exconvrt.c
@@ -0,0 +1,708 @@
+/******************************************************************************
+ *
+ * Module Name: exconvrt - Object conversion routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exconvrt")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_convert_to_integer
+ *
+ * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ *                                Integer, Buffer, or String
+ *              result_desc     - Where the new Integer object is returned
+ *              Flags           - Used for string conversion
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to an integer.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_convert_to_integer (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc,
+	u32                             flags)
+{
+	union acpi_operand_object       *return_desc;
+	u8                              *pointer;
+	acpi_integer                    result;
+	u32                             i;
+	u32                             count;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_integer", obj_desc);
+
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_INTEGER:
+
+		/* No conversion necessary */
+
+		*result_desc = obj_desc;
+		return_ACPI_STATUS (AE_OK);
+
+	case ACPI_TYPE_BUFFER:
+	case ACPI_TYPE_STRING:
+
+		/* Note: Takes advantage of common buffer/string fields */
+
+		pointer = obj_desc->buffer.pointer;
+		count   = obj_desc->buffer.length;
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+	/*
+	 * Convert the buffer/string to an integer.  Note that both buffers and
+	 * strings are treated as raw data - we don't convert ascii to hex for
+	 * strings.
+	 *
+	 * There are two terminating conditions for the loop:
+	 * 1) The size of an integer has been reached, or
+	 * 2) The end of the buffer or string has been reached
+	 */
+	result = 0;
+
+	/*
+	 * String conversion is different than Buffer conversion
+	 */
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_STRING:
+
+		/*
+		 * Convert string to an integer - for most cases, the string must be
+		 * hexadecimal as per the ACPI specification.  The only exception (as
+		 * of ACPI 3.0) is that the to_integer() operator allows both decimal
+		 * and hexadecimal strings (hex prefixed with "0x").
+		 */
+		status = acpi_ut_strtoul64 ((char *) pointer, flags, &result);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		/* Check for zero-length buffer */
+
+		if (!count) {
+			return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+		}
+
+		/* Transfer no more than an integer's worth of data */
+
+		if (count > acpi_gbl_integer_byte_width) {
+			count = acpi_gbl_integer_byte_width;
+		}
+
+		/*
+		 * Convert buffer to an integer - we simply grab enough raw data
+		 * from the buffer to fill an integer
+		 */
+		for (i = 0; i < count; i++) {
+			/*
+			 * Get next byte and shift it into the Result.
+			 * Little endian is used, meaning that the first byte of the buffer
+			 * is the LSB of the integer
+			 */
+			result |= (((acpi_integer) pointer[i]) << (i * 8));
+		}
+		break;
+
+
+	default:
+		/* No other types can get here */
+		break;
+	}
+
+	/*
+	 * Create a new integer
+	 */
+	return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!return_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Save the Result */
+
+	return_desc->integer.value = result;
+	acpi_ex_truncate_for32bit_table (return_desc);
+	*result_desc = return_desc;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_convert_to_buffer
+ *
+ * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ *                                Integer, Buffer, or String
+ *              result_desc     - Where the new buffer object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to a Buffer
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_convert_to_buffer (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc)
+{
+	union acpi_operand_object       *return_desc;
+	u8                              *new_buf;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_buffer", obj_desc);
+
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_BUFFER:
+
+		/* No conversion necessary */
+
+		*result_desc = obj_desc;
+		return_ACPI_STATUS (AE_OK);
+
+
+	case ACPI_TYPE_INTEGER:
+
+		/*
+		 * Create a new Buffer object.
+		 * Need enough space for one integer
+		 */
+		return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
+		if (!return_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Copy the integer to the buffer, LSB first */
+
+		new_buf = return_desc->buffer.pointer;
+		ACPI_MEMCPY (new_buf,
+				  &obj_desc->integer.value,
+				  acpi_gbl_integer_byte_width);
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		/*
+		 * Create a new Buffer object
+		 * Size will be the string length
+		 *
+		 * NOTE: Add one to the string length to include the null terminator.
+		 * The ACPI spec is unclear on this subject, but there is existing
+		 * ASL/AML code that depends on the null being transferred to the new
+		 * buffer.
+		 */
+		return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length + 1);
+		if (!return_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Copy the string to the buffer */
+
+		new_buf = return_desc->buffer.pointer;
+		ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer,
+			obj_desc->string.length);
+		break;
+
+
+	default:
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+	/* Mark buffer initialized */
+
+	return_desc->common.flags |= AOPOBJ_DATA_VALID;
+	*result_desc = return_desc;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_convert_to_ascii
+ *
+ * PARAMETERS:  Integer         - Value to be converted
+ *              Base            - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
+ *              String          - Where the string is returned
+ *              data_width      - Size of data item to be converted, in bytes
+ *
+ * RETURN:      Actual string length
+ *
+ * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
+ *
+ ******************************************************************************/
+
+u32
+acpi_ex_convert_to_ascii (
+	acpi_integer                    integer,
+	u16                             base,
+	u8                              *string,
+	u8                              data_width)
+{
+	acpi_integer                    digit;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
+	acpi_native_uint                k = 0;
+	acpi_native_uint                hex_length;
+	acpi_native_uint                decimal_length;
+	u32                             remainder;
+	u8                              supress_zeros;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	switch (base) {
+	case 10:
+
+		/* Setup max length for the decimal number */
+
+		switch (data_width) {
+		case 1:
+			decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
+			break;
+
+		case 4:
+			decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
+			break;
+
+		case 8:
+		default:
+			decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
+			break;
+		}
+
+		supress_zeros = TRUE;    /* No leading zeros */
+		remainder = 0;
+
+		for (i = decimal_length; i > 0; i--) {
+			/* Divide by nth factor of 10 */
+
+			digit = integer;
+			for (j = 0; j < i; j++) {
+				(void) acpi_ut_short_divide (digit, 10, &digit, &remainder);
+			}
+
+			/* Handle leading zeros */
+
+			if (remainder != 0) {
+				supress_zeros = FALSE;
+			}
+
+			if (!supress_zeros) {
+				string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
+				k++;
+			}
+		}
+		break;
+
+	case 16:
+
+		hex_length = ACPI_MUL_2 (data_width); /* 2 ascii hex chars per data byte */
+
+		for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) {
+			/* Get one hex digit, most significant digits first */
+
+			string[k] = (u8) acpi_ut_hex_to_ascii_char (integer, ACPI_MUL_4 (j));
+			k++;
+		}
+		break;
+
+	default:
+		return (0);
+	}
+
+	/*
+	 * Since leading zeros are supressed, we must check for the case where
+	 * the integer equals 0
+	 *
+	 * Finally, null terminate the string and return the length
+	 */
+	if (!k) {
+		string [0] = ACPI_ASCII_ZERO;
+		k = 1;
+	}
+
+	string [k] = 0;
+	return ((u32) k);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_convert_to_string
+ *
+ * PARAMETERS:  obj_desc        - Object to be converted.  Must be an
+ *                                Integer, Buffer, or String
+ *              result_desc     - Where the string object is returned
+ *              Type            - String flags (base and conversion type)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an ACPI Object to a string
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_convert_to_string (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc,
+	u32                             type)
+{
+	union acpi_operand_object       *return_desc;
+	u8                              *new_buf;
+	u32                             i;
+	u32                             string_length = 0;
+	u16                             base = 16;
+	u8                              separator = ',';
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
+
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_STRING:
+
+		/* No conversion necessary */
+
+		*result_desc = obj_desc;
+		return_ACPI_STATUS (AE_OK);
+
+
+	case ACPI_TYPE_INTEGER:
+
+		switch (type) {
+		case ACPI_EXPLICIT_CONVERT_DECIMAL:
+
+			/* Make room for maximum decimal number */
+
+			string_length = ACPI_MAX_DECIMAL_DIGITS;
+			base = 10;
+			break;
+
+		default:
+
+			/* Two hex string characters for each integer byte */
+
+			string_length = ACPI_MUL_2 (acpi_gbl_integer_byte_width);
+			break;
+		}
+
+		/*
+		 * Create a new String
+		 * Need enough space for one ASCII integer (plus null terminator)
+		 */
+		return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
+		if (!return_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		new_buf = return_desc->buffer.pointer;
+
+		/* Convert integer to string */
+
+		string_length = acpi_ex_convert_to_ascii (obj_desc->integer.value, base,
+				   new_buf, acpi_gbl_integer_byte_width);
+
+		/* Null terminate at the correct place */
+
+		return_desc->string.length = string_length;
+		new_buf [string_length] = 0;
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		/* Setup string length, base, and separator */
+
+		switch (type) {
+		case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
+			/*
+			 * From ACPI: "If Data is a buffer, it is converted to a string of
+			 * decimal values separated by commas."
+			 */
+			base = 10;
+
+			/*
+			 * Calculate the final string length.  Individual string values
+			 * are variable length (include separator for each)
+			 */
+			for (i = 0; i < obj_desc->buffer.length; i++) {
+				if (obj_desc->buffer.pointer[i] >= 100) {
+					string_length += 4;
+				}
+				else if (obj_desc->buffer.pointer[i] >= 10) {
+					string_length += 3;
+				}
+				else {
+					string_length += 2;
+				}
+			}
+			break;
+
+		case ACPI_IMPLICIT_CONVERT_HEX:
+			/*
+			 * From the ACPI spec:
+			 *"The entire contents of the buffer are converted to a string of
+			 * two-character hexadecimal numbers, each separated by a space."
+			 */
+			separator = ' ';
+			string_length = (obj_desc->buffer.length * 3);
+			break;
+
+		case ACPI_EXPLICIT_CONVERT_HEX:     /* Used by to_hex_string operator */
+			/*
+			 * From ACPI: "If Data is a buffer, it is converted to a string of
+			 * hexadecimal values separated by commas."
+			 */
+			string_length = (obj_desc->buffer.length * 3);
+			break;
+
+		default:
+			return_ACPI_STATUS (AE_BAD_PARAMETER);
+		}
+
+		/*
+		 * Perform the conversion.
+		 * (-1 because of extra separator included in string_length from above)
+		 */
+		string_length--;
+		if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
+			return_ACPI_STATUS (AE_AML_STRING_LIMIT);
+		}
+
+		/*
+		 * Create a new string object and string buffer
+		 */
+		return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
+		if (!return_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		new_buf = return_desc->buffer.pointer;
+
+		/*
+		 * Convert buffer bytes to hex or decimal values
+		 * (separated by commas or spaces)
+		 */
+		for (i = 0; i < obj_desc->buffer.length; i++) {
+			new_buf += acpi_ex_convert_to_ascii (
+					 (acpi_integer) obj_desc->buffer.pointer[i], base,
+					 new_buf, 1);
+			*new_buf++ = separator; /* each separated by a comma or space */
+		}
+
+		/* Null terminate the string (overwrites final comma/space from above) */
+
+		new_buf--;
+		*new_buf = 0;
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+	*result_desc = return_desc;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_convert_to_target_type
+ *
+ * PARAMETERS:  destination_type    - Current type of the destination
+ *              source_desc         - Source object to be converted.
+ *              result_desc         - Where the converted object is returned
+ *              walk_state          - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_convert_to_target_type (
+	acpi_object_type                destination_type,
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       **result_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_convert_to_target_type");
+
+
+	/* Default behavior */
+
+	*result_desc = source_desc;
+
+	/*
+	 * If required by the target,
+	 * perform implicit conversion on the source before we store it.
+	 */
+	switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
+	case ARGI_SIMPLE_TARGET:
+	case ARGI_FIXED_TARGET:
+	case ARGI_INTEGER_REF:      /* Handles Increment, Decrement cases */
+
+		switch (destination_type) {
+		case ACPI_TYPE_LOCAL_REGION_FIELD:
+			/*
+			 * Named field can always handle conversions
+			 */
+			break;
+
+		default:
+			/* No conversion allowed for these types */
+
+			if (destination_type != ACPI_GET_OBJECT_TYPE (source_desc)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+					"Explicit operator, will store (%s) over existing type (%s)\n",
+					acpi_ut_get_object_type_name (source_desc),
+					acpi_ut_get_type_name (destination_type)));
+				status = AE_TYPE;
+			}
+		}
+		break;
+
+
+	case ARGI_TARGETREF:
+
+		switch (destination_type) {
+		case ACPI_TYPE_INTEGER:
+		case ACPI_TYPE_BUFFER_FIELD:
+		case ACPI_TYPE_LOCAL_BANK_FIELD:
+		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+			/*
+			 * These types require an Integer operand.  We can convert
+			 * a Buffer or a String to an Integer if necessary.
+			 */
+			status = acpi_ex_convert_to_integer (source_desc, result_desc,
+					 16);
+			break;
+
+
+		case ACPI_TYPE_STRING:
+
+			/*
+			 * The operand must be a String.  We can convert an
+			 * Integer or Buffer if necessary
+			 */
+			status = acpi_ex_convert_to_string (source_desc, result_desc,
+					 ACPI_IMPLICIT_CONVERT_HEX);
+			break;
+
+
+		case ACPI_TYPE_BUFFER:
+
+			/*
+			 * The operand must be a Buffer.  We can convert an
+			 * Integer or String if necessary
+			 */
+			status = acpi_ex_convert_to_buffer (source_desc, result_desc);
+			break;
+
+
+		default:
+			ACPI_REPORT_ERROR (("Bad destination type during conversion: %X\n",
+				destination_type));
+			status = AE_AML_INTERNAL;
+			break;
+		}
+		break;
+
+
+	case ARGI_REFERENCE:
+		/*
+		 * create_xxxx_field cases - we are storing the field object into the name
+		 */
+		break;
+
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown Target type ID 0x%X Op %s dest_type %s\n",
+			GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args),
+			walk_state->op_info->name, acpi_ut_get_type_name (destination_type)));
+
+		ACPI_REPORT_ERROR (("Bad Target Type (ARGI): %X\n",
+			GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)))
+		status = AE_AML_INTERNAL;
+	}
+
+	/*
+	 * Source-to-Target conversion semantics:
+	 *
+	 * If conversion to the target type cannot be performed, then simply
+	 * overwrite the target with the new object and type.
+	 */
+	if (status == AE_TYPE) {
+		status = AE_OK;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
new file mode 100644
index 0000000..d94c260
--- /dev/null
+++ b/drivers/acpi/executer/excreate.c
@@ -0,0 +1,646 @@
+/******************************************************************************
+ *
+ * Module Name: excreate - Named object creation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("excreate")
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_alias
+ *
+ * PARAMETERS:  walk_state           - Current state, contains operands
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new named alias
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_alias (
+	struct acpi_walk_state          *walk_state)
+{
+	struct acpi_namespace_node      *target_node;
+	struct acpi_namespace_node      *alias_node;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_create_alias");
+
+
+	/* Get the source/alias operands (both namespace nodes) */
+
+	alias_node = (struct acpi_namespace_node *) walk_state->operands[0];
+	target_node = (struct acpi_namespace_node *) walk_state->operands[1];
+
+	if ((target_node->type == ACPI_TYPE_LOCAL_ALIAS) ||
+		(target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
+		/*
+		 * Dereference an existing alias so that we don't create a chain
+		 * of aliases.  With this code, we guarantee that an alias is
+		 * always exactly one level of indirection away from the
+		 * actual aliased name.
+		 */
+		target_node = ACPI_CAST_PTR (struct acpi_namespace_node, target_node->object);
+	}
+
+	/*
+	 * For objects that can never change (i.e., the NS node will
+	 * permanently point to the same object), we can simply attach
+	 * the object to the new NS node.  For other objects (such as
+	 * Integers, buffers, etc.), we have to point the Alias node
+	 * to the original Node.
+	 */
+	switch (target_node->type) {
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
+	case ACPI_TYPE_PACKAGE:
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		/*
+		 * The new alias has the type ALIAS and points to the original
+		 * NS node, not the object itself.  This is because for these
+		 * types, the object can change dynamically via a Store.
+		 */
+		alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
+		alias_node->object = ACPI_CAST_PTR (union acpi_operand_object, target_node);
+		break;
+
+	case ACPI_TYPE_METHOD:
+
+		/*
+		 * The new alias has the type ALIAS and points to the original
+		 * NS node, not the object itself.  This is because for these
+		 * types, the object can change dynamically via a Store.
+		 */
+		alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
+		alias_node->object = ACPI_CAST_PTR (union acpi_operand_object, target_node);
+		break;
+
+	default:
+
+		/* Attach the original source object to the new Alias Node */
+
+		/*
+		 * The new alias assumes the type of the target, and it points
+		 * to the same object.  The reference count of the object has an
+		 * additional reference to prevent deletion out from under either the
+		 * target node or the alias Node
+		 */
+		status = acpi_ns_attach_object (alias_node,
+				 acpi_ns_get_attached_object (target_node),
+				 target_node->type);
+		break;
+	}
+
+	/* Since both operands are Nodes, we don't need to delete them */
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_event
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new event object
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_event (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE ("ex_create_event");
+
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_EVENT);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Create the actual OS semaphore, with zero initial units -- meaning
+	 * that the event is created in an unsignalled state
+	 */
+	status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0,
+			   &obj_desc->event.semaphore);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Attach object to the Node */
+
+	status = acpi_ns_attach_object ((struct acpi_namespace_node *) walk_state->operands[0],
+			   obj_desc, ACPI_TYPE_EVENT);
+
+cleanup:
+	/*
+	 * Remove local reference to the object (on error, will cause deletion
+	 * of both object and semaphore if present.)
+	 */
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_mutex
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new mutex object
+ *
+ *              Mutex (Name[0], sync_level[1])
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_mutex (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_create_mutex", ACPI_WALK_OPERANDS);
+
+
+	/* Create the new mutex object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_MUTEX);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Create the actual OS semaphore.
+	 * One unit max to make it a mutex, with one initial unit to allow
+	 * the mutex to be acquired.
+	 */
+	status = acpi_os_create_semaphore (1, 1, &obj_desc->mutex.semaphore);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Init object and attach to NS node */
+
+	obj_desc->mutex.sync_level = (u8) walk_state->operands[1]->integer.value;
+	obj_desc->mutex.node = (struct acpi_namespace_node *) walk_state->operands[0];
+
+	status = acpi_ns_attach_object (obj_desc->mutex.node,
+			 obj_desc, ACPI_TYPE_MUTEX);
+
+
+cleanup:
+	/*
+	 * Remove local reference to the object (on error, will cause deletion
+	 * of both object and semaphore if present.)
+	 */
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_region
+ *
+ * PARAMETERS:  aml_start           - Pointer to the region declaration AML
+ *              aml_length          - Max length of the declaration AML
+ *              Operands            - List of operands for the opcode
+ *              walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new operation region object
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_region (
+	u8                              *aml_start,
+	u32                             aml_length,
+	u8                              region_space,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	union acpi_operand_object       *region_obj2;
+
+
+	ACPI_FUNCTION_TRACE ("ex_create_region");
+
+
+	/* Get the Namespace Node */
+
+	node = walk_state->op->common.node;
+
+	/*
+	 * If the region object is already attached to this node,
+	 * just return
+	 */
+	if (acpi_ns_get_attached_object (node)) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * Space ID must be one of the predefined IDs, or in the user-defined
+	 * range
+	 */
+	if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
+		(region_space < ACPI_USER_REGION_BEGIN)) {
+		ACPI_REPORT_ERROR (("Invalid address_space type %X\n", region_space));
+		return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
+			  acpi_ut_get_region_name (region_space), region_space));
+
+	/* Create the region descriptor */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
+	if (!obj_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Remember location in AML stream of address & length
+	 * operands since they need to be evaluated at run time.
+	 */
+	region_obj2                 = obj_desc->common.next_object;
+	region_obj2->extra.aml_start = aml_start;
+	region_obj2->extra.aml_length = aml_length;
+
+	/* Init the region from the operands */
+
+	obj_desc->region.space_id = region_space;
+	obj_desc->region.address = 0;
+	obj_desc->region.length = 0;
+	obj_desc->region.node   = node;
+
+	/* Install the new region object in the parent Node */
+
+	status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION);
+
+
+cleanup:
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_table_region
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new data_table_region object
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_table_region (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	struct acpi_table_header        *table;
+	union acpi_operand_object       *region_obj2;
+
+
+	ACPI_FUNCTION_TRACE ("ex_create_table_region");
+
+
+	/* Get the Node from the object stack  */
+
+	node = walk_state->op->common.node;
+
+	/*
+	 * If the region object is already attached to this node,
+	 * just return
+	 */
+	if (acpi_ns_get_attached_object (node)) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Find the ACPI table */
+
+	status = acpi_tb_find_table (operand[1]->string.pointer,
+			   operand[2]->string.pointer,
+			   operand[3]->string.pointer, &table);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Create the region descriptor */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_REGION);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	region_obj2                     = obj_desc->common.next_object;
+	region_obj2->extra.region_context = NULL;
+
+	/* Init the region from the operands */
+
+	obj_desc->region.space_id = REGION_DATA_TABLE;
+	obj_desc->region.address = (acpi_physical_address) ACPI_TO_INTEGER (table);
+	obj_desc->region.length = table->length;
+	obj_desc->region.node   = node;
+	obj_desc->region.flags  = AOPOBJ_DATA_VALID;
+
+	/* Install the new region object in the parent Node */
+
+	status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_REGION);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	status = acpi_ev_initialize_region (obj_desc, FALSE);
+	if (ACPI_FAILURE (status)) {
+		if (status == AE_NOT_EXIST) {
+			status = AE_OK;
+		}
+		else {
+			goto cleanup;
+		}
+	}
+
+	obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE;
+
+
+cleanup:
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_processor
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new processor object and populate the fields
+ *
+ *              Processor (Name[0], cpu_iD[1], pblock_addr[2], pblock_length[3])
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_processor (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_create_processor", walk_state);
+
+
+	/* Create the processor object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PROCESSOR);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * Initialize the processor object from the operands
+	 */
+	obj_desc->processor.proc_id = (u8)          operand[1]->integer.value;
+	obj_desc->processor.address = (acpi_io_address) operand[2]->integer.value;
+	obj_desc->processor.length = (u8)           operand[3]->integer.value;
+
+	/* Install the processor object in the parent Node */
+
+	status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
+			  obj_desc, ACPI_TYPE_PROCESSOR);
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_power_resource
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new power_resource object and populate the fields
+ *
+ *              power_resource (Name[0], system_level[1], resource_order[2])
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_power_resource (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_create_power_resource", walk_state);
+
+
+	/* Create the power resource object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_POWER);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Initialize the power object from the operands */
+
+	obj_desc->power_resource.system_level = (u8) operand[1]->integer.value;
+	obj_desc->power_resource.resource_order = (u16) operand[2]->integer.value;
+
+	/* Install the  power resource object in the parent Node */
+
+	status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
+			  obj_desc, ACPI_TYPE_POWER);
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+#endif
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_create_method
+ *
+ * PARAMETERS:  aml_start       - First byte of the method's AML
+ *              aml_length      - AML byte count for this method
+ *              walk_state      - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a new method object
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_ex_create_method (
+	u8                              *aml_start,
+	u32                             aml_length,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+	u8                              method_flags;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_create_method", walk_state);
+
+
+	/* Create a new method object */
+
+	obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_METHOD);
+	if (!obj_desc) {
+	   return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Save the method's AML pointer and length  */
+
+	obj_desc->method.aml_start = aml_start;
+	obj_desc->method.aml_length = aml_length;
+
+	/*
+	 * Disassemble the method flags.  Split off the Arg Count
+	 * for efficiency
+	 */
+	method_flags = (u8) operand[1]->integer.value;
+
+	obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
+	obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT);
+
+	/*
+	 * Get the concurrency count.  If required, a semaphore will be
+	 * created for this method when it is parsed.
+	 */
+	if (acpi_gbl_all_methods_serialized) {
+		obj_desc->method.concurrency = 1;
+		obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
+	}
+	else if (method_flags & AML_METHOD_SERIALIZED) {
+		/*
+		 * ACPI 1.0: Concurrency = 1
+		 * ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1)
+		 */
+		obj_desc->method.concurrency = (u8)
+				  (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1);
+	}
+	else {
+		obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY;
+	}
+
+	/* Attach the new object to the method Node */
+
+	status = acpi_ns_attach_object ((struct acpi_namespace_node *) operand[0],
+			  obj_desc, ACPI_TYPE_METHOD);
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+
+	/* Remove a reference to the operand */
+
+	acpi_ut_remove_reference (operand[1]);
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
new file mode 100644
index 0000000..e2f7c32
--- /dev/null
+++ b/drivers/acpi/executer/exdump.c
@@ -0,0 +1,793 @@
+/******************************************************************************
+ *
+ * Module Name: exdump - Interpreter debug output routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exdump")
+
+
+/*
+ * The following routines are used for debug output only
+ */
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_dump_operand
+ *
+ * PARAMETERS:  *obj_desc         - Pointer to entry to be dumped
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump an operand object
+ *
+ ****************************************************************************/
+
+void
+acpi_ex_dump_operand (
+	union acpi_operand_object       *obj_desc,
+	u32                             depth)
+{
+	u32                             length;
+	u32                             index;
+
+
+	ACPI_FUNCTION_NAME ("ex_dump_operand")
+
+
+	if (!((ACPI_LV_EXEC & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
+		return;
+	}
+
+	if (!obj_desc) {
+		/*
+		 * This could be a null element of a package
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
+		return;
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is a NS Node: ", obj_desc));
+		ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC);
+		return;
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"%p is not a node or operand object: [%s]\n",
+			obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
+		ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object));
+		return;
+	}
+
+	/* obj_desc is a valid object */
+
+	if (depth > 0) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%*s[%u] %p ",
+			depth, " ", depth, obj_desc));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
+	}
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		switch (obj_desc->reference.opcode) {
+		case AML_DEBUG_OP:
+
+			acpi_os_printf ("Reference: Debug\n");
+			break;
+
+
+		case AML_NAME_OP:
+
+			ACPI_DUMP_PATHNAME (obj_desc->reference.object,
+				"Reference: Name: ", ACPI_LV_INFO, _COMPONENT);
+			ACPI_DUMP_ENTRY (obj_desc->reference.object, ACPI_LV_INFO);
+			break;
+
+
+		case AML_INDEX_OP:
+
+			acpi_os_printf ("Reference: Index %p\n",
+				obj_desc->reference.object);
+			break;
+
+
+		case AML_REF_OF_OP:
+
+			acpi_os_printf ("Reference: (ref_of) %p\n",
+				obj_desc->reference.object);
+			break;
+
+
+		case AML_ARG_OP:
+
+			acpi_os_printf ("Reference: Arg%d",
+				obj_desc->reference.offset);
+
+			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 AML_LOCAL_OP:
+
+			acpi_os_printf ("Reference: Local%d",
+				obj_desc->reference.offset);
+
+			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 AML_INT_NAMEPATH_OP:
+
+			acpi_os_printf ("Reference.Node->Name %X\n",
+				obj_desc->reference.node->name.integer);
+			break;
+
+
+		default:
+
+			/* Unknown opcode */
+
+			acpi_os_printf ("Unknown Reference opcode=%X\n",
+				obj_desc->reference.opcode);
+			break;
+
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		acpi_os_printf ("Buffer len %X @ %p \n",
+			obj_desc->buffer.length, obj_desc->buffer.pointer);
+
+		length = obj_desc->buffer.length;
+		if (length > 64) {
+			length = 64;
+		}
+
+		/* Debug only -- dump the buffer contents */
+
+		if (obj_desc->buffer.pointer) {
+			acpi_os_printf ("Buffer Contents: ");
+
+			for (index = 0; index < length; index++) {
+				acpi_os_printf (" %02x", obj_desc->buffer.pointer[index]);
+			}
+			acpi_os_printf ("\n");
+		}
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		acpi_os_printf ("Integer %8.8X%8.8X\n",
+			ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		acpi_os_printf ("Package [Len %X] element_array %p\n",
+			obj_desc->package.count, obj_desc->package.elements);
+
+		/*
+		 * If elements exist, package element pointer is valid,
+		 * and debug_level exceeds 1, dump package's elements.
+		 */
+		if (obj_desc->package.count &&
+			obj_desc->package.elements &&
+			acpi_dbg_level > 1) {
+			for (index = 0; index < obj_desc->package.count; index++) {
+				acpi_ex_dump_operand (obj_desc->package.elements[index], depth+1);
+			}
+		}
+		break;
+
+
+	case ACPI_TYPE_REGION:
+
+		acpi_os_printf ("Region %s (%X)",
+			acpi_ut_get_region_name (obj_desc->region.space_id),
+			obj_desc->region.space_id);
+
+		/*
+		 * If the address and length have not been evaluated,
+		 * don't print them.
+		 */
+		if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) {
+			acpi_os_printf ("\n");
+		}
+		else {
+			acpi_os_printf (" base %8.8X%8.8X Length %X\n",
+				ACPI_FORMAT_UINT64 (obj_desc->region.address),
+				obj_desc->region.length);
+		}
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		acpi_os_printf ("String length %X @ %p ",
+			obj_desc->string.length, obj_desc->string.pointer);
+		acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
+		acpi_os_printf ("\n");
+		break;
+
+
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+		acpi_os_printf ("bank_field\n");
+		break;
+
+
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+		acpi_os_printf (
+			"region_field: Bits=%X acc_width=%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,
+			obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset);
+		acpi_ex_dump_operand (obj_desc->field.region_obj, depth+1);
+		break;
+
+
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		acpi_os_printf ("index_field\n");
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		acpi_os_printf (
+			"buffer_field: %X bits at byte %X bit %X of \n",
+			obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset,
+			obj_desc->buffer_field.start_field_bit_offset);
+
+		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) {
+			acpi_os_printf ("*not a Buffer* \n");
+		}
+		else {
+			acpi_ex_dump_operand (obj_desc->buffer_field.buffer_obj, depth+1);
+		}
+		break;
+
+
+	case ACPI_TYPE_EVENT:
+
+		acpi_os_printf ("Event\n");
+		break;
+
+
+	case ACPI_TYPE_METHOD:
+
+		acpi_os_printf (
+			"Method(%X) @ %p:%X\n",
+			obj_desc->method.param_count,
+			obj_desc->method.aml_start, obj_desc->method.aml_length);
+		break;
+
+
+	case ACPI_TYPE_MUTEX:
+
+		acpi_os_printf ("Mutex\n");
+		break;
+
+
+	case ACPI_TYPE_DEVICE:
+
+		acpi_os_printf ("Device\n");
+		break;
+
+
+	case ACPI_TYPE_POWER:
+
+		acpi_os_printf ("Power\n");
+		break;
+
+
+	case ACPI_TYPE_PROCESSOR:
+
+		acpi_os_printf ("Processor\n");
+		break;
+
+
+	case ACPI_TYPE_THERMAL:
+
+		acpi_os_printf ("Thermal\n");
+		break;
+
+
+	default:
+		/* Unknown Type */
+
+		acpi_os_printf ("Unknown Type %X\n", ACPI_GET_OBJECT_TYPE (obj_desc));
+		break;
+	}
+
+	return;
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_dump_operands
+ *
+ * PARAMETERS:  Operands            - Operand list
+ *              interpreter_mode    - Load or Exec
+ *              Ident               - Identification
+ *              num_levels          - # of stack entries to dump above line
+ *              Note                - Output notation
+ *              module_name         - Caller's module name
+ *              line_number         - Caller's invocation line number
+ *
+ * DESCRIPTION: Dump the object stack
+ *
+ ****************************************************************************/
+
+void
+acpi_ex_dump_operands (
+	union acpi_operand_object       **operands,
+	acpi_interpreter_mode           interpreter_mode,
+	char                            *ident,
+	u32                             num_levels,
+	char                            *note,
+	char                            *module_name,
+	u32                             line_number)
+{
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_NAME ("ex_dump_operands");
+
+
+	if (!ident) {
+		ident = "?";
+	}
+
+	if (!note) {
+		note = "?";
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"************* Operand Stack Contents (Opcode [%s], %d Operands)\n",
+		ident, num_levels));
+
+	if (num_levels == 0) {
+		num_levels = 1;
+	}
+
+	/* Dump the operand stack starting at the top */
+
+	for (i = 0; num_levels > 0; i--, num_levels--) {
+		acpi_ex_dump_operand (operands[i], 0);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"************* Stack dump from %s(%d), %s\n",
+		module_name, line_number, note));
+	return;
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_out*
+ *
+ * PARAMETERS:  Title               - Descriptive text
+ *              Value               - Value to be displayed
+ *
+ * DESCRIPTION: Object dump output formatting functions.  These functions
+ *              reduce the number of format strings required and keeps them
+ *              all in one place for easy modification.
+ *
+ ****************************************************************************/
+
+void
+acpi_ex_out_string (
+	char                            *title,
+	char                            *value)
+{
+	acpi_os_printf ("%20s : %s\n", title, value);
+}
+
+void
+acpi_ex_out_pointer (
+	char                            *title,
+	void                            *value)
+{
+	acpi_os_printf ("%20s : %p\n", title, value);
+}
+
+void
+acpi_ex_out_integer (
+	char                            *title,
+	u32                             value)
+{
+	acpi_os_printf ("%20s : %X\n", title, value);
+}
+
+void
+acpi_ex_out_address (
+	char                            *title,
+	acpi_physical_address           value)
+{
+
+#if ACPI_MACHINE_WIDTH == 16
+	acpi_os_printf ("%20s : %p\n", title, value);
+#else
+	acpi_os_printf ("%20s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64 (value));
+#endif
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_dump_node
+ *
+ * PARAMETERS:  *Node               - Descriptor to dump
+ *              Flags               - Force display
+ *
+ * DESCRIPTION: Dumps the members of the given.Node
+ *
+ ****************************************************************************/
+
+void
+acpi_ex_dump_node (
+	struct acpi_namespace_node      *node,
+	u32                             flags)
+{
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (!flags) {
+		if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
+			return;
+		}
+	}
+
+	acpi_os_printf ("%20s : %4.4s\n",     "Name", acpi_ut_get_node_name (node));
+	acpi_ex_out_string ("Type",           acpi_ut_get_type_name (node->type));
+	acpi_ex_out_integer ("Flags",         node->flags);
+	acpi_ex_out_integer ("Owner Id",      node->owner_id);
+	acpi_ex_out_integer ("Reference Count", node->reference_count);
+	acpi_ex_out_pointer ("Attached Object", acpi_ns_get_attached_object (node));
+	acpi_ex_out_pointer ("child_list",    node->child);
+	acpi_ex_out_pointer ("next_peer",     node->peer);
+	acpi_ex_out_pointer ("Parent",        acpi_ns_get_parent_node (node));
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ex_dump_object_descriptor
+ *
+ * PARAMETERS:  *Object             - Descriptor to dump
+ *              Flags               - Force display
+ *
+ * DESCRIPTION: Dumps the members of the object descriptor given.
+ *
+ ****************************************************************************/
+
+void
+acpi_ex_dump_object_descriptor (
+	union acpi_operand_object       *obj_desc,
+	u32                             flags)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor");
+
+
+	if (!flags) {
+		if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
+			return_VOID;
+		}
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
+		acpi_ex_dump_node ((struct acpi_namespace_node *) obj_desc, flags);
+		acpi_os_printf ("\nAttached Object (%p):\n",
+			((struct acpi_namespace_node *) obj_desc)->object);
+		acpi_ex_dump_object_descriptor (
+			((struct acpi_namespace_node *) obj_desc)->object, flags);
+		return_VOID;
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+		acpi_os_printf (
+			"ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n",
+			obj_desc, acpi_ut_get_descriptor_name (obj_desc));
+		return_VOID;
+	}
+
+	/* Common Fields */
+
+	acpi_ex_out_string ("Type",             acpi_ut_get_object_type_name (obj_desc));
+	acpi_ex_out_integer ("Reference Count", obj_desc->common.reference_count);
+	acpi_ex_out_integer ("Flags",           obj_desc->common.flags);
+
+	/* Object-specific Fields */
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_INTEGER:
+
+		acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value",
+				ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		acpi_ex_out_integer ("Length",      obj_desc->string.length);
+
+		acpi_os_printf ("%20s : %p ", "Pointer", obj_desc->string.pointer);
+		acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
+		acpi_os_printf ("\n");
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		acpi_ex_out_integer ("Length",      obj_desc->buffer.length);
+		acpi_ex_out_pointer ("Pointer",     obj_desc->buffer.pointer);
+		ACPI_DUMP_BUFFER (obj_desc->buffer.pointer, obj_desc->buffer.length);
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		acpi_ex_out_integer ("Flags",       obj_desc->package.flags);
+		acpi_ex_out_integer ("Count",       obj_desc->package.count);
+		acpi_ex_out_pointer ("Elements",    obj_desc->package.elements);
+
+		/* Dump the package contents */
+
+		if (obj_desc->package.count > 0) {
+			acpi_os_printf ("\nPackage Contents:\n");
+			for (i = 0; i < obj_desc->package.count; i++) {
+				acpi_os_printf ("[%.3d] %p", i, obj_desc->package.elements[i]);
+				if (obj_desc->package.elements[i]) {
+					acpi_os_printf (" %s",
+						acpi_ut_get_object_type_name (obj_desc->package.elements[i]));
+				}
+				acpi_os_printf ("\n");
+			}
+		}
+		break;
+
+
+	case ACPI_TYPE_DEVICE:
+
+		acpi_ex_out_pointer ("Handler",     obj_desc->device.handler);
+		acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
+		break;
+
+
+	case ACPI_TYPE_EVENT:
+
+		acpi_ex_out_pointer ("Semaphore",   obj_desc->event.semaphore);
+		break;
+
+
+	case ACPI_TYPE_METHOD:
+
+		acpi_ex_out_integer ("param_count", obj_desc->method.param_count);
+		acpi_ex_out_integer ("Concurrency", obj_desc->method.concurrency);
+		acpi_ex_out_pointer ("Semaphore",   obj_desc->method.semaphore);
+		acpi_ex_out_integer ("owning_id",   obj_desc->method.owning_id);
+		acpi_ex_out_integer ("aml_length",  obj_desc->method.aml_length);
+		acpi_ex_out_pointer ("aml_start",   obj_desc->method.aml_start);
+		break;
+
+
+	case ACPI_TYPE_MUTEX:
+
+		acpi_ex_out_integer ("sync_level",  obj_desc->mutex.sync_level);
+		acpi_ex_out_pointer ("owner_thread", obj_desc->mutex.owner_thread);
+		acpi_ex_out_integer ("acquire_depth", obj_desc->mutex.acquisition_depth);
+		acpi_ex_out_pointer ("Semaphore",   obj_desc->mutex.semaphore);
+		break;
+
+
+	case ACPI_TYPE_REGION:
+
+		acpi_ex_out_integer ("space_id",    obj_desc->region.space_id);
+		acpi_ex_out_integer ("Flags",       obj_desc->region.flags);
+		acpi_ex_out_address ("Address",     obj_desc->region.address);
+		acpi_ex_out_integer ("Length",      obj_desc->region.length);
+		acpi_ex_out_pointer ("Handler",     obj_desc->region.handler);
+		acpi_ex_out_pointer ("Next",        obj_desc->region.next);
+		break;
+
+
+	case ACPI_TYPE_POWER:
+
+		acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level);
+		acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order);
+		acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify);
+		break;
+
+
+	case ACPI_TYPE_PROCESSOR:
+
+		acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id);
+		acpi_ex_out_integer ("Length",      obj_desc->processor.length);
+		acpi_ex_out_address ("Address",     (acpi_physical_address) obj_desc->processor.address);
+		acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify);
+		acpi_ex_out_pointer ("Handler",     obj_desc->processor.handler);
+		break;
+
+
+	case ACPI_TYPE_THERMAL:
+
+		acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify);
+		acpi_ex_out_pointer ("Handler",     obj_desc->thermal_zone.handler);
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		acpi_ex_out_integer ("field_flags", obj_desc->common_field.field_flags);
+		acpi_ex_out_integer ("access_byte_width",obj_desc->common_field.access_byte_width);
+		acpi_ex_out_integer ("bit_length",  obj_desc->common_field.bit_length);
+		acpi_ex_out_integer ("fld_bit_offset", obj_desc->common_field.start_field_bit_offset);
+		acpi_ex_out_integer ("base_byte_offset", obj_desc->common_field.base_byte_offset);
+		acpi_ex_out_pointer ("parent_node", obj_desc->common_field.node);
+
+		switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+		case ACPI_TYPE_BUFFER_FIELD:
+			acpi_ex_out_pointer ("buffer_obj", obj_desc->buffer_field.buffer_obj);
+			break;
+
+		case ACPI_TYPE_LOCAL_REGION_FIELD:
+			acpi_ex_out_pointer ("region_obj", obj_desc->field.region_obj);
+			break;
+
+		case ACPI_TYPE_LOCAL_BANK_FIELD:
+			acpi_ex_out_integer ("Value",   obj_desc->bank_field.value);
+			acpi_ex_out_pointer ("region_obj", obj_desc->bank_field.region_obj);
+			acpi_ex_out_pointer ("bank_obj", obj_desc->bank_field.bank_obj);
+			break;
+
+		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+			acpi_ex_out_integer ("Value",   obj_desc->index_field.value);
+			acpi_ex_out_pointer ("Index",   obj_desc->index_field.index_obj);
+			acpi_ex_out_pointer ("Data",    obj_desc->index_field.data_obj);
+			break;
+
+		default:
+			/* All object types covered above */
+			break;
+		}
+		break;
+
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		acpi_ex_out_integer ("target_type", obj_desc->reference.target_type);
+		acpi_ex_out_string ("Opcode",       (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name);
+		acpi_ex_out_integer ("Offset",      obj_desc->reference.offset);
+		acpi_ex_out_pointer ("obj_desc",    obj_desc->reference.object);
+		acpi_ex_out_pointer ("Node",        obj_desc->reference.node);
+		acpi_ex_out_pointer ("Where",       obj_desc->reference.where);
+		break;
+
+
+	case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
+
+		acpi_ex_out_integer ("space_id",    obj_desc->address_space.space_id);
+		acpi_ex_out_pointer ("Next",        obj_desc->address_space.next);
+		acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list);
+		acpi_ex_out_pointer ("Node",        obj_desc->address_space.node);
+		acpi_ex_out_pointer ("Context",     obj_desc->address_space.context);
+		break;
+
+
+	case ACPI_TYPE_LOCAL_NOTIFY:
+
+		acpi_ex_out_pointer ("Node",        obj_desc->notify.node);
+		acpi_ex_out_pointer ("Context",     obj_desc->notify.context);
+		break;
+
+
+	case ACPI_TYPE_LOCAL_ALIAS:
+	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
+	case ACPI_TYPE_LOCAL_EXTRA:
+	case ACPI_TYPE_LOCAL_DATA:
+	default:
+
+		acpi_os_printf (
+			"ex_dump_object_descriptor: Display not implemented for object type %s\n",
+			acpi_ut_get_object_type_name (obj_desc));
+		break;
+	}
+
+	return_VOID;
+}
+
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+#endif
+
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
new file mode 100644
index 0000000..be7f212
--- /dev/null
+++ b/drivers/acpi/executer/exfield.c
@@ -0,0 +1,367 @@
+/******************************************************************************
+ *
+ * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exfield")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_read_data_from_field
+ *
+ * PARAMETERS:  walk_state          - Current execution state
+ *              obj_desc            - The named field
+ *              ret_buffer_desc     - Where the return data object is stored
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read from a named field.  Returns either an Integer or a
+ *              Buffer, depending on the size of the field.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_read_data_from_field (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **ret_buffer_desc)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *buffer_desc;
+	acpi_size                       length;
+	void                            *buffer;
+	u8                              locked;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_read_data_from_field", obj_desc);
+
+
+	/* Parameter validation */
+
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+		/*
+		 * If the buffer_field arguments have not been previously evaluated,
+		 * evaluate them now and save the results.
+		 */
+		if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+			status = acpi_ds_get_buffer_field_arguments (obj_desc);
+			if (ACPI_FAILURE (status)) {
+				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 == ACPI_ADR_SPACE_SMBUS)) {
+		/*
+		 * This is an SMBus read.  We must create a buffer to hold the data
+		 * and directly access the region handler.
+		 */
+		buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE);
+		if (!buffer_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Lock entire transaction if requested */
+
+		locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+
+		/*
+		 * Perform the read.
+		 * Note: Smbus protocol value is passed in upper 16-bits of Function
+		 */
+		status = acpi_ex_access_region (obj_desc, 0,
+				  ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer),
+				  ACPI_READ | (obj_desc->field.attribute << 16));
+		acpi_ex_release_global_lock (locked);
+		goto exit;
+	}
+
+	/*
+	 * Allocate a buffer for the contents of the field.
+	 *
+	 * If the field is larger than the size of an acpi_integer, create
+	 * a BUFFER to hold it.  Otherwise, use an INTEGER.  This allows
+	 * the use of arithmetic operators on the returned value if the
+	 * field size is equal or smaller than an Integer.
+	 *
+	 * Note: Field.length is in bits.
+	 */
+	length = (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length);
+	if (length > acpi_gbl_integer_byte_width) {
+		/* Field is too large for an Integer, create a Buffer instead */
+
+		buffer_desc = acpi_ut_create_buffer_object (length);
+		if (!buffer_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+		buffer = buffer_desc->buffer.pointer;
+	}
+	else {
+		/* Field will fit within an Integer (normal case) */
+
+		buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!buffer_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		length = acpi_gbl_integer_byte_width;
+		buffer_desc->integer.value = 0;
+		buffer = &buffer_desc->integer.value;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+		"field_read [TO]:  Obj %p, Type %X, Buf %p, byte_len %X\n",
+		obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length));
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+		"field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n",
+		obj_desc->common_field.bit_length,
+		obj_desc->common_field.start_field_bit_offset,
+		obj_desc->common_field.base_byte_offset));
+
+	/* Lock entire transaction if requested */
+
+	locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+
+	/* Read from the field */
+
+	status = acpi_ex_extract_from_field (obj_desc, buffer, (u32) length);
+	acpi_ex_release_global_lock (locked);
+
+
+exit:
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (buffer_desc);
+	}
+	else if (ret_buffer_desc) {
+		*ret_buffer_desc = buffer_desc;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_write_data_to_field
+ *
+ * PARAMETERS:  source_desc         - Contains data to write
+ *              obj_desc            - The named field
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write to a named field
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_write_data_to_field (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc)
+{
+	acpi_status                     status;
+	u32                             length;
+	u32                             required_length;
+	void                            *buffer;
+	void                            *new_buffer;
+	u8                              locked;
+	union acpi_operand_object       *buffer_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_write_data_to_field", obj_desc);
+
+
+	/* Parameter validation */
+
+	if (!source_desc || !obj_desc) {
+		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+		/*
+		 * If the buffer_field arguments have not been previously evaluated,
+		 * evaluate them now and save the results.
+		 */
+		if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+			status = acpi_ds_get_buffer_field_arguments (obj_desc);
+			if (ACPI_FAILURE (status)) {
+				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 == ACPI_ADR_SPACE_SMBUS)) {
+		/*
+		 * This is an SMBus write.  We will bypass the entire field mechanism
+		 * and handoff the buffer directly to the handler.
+		 *
+		 * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
+		 */
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
+			ACPI_REPORT_ERROR (("SMBus write requires Buffer, found type %s\n",
+				acpi_ut_get_object_type_name (source_desc)));
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
+			ACPI_REPORT_ERROR (("SMBus write requires Buffer of length %X, found length %X\n",
+				ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
+			return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
+		}
+
+		buffer_desc = acpi_ut_create_buffer_object (ACPI_SMBUS_BUFFER_SIZE);
+		if (!buffer_desc) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		buffer = buffer_desc->buffer.pointer;
+		ACPI_MEMCPY (buffer, source_desc->buffer.pointer, ACPI_SMBUS_BUFFER_SIZE);
+
+		/* Lock entire transaction if requested */
+
+		locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+
+		/*
+		 * Perform the write (returns status and perhaps data in the same buffer)
+		 * Note: SMBus protocol type is passed in upper 16-bits of Function.
+		 */
+		status = acpi_ex_access_region (obj_desc, 0,
+				  (acpi_integer *) buffer,
+				  ACPI_WRITE | (obj_desc->field.attribute << 16));
+		acpi_ex_release_global_lock (locked);
+
+		*result_desc = buffer_desc;
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Get a pointer to the data to be written
+	 */
+	switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+	case ACPI_TYPE_INTEGER:
+		buffer = &source_desc->integer.value;
+		length = sizeof (source_desc->integer.value);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		buffer = source_desc->buffer.pointer;
+		length = source_desc->buffer.length;
+		break;
+
+	case ACPI_TYPE_STRING:
+		buffer = source_desc->string.pointer;
+		length = source_desc->string.length;
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+	}
+
+	/*
+	 * We must have a buffer that is at least as long as the field
+	 * we are writing to.  This is because individual fields are
+	 * indivisible and partial writes are not supported -- as per
+	 * the ACPI specification.
+	 */
+	new_buffer = NULL;
+	required_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
+
+	if (length < required_length) {
+		/* We need to create a new buffer */
+
+		new_buffer = ACPI_MEM_CALLOCATE (required_length);
+		if (!new_buffer) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/*
+		 * Copy the original data to the new buffer, starting
+		 * at Byte zero.  All unused (upper) bytes of the
+		 * buffer will be 0.
+		 */
+		ACPI_MEMCPY ((char *) new_buffer, (char *) buffer, length);
+		buffer = new_buffer;
+		length = required_length;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+		"field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n",
+		source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)),
+		ACPI_GET_OBJECT_TYPE (source_desc), buffer, length));
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+		"field_write [TO]:  Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n",
+		obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)),
+		ACPI_GET_OBJECT_TYPE (obj_desc),
+		obj_desc->common_field.bit_length,
+		obj_desc->common_field.start_field_bit_offset,
+		obj_desc->common_field.base_byte_offset));
+
+	/* Lock entire transaction if requested */
+
+	locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
+
+	/* Write to the field */
+
+	status = acpi_ex_insert_into_field (obj_desc, buffer, length);
+	acpi_ex_release_global_lock (locked);
+
+	/* Free temporary buffer if we used one */
+
+	if (new_buffer) {
+		ACPI_MEM_FREE (new_buffer);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
new file mode 100644
index 0000000..9d0f9d2
--- /dev/null
+++ b/drivers/acpi/executer/exfldio.c
@@ -0,0 +1,835 @@
+/******************************************************************************
+ *
+ * Module Name: exfldio - Aml Field I/O
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acevents.h>
+#include <acpi/acdispat.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exfldio")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_setup_region
+ *
+ * PARAMETERS:  *obj_desc               - Field to be read or written
+ *              field_datum_byte_offset - Byte offset of this datum within the
+ *                                        parent field
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Common processing for acpi_ex_extract_from_field and
+ *              acpi_ex_insert_into_field. Initialize the Region if necessary and
+ *              validate the request.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_setup_region (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *rgn_desc;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ex_setup_region", field_datum_byte_offset);
+
+
+	rgn_desc = obj_desc->common_field.region_obj;
+
+	/* We must have a valid region */
+
+	if (ACPI_GET_OBJECT_TYPE (rgn_desc) != ACPI_TYPE_REGION) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X (%s)\n",
+			ACPI_GET_OBJECT_TYPE (rgn_desc),
+			acpi_ut_get_object_type_name (rgn_desc)));
+
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+	}
+
+	/*
+	 * If the Region Address and Length have not been previously evaluated,
+	 * evaluate them now and save the results.
+	 */
+	if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
+		status = acpi_ds_get_region_arguments (rgn_desc);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
+		/* SMBus has a non-linear address space */
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+#ifdef ACPI_UNDER_DEVELOPMENT
+	/*
+	 * If the Field access is any_acc, we can now compute the optimal
+	 * access (because we know know the length of the parent region)
+	 */
+	if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+#endif
+
+	/*
+	 * Validate the request.  The entire request from the byte offset for a
+	 * length of one field datum (access width) must fit within the region.
+	 * (Region length is specified in bytes)
+	 */
+	if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
+			   + field_datum_byte_offset
+			   + obj_desc->common_field.access_byte_width)) {
+		if (acpi_gbl_enable_interpreter_slack) {
+			/*
+			 * Slack mode only:  We will go ahead and allow access to this
+			 * field if it is within the region length rounded up to the next
+			 * access width boundary.
+			 */
+			if (ACPI_ROUND_UP (rgn_desc->region.length,
+					   obj_desc->common_field.access_byte_width) >=
+				(obj_desc->common_field.base_byte_offset +
+				 (acpi_native_uint) obj_desc->common_field.access_byte_width +
+				 field_datum_byte_offset)) {
+				return_ACPI_STATUS (AE_OK);
+			}
+		}
+
+		if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) {
+			/*
+			 * This is the case where the access_type (acc_word, etc.) is wider
+			 * than the region itself.  For example, a region of length one
+			 * byte, and a field with Dword access specified.
+			 */
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
+				acpi_ut_get_node_name (obj_desc->common_field.node),
+				obj_desc->common_field.access_byte_width,
+				acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+		}
+
+		/*
+		 * Offset rounded up to next multiple of field width
+		 * exceeds region length, indicate an error
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
+			acpi_ut_get_node_name (obj_desc->common_field.node),
+			obj_desc->common_field.base_byte_offset,
+			field_datum_byte_offset, obj_desc->common_field.access_byte_width,
+			acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+
+		return_ACPI_STATUS (AE_AML_REGION_LIMIT);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_access_region
+ *
+ * PARAMETERS:  *obj_desc               - Field to be read
+ *              field_datum_byte_offset - Byte offset of this datum within the
+ *                                        parent field
+ *              *Value                  - Where to store value (must at least
+ *                                        the size of acpi_integer)
+ *              Function                - Read or Write flag plus other region-
+ *                                        dependent flags
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or Write a single field datum to an Operation Region.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_access_region (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset,
+	acpi_integer                    *value,
+	u32                             function)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *rgn_desc;
+	acpi_physical_address           address;
+
+
+	ACPI_FUNCTION_TRACE ("ex_access_region");
+
+
+	/*
+	 * Ensure that the region operands are fully evaluated and verify
+	 * the validity of the request
+	 */
+	status = acpi_ex_setup_region (obj_desc, field_datum_byte_offset);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * The physical address of this field datum is:
+	 *
+	 * 1) The base of the region, plus
+	 * 2) The base offset of the field, plus
+	 * 3) The current offset into the field
+	 */
+	rgn_desc = obj_desc->common_field.region_obj;
+	address = rgn_desc->region.address
+			 + obj_desc->common_field.base_byte_offset
+			 + field_datum_byte_offset;
+
+	if ((function & ACPI_IO_MASK) == ACPI_READ) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[WRITE]"));
+	}
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD,
+		" Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n",
+		acpi_ut_get_region_name (rgn_desc->region.space_id),
+		rgn_desc->region.space_id,
+		obj_desc->common_field.access_byte_width,
+		obj_desc->common_field.base_byte_offset,
+		field_datum_byte_offset,
+		ACPI_FORMAT_UINT64 (address)));
+
+	/* Invoke the appropriate address_space/op_region handler */
+
+	status = acpi_ev_address_space_dispatch (rgn_desc, function,
+			  address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
+
+	if (ACPI_FAILURE (status)) {
+		if (status == AE_NOT_IMPLEMENTED) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Region %s(%X) not implemented\n",
+				acpi_ut_get_region_name (rgn_desc->region.space_id),
+				rgn_desc->region.space_id));
+		}
+		else if (status == AE_NOT_EXIST) {
+			ACPI_REPORT_ERROR ((
+				"Region %s(%X) has no handler\n",
+				acpi_ut_get_region_name (rgn_desc->region.space_id),
+				rgn_desc->region.space_id));
+		}
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_register_overflow
+ *
+ * PARAMETERS:  *obj_desc               - Register(Field) to be written
+ *              Value                   - Value to be stored
+ *
+ * RETURN:      TRUE if value overflows the field, FALSE otherwise
+ *
+ * DESCRIPTION: Check if a value is out of range of the field being written.
+ *              Used to check if the values written to Index and Bank registers
+ *              are out of range.  Normally, the value is simply truncated
+ *              to fit the field, but this case is most likely a serious
+ *              coding error in the ASL.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ex_register_overflow (
+	union acpi_operand_object       *obj_desc,
+	acpi_integer                    value)
+{
+
+	if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
+		/*
+		 * The field is large enough to hold the maximum integer, so we can
+		 * never overflow it.
+		 */
+		return (FALSE);
+	}
+
+	if (value >= ((acpi_integer) 1 << obj_desc->common_field.bit_length)) {
+		/*
+		 * The Value is larger than the maximum value that can fit into
+		 * the register.
+		 */
+		return (TRUE);
+	}
+
+	/* The Value will fit into the field with no truncation */
+
+	return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_field_datum_io
+ *
+ * PARAMETERS:  *obj_desc               - Field to be read
+ *              field_datum_byte_offset - Byte offset of this datum within the
+ *                                        parent field
+ *              *Value                  - Where to store value (must be 64 bits)
+ *              read_write              - Read or Write flag
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read or Write a single datum of a field.  The field_type is
+ *              demultiplexed here to handle the different types of fields
+ *              (buffer_field, region_field, index_field, bank_field)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_field_datum_io (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset,
+	acpi_integer                    *value,
+	u32                             read_write)
+{
+	acpi_status                     status;
+	acpi_integer                    local_value;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ex_field_datum_io", field_datum_byte_offset);
+
+
+	if (read_write == ACPI_READ) {
+		if (!value) {
+			local_value = 0;
+			value = &local_value; /* To support reads without saving return value */
+		}
+
+		/* Clear the entire return buffer first, [Very Important!] */
+
+		*value = 0;
+	}
+
+	/*
+	 * The four types of fields are:
+	 *
+	 * buffer_field - Read/write from/to a Buffer
+	 * region_field - Read/write from/to a Operation Region.
+	 * bank_field  - Write to a Bank Register, then read/write from/to an op_region
+	 * index_field - Write to an Index Register, then read/write from/to a Data Register
+	 */
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_BUFFER_FIELD:
+		/*
+		 * If the buffer_field arguments have not been previously evaluated,
+		 * evaluate them now and save the results.
+		 */
+		if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+			status = acpi_ds_get_buffer_field_arguments (obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+
+		if (read_write == ACPI_READ) {
+			/*
+			 * Copy the data from the source buffer.
+			 * Length is the field width in bytes.
+			 */
+			ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer
+					  + obj_desc->buffer_field.base_byte_offset
+					  + field_datum_byte_offset,
+					  obj_desc->common_field.access_byte_width);
+		}
+		else {
+			/*
+			 * Copy the data to the target buffer.
+			 * Length is the field width in bytes.
+			 */
+			ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer
+					+ obj_desc->buffer_field.base_byte_offset
+					+ field_datum_byte_offset,
+					value, obj_desc->common_field.access_byte_width);
+		}
+
+		status = AE_OK;
+		break;
+
+
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+		/* Ensure that the bank_value is not beyond the capacity of the register */
+
+		if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj,
+				  (acpi_integer) obj_desc->bank_field.value)) {
+			return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
+		}
+
+		/*
+		 * For bank_fields, we must write the bank_value to the bank_register
+		 * (itself a region_field) before we can access the data.
+		 */
+		status = acpi_ex_insert_into_field (obj_desc->bank_field.bank_obj,
+				 &obj_desc->bank_field.value,
+				 sizeof (obj_desc->bank_field.value));
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/*
+		 * Now that the Bank has been selected, fall through to the
+		 * region_field case and write the datum to the Operation Region
+		 */
+
+		/*lint -fallthrough */
+
+
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+		/*
+		 * For simple region_fields, we just directly access the owning
+		 * Operation Region.
+		 */
+		status = acpi_ex_access_region (obj_desc, field_datum_byte_offset, value,
+				  read_write);
+		break;
+
+
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+
+		/* Ensure that the index_value is not beyond the capacity of the register */
+
+		if (acpi_ex_register_overflow (obj_desc->index_field.index_obj,
+				  (acpi_integer) obj_desc->index_field.value)) {
+			return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
+		}
+
+		/* Write the index value to the index_register (itself a region_field) */
+
+		field_datum_byte_offset += obj_desc->index_field.value;
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+				"Write to Index Register: Value %8.8X\n",
+				field_datum_byte_offset));
+
+		status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj,
+				 &field_datum_byte_offset,
+				 sizeof (field_datum_byte_offset));
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+				"I/O to Data Register: value_ptr %p\n",
+				value));
+
+		if (read_write == ACPI_READ) {
+			/* Read the datum from the data_register */
+
+			status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj,
+					  value, sizeof (acpi_integer));
+		}
+		else {
+			/* Write the datum to the data_register */
+
+			status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj,
+					  value, sizeof (acpi_integer));
+		}
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("Wrong object type in field I/O %X\n",
+			ACPI_GET_OBJECT_TYPE (obj_desc)));
+		status = AE_AML_INTERNAL;
+		break;
+	}
+
+	if (ACPI_SUCCESS (status)) {
+		if (read_write == ACPI_READ) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n",
+					   ACPI_FORMAT_UINT64 (*value),
+					   obj_desc->common_field.access_byte_width));
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n",
+					   ACPI_FORMAT_UINT64 (*value),
+					   obj_desc->common_field.access_byte_width));
+		}
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_write_with_update_rule
+ *
+ * PARAMETERS:  *obj_desc           - Field to be set
+ *              Value               - Value to store
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Apply the field update rule to a field write
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_write_with_update_rule (
+	union acpi_operand_object       *obj_desc,
+	acpi_integer                    mask,
+	acpi_integer                    field_value,
+	u32                             field_datum_byte_offset)
+{
+	acpi_status                     status = AE_OK;
+	acpi_integer                    merged_value;
+	acpi_integer                    current_value;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ex_write_with_update_rule", mask);
+
+
+	/* Start with the new bits  */
+
+	merged_value = field_value;
+
+	/* If the mask is all ones, we don't need to worry about the update rule */
+
+	if (mask != ACPI_INTEGER_MAX) {
+		/* Decode the update rule */
+
+		switch (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK) {
+		case AML_FIELD_UPDATE_PRESERVE:
+			/*
+			 * Check if update rule needs to be applied (not if mask is all
+			 * ones)  The left shift drops the bits we want to ignore.
+			 */
+			if ((~mask << (ACPI_MUL_8 (sizeof (mask)) -
+					 ACPI_MUL_8 (obj_desc->common_field.access_byte_width))) != 0) {
+				/*
+				 * Read the current contents of the byte/word/dword containing
+				 * the field, and merge with the new field value.
+				 */
+				status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
+						  &current_value, ACPI_READ);
+				if (ACPI_FAILURE (status)) {
+					return_ACPI_STATUS (status);
+				}
+
+				merged_value |= (current_value & ~mask);
+			}
+			break;
+
+		case AML_FIELD_UPDATE_WRITE_AS_ONES:
+
+			/* Set positions outside the field to all ones */
+
+			merged_value |= ~mask;
+			break;
+
+		case AML_FIELD_UPDATE_WRITE_AS_ZEROS:
+
+			/* Set positions outside the field to all zeros */
+
+			merged_value &= mask;
+			break;
+
+		default:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"write_with_update_rule: Unknown update_rule setting: %X\n",
+				(obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK)));
+			return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+		"Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
+		ACPI_FORMAT_UINT64 (mask),
+		field_datum_byte_offset,
+		obj_desc->common_field.access_byte_width,
+		ACPI_FORMAT_UINT64 (field_value),
+		ACPI_FORMAT_UINT64 (merged_value)));
+
+	/* Write the merged value */
+
+	status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
+			  &merged_value, ACPI_WRITE);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_extract_from_field
+ *
+ * PARAMETERS:  obj_desc            - Field to be read
+ *              Buffer              - Where to store the field data
+ *              buffer_length       - Length of Buffer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve the current value of the given field
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_extract_from_field (
+	union acpi_operand_object       *obj_desc,
+	void                            *buffer,
+	u32                             buffer_length)
+{
+	acpi_status                     status;
+	acpi_integer                    raw_datum;
+	acpi_integer                    merged_datum;
+	u32                             field_offset = 0;
+	u32                             buffer_offset = 0;
+	u32                             buffer_tail_bits;
+	u32                             datum_count;
+	u32                             field_datum_count;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ex_extract_from_field");
+
+
+	/* Validate target buffer and clear it */
+
+	if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
+			 obj_desc->common_field.bit_length)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Field size %X (bits) is too large for buffer (%X)\n",
+			obj_desc->common_field.bit_length, buffer_length));
+
+		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+	}
+	ACPI_MEMSET (buffer, 0, buffer_length);
+
+	/* Compute the number of datums (access width data items) */
+
+	datum_count = ACPI_ROUND_UP_TO (
+			   obj_desc->common_field.bit_length,
+			   obj_desc->common_field.access_bit_width);
+	field_datum_count = ACPI_ROUND_UP_TO (
+			   obj_desc->common_field.bit_length +
+			   obj_desc->common_field.start_field_bit_offset,
+			   obj_desc->common_field.access_bit_width);
+
+	/* Priming read from the field */
+
+	status = acpi_ex_field_datum_io (obj_desc, field_offset, &raw_datum, ACPI_READ);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
+
+	/* Read the rest of the field */
+
+	for (i = 1; i < field_datum_count; i++) {
+		/* Get next input datum from the field */
+
+		field_offset += obj_desc->common_field.access_byte_width;
+		status = acpi_ex_field_datum_io (obj_desc, field_offset,
+				  &raw_datum, ACPI_READ);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* Merge with previous datum if necessary */
+
+		merged_datum |= raw_datum <<
+			(obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
+
+		if (i == datum_count) {
+			break;
+		}
+
+		/* Write merged datum to target buffer */
+
+		ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
+			ACPI_MIN(obj_desc->common_field.access_byte_width,
+					 buffer_length - buffer_offset));
+
+		buffer_offset += obj_desc->common_field.access_byte_width;
+		merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset;
+	}
+
+	/* Mask off any extra bits in the last datum */
+
+	buffer_tail_bits = obj_desc->common_field.bit_length % obj_desc->common_field.access_bit_width;
+	if (buffer_tail_bits) {
+		merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
+	}
+
+	/* Write the last datum to the buffer */
+
+	ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum,
+		ACPI_MIN(obj_desc->common_field.access_byte_width,
+				 buffer_length - buffer_offset));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_insert_into_field
+ *
+ * PARAMETERS:  obj_desc            - Field to be written
+ *              Buffer              - Data to be written
+ *              buffer_length       - Length of Buffer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the Buffer contents into the given field
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_insert_into_field (
+	union acpi_operand_object       *obj_desc,
+	void                            *buffer,
+	u32                             buffer_length)
+{
+	acpi_status                     status;
+	acpi_integer                    mask;
+	acpi_integer                    merged_datum;
+	acpi_integer                    raw_datum = 0;
+	u32                             field_offset = 0;
+	u32                             buffer_offset = 0;
+	u32                             buffer_tail_bits;
+	u32                             datum_count;
+	u32                             field_datum_count;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ex_insert_into_field");
+
+
+	/* Validate input buffer */
+
+	if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES (
+			 obj_desc->common_field.bit_length)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Field size %X (bits) is too large for buffer (%X)\n",
+			obj_desc->common_field.bit_length, buffer_length));
+
+		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+	}
+
+	/* Compute the number of datums (access width data items) */
+
+	mask = ACPI_MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset);
+	datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length,
+			  obj_desc->common_field.access_bit_width);
+	field_datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length +
+			   obj_desc->common_field.start_field_bit_offset,
+			   obj_desc->common_field.access_bit_width);
+
+	/* Get initial Datum from the input buffer */
+
+	ACPI_MEMCPY (&raw_datum, buffer,
+		ACPI_MIN(obj_desc->common_field.access_byte_width,
+				 buffer_length - buffer_offset));
+
+	merged_datum = raw_datum << obj_desc->common_field.start_field_bit_offset;
+
+	/* Write the entire field */
+
+	for (i = 1; i < field_datum_count; i++) {
+		/* Write merged datum to the target field */
+
+		merged_datum &= mask;
+		status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* Start new output datum by merging with previous input datum */
+
+		field_offset += obj_desc->common_field.access_byte_width;
+		merged_datum = raw_datum >>
+			(obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
+		mask = ACPI_INTEGER_MAX;
+
+		if (i == datum_count) {
+			break;
+		}
+
+		/* Get the next input datum from the buffer */
+
+		buffer_offset += obj_desc->common_field.access_byte_width;
+		ACPI_MEMCPY (&raw_datum, ((char *) buffer) + buffer_offset,
+			ACPI_MIN(obj_desc->common_field.access_byte_width,
+					 buffer_length - buffer_offset));
+		merged_datum |= raw_datum << obj_desc->common_field.start_field_bit_offset;
+	}
+
+	/* Mask off any extra bits in the last datum */
+
+	buffer_tail_bits = (obj_desc->common_field.bit_length +
+			obj_desc->common_field.start_field_bit_offset) % obj_desc->common_field.access_bit_width;
+	if (buffer_tail_bits) {
+		mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
+	}
+
+	/* Write the last datum to the field */
+
+	merged_datum &= mask;
+	status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
new file mode 100644
index 0000000..b542dcd
--- /dev/null
+++ b/drivers/acpi/executer/exmisc.c
@@ -0,0 +1,738 @@
+
+/******************************************************************************
+ *
+ * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_get_object_reference
+ *
+ * PARAMETERS:  obj_desc            - Create a reference to this object
+ *              return_desc         - Where to store the reference
+ *              walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtain and return a "reference" to the target object
+ *              Common code for the ref_of_op and the cond_ref_of_op.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_get_object_reference (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **return_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *reference_obj;
+	union acpi_operand_object       *referenced_obj;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_get_object_reference", obj_desc);
+
+
+	*return_desc = NULL;
+
+	switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+	case ACPI_DESC_TYPE_OPERAND:
+
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		/*
+		 * Must be a reference to a Local or Arg
+		 */
+		switch (obj_desc->reference.opcode) {
+		case AML_LOCAL_OP:
+		case AML_ARG_OP:
+		case AML_DEBUG_OP:
+
+			/* The referenced object is the pseudo-node for the local/arg */
+
+			referenced_obj = obj_desc->reference.object;
+			break;
+
+		default:
+
+			ACPI_REPORT_ERROR (("Unknown Reference opcode in get_reference %X\n",
+				obj_desc->reference.opcode));
+			return_ACPI_STATUS (AE_AML_INTERNAL);
+		}
+		break;
+
+
+	case ACPI_DESC_TYPE_NAMED:
+
+		/*
+		 * A named reference that has already been resolved to a Node
+		 */
+		referenced_obj = obj_desc;
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("Invalid descriptor type in get_reference: %X\n",
+				ACPI_GET_DESCRIPTOR_TYPE (obj_desc)));
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+
+	/* Create a new reference object */
+
+	reference_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
+	if (!reference_obj) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	reference_obj->reference.opcode = AML_REF_OF_OP;
+	reference_obj->reference.object = referenced_obj;
+	*return_desc = reference_obj;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
+			obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_concat_template
+ *
+ * PARAMETERS:  Operand0            - First source object
+ *              Operand1            - Second source object
+ *              actual_return_desc  - Where to place the return object
+ *              walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Concatenate two resource templates
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_concat_template (
+	union acpi_operand_object       *operand0,
+	union acpi_operand_object       *operand1,
+	union acpi_operand_object       **actual_return_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *return_desc;
+	u8                              *new_buf;
+	u8                              *end_tag1;
+	u8                              *end_tag2;
+	acpi_size                       length1;
+	acpi_size                       length2;
+
+
+	ACPI_FUNCTION_TRACE ("ex_concat_template");
+
+
+	/* Find the end_tags in each resource template */
+
+	end_tag1 = acpi_ut_get_resource_end_tag (operand0);
+	end_tag2 = acpi_ut_get_resource_end_tag (operand1);
+	if (!end_tag1 || !end_tag2) {
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+	}
+
+	/* Compute the length of each part */
+
+	length1 = ACPI_PTR_DIFF (end_tag1, operand0->buffer.pointer);
+	length2 = ACPI_PTR_DIFF (end_tag2, operand1->buffer.pointer) +
+			  2; /* Size of END_TAG */
+
+	/* Create a new buffer object for the result */
+
+	return_desc = acpi_ut_create_buffer_object (length1 + length2);
+	if (!return_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Copy the templates to the new descriptor */
+
+	new_buf = return_desc->buffer.pointer;
+	ACPI_MEMCPY (new_buf, operand0->buffer.pointer, length1);
+	ACPI_MEMCPY (new_buf + length1, operand1->buffer.pointer, length2);
+
+	/* Compute the new checksum */
+
+	new_buf[return_desc->buffer.length - 1] =
+			acpi_ut_generate_checksum (return_desc->buffer.pointer,
+					   (return_desc->buffer.length - 1));
+
+	/* Return the completed template descriptor */
+
+	*actual_return_desc = return_desc;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_do_concatenate
+ *
+ * PARAMETERS:  Operand0            - First source object
+ *              Operand1            - Second source object
+ *              actual_return_desc  - Where to place the return object
+ *              walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_do_concatenate (
+	union acpi_operand_object       *operand0,
+	union acpi_operand_object       *operand1,
+	union acpi_operand_object       **actual_return_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *local_operand1 = operand1;
+	union acpi_operand_object       *return_desc;
+	char                            *new_buf;
+	acpi_status                     status;
+	acpi_size                       new_length;
+
+
+	ACPI_FUNCTION_TRACE ("ex_do_concatenate");
+
+
+	/*
+	 * Convert the second operand if necessary.  The first operand
+	 * determines the type of the second operand, (See the Data Types
+	 * section of the ACPI specification.)  Both object types are
+	 * guaranteed to be either Integer/String/Buffer by the operand
+	 * resolution mechanism.
+	 */
+	switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+	case ACPI_TYPE_INTEGER:
+		status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16);
+		break;
+
+	case ACPI_TYPE_STRING:
+		status = acpi_ex_convert_to_string (operand1, &local_operand1,
+				 ACPI_IMPLICIT_CONVERT_HEX);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		status = acpi_ex_convert_to_buffer (operand1, &local_operand1);
+		break;
+
+	default:
+		ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
+				ACPI_GET_OBJECT_TYPE (operand0)));
+		status = AE_AML_INTERNAL;
+	}
+
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/*
+	 * Both operands are now known to be the same object type
+	 * (Both are Integer, String, or Buffer), and we can now perform the
+	 * concatenation.
+	 */
+
+	/*
+	 * There are three cases to handle:
+	 *
+	 * 1) Two Integers concatenated to produce a new Buffer
+	 * 2) Two Strings concatenated to produce a new String
+	 * 3) Two Buffers concatenated to produce a new Buffer
+	 */
+	switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+	case ACPI_TYPE_INTEGER:
+
+		/* Result of two Integers is a Buffer */
+		/* Need enough buffer space for two integers */
+
+		return_desc = acpi_ut_create_buffer_object (
+				   ACPI_MUL_2 (acpi_gbl_integer_byte_width));
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		new_buf = (char *) return_desc->buffer.pointer;
+
+		/* Copy the first integer, LSB first */
+
+		ACPI_MEMCPY (new_buf,
+				  &operand0->integer.value,
+				  acpi_gbl_integer_byte_width);
+
+		/* Copy the second integer (LSB first) after the first */
+
+		ACPI_MEMCPY (new_buf + acpi_gbl_integer_byte_width,
+				  &local_operand1->integer.value,
+				  acpi_gbl_integer_byte_width);
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		/* Result of two Strings is a String */
+
+		new_length = (acpi_size) operand0->string.length +
+				 (acpi_size) local_operand1->string.length;
+		if (new_length > ACPI_MAX_STRING_CONVERSION) {
+			status = AE_AML_STRING_LIMIT;
+			goto cleanup;
+		}
+
+		return_desc = acpi_ut_create_string_object (new_length);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		new_buf = return_desc->string.pointer;
+
+		/* Concatenate the strings */
+
+		ACPI_STRCPY (new_buf,
+				  operand0->string.pointer);
+		ACPI_STRCPY (new_buf + operand0->string.length,
+				  local_operand1->string.pointer);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		/* Result of two Buffers is a Buffer */
+
+		return_desc = acpi_ut_create_buffer_object (
+				   (acpi_size) operand0->buffer.length +
+				   (acpi_size) local_operand1->buffer.length);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		new_buf = (char *) return_desc->buffer.pointer;
+
+		/* Concatenate the buffers */
+
+		ACPI_MEMCPY (new_buf,
+				  operand0->buffer.pointer,
+				  operand0->buffer.length);
+		ACPI_MEMCPY (new_buf + operand0->buffer.length,
+				  local_operand1->buffer.pointer,
+				  local_operand1->buffer.length);
+		break;
+
+	default:
+
+		/* Invalid object type, should not happen here */
+
+		ACPI_REPORT_ERROR (("Concatenate - Invalid object type: %X\n",
+				ACPI_GET_OBJECT_TYPE (operand0)));
+		status =AE_AML_INTERNAL;
+		goto cleanup;
+	}
+
+	*actual_return_desc = return_desc;
+
+cleanup:
+	if (local_operand1 != operand1) {
+		acpi_ut_remove_reference (local_operand1);
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_do_math_op
+ *
+ * PARAMETERS:  Opcode              - AML opcode
+ *              Integer0            - Integer operand #0
+ *              Integer1            - Integer operand #1
+ *
+ * RETURN:      Integer result of the operation
+ *
+ * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
+ *              math functions here is to prevent a lot of pointer dereferencing
+ *              to obtain the operands.
+ *
+ ******************************************************************************/
+
+acpi_integer
+acpi_ex_do_math_op (
+	u16                             opcode,
+	acpi_integer                    integer0,
+	acpi_integer                    integer1)
+{
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	switch (opcode) {
+	case AML_ADD_OP:                /* Add (Integer0, Integer1, Result) */
+
+		return (integer0 + integer1);
+
+
+	case AML_BIT_AND_OP:            /* And (Integer0, Integer1, Result) */
+
+		return (integer0 & integer1);
+
+
+	case AML_BIT_NAND_OP:           /* NAnd (Integer0, Integer1, Result) */
+
+		return (~(integer0 & integer1));
+
+
+	case AML_BIT_OR_OP:             /* Or (Integer0, Integer1, Result) */
+
+		return (integer0 | integer1);
+
+
+	case AML_BIT_NOR_OP:            /* NOr (Integer0, Integer1, Result) */
+
+		return (~(integer0 | integer1));
+
+
+	case AML_BIT_XOR_OP:            /* XOr (Integer0, Integer1, Result) */
+
+		return (integer0 ^ integer1);
+
+
+	case AML_MULTIPLY_OP:           /* Multiply (Integer0, Integer1, Result) */
+
+		return (integer0 * integer1);
+
+
+	case AML_SHIFT_LEFT_OP:         /* shift_left (Operand, shift_count, Result) */
+
+		return (integer0 << integer1);
+
+
+	case AML_SHIFT_RIGHT_OP:        /* shift_right (Operand, shift_count, Result) */
+
+		return (integer0 >> integer1);
+
+
+	case AML_SUBTRACT_OP:           /* Subtract (Integer0, Integer1, Result) */
+
+		return (integer0 - integer1);
+
+	default:
+
+		return (0);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_do_logical_numeric_op
+ *
+ * PARAMETERS:  Opcode              - AML opcode
+ *              Integer0            - Integer operand #0
+ *              Integer1            - Integer operand #1
+ *              logical_result      - TRUE/FALSE result of the operation
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
+ *              operators (LAnd and LOr), both operands must be integers.
+ *
+ *              Note: cleanest machine code seems to be produced by the code
+ *              below, rather than using statements of the form:
+ *                  Result = (Integer0 && Integer1);
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_do_logical_numeric_op (
+	u16                             opcode,
+	acpi_integer                    integer0,
+	acpi_integer                    integer1,
+	u8                              *logical_result)
+{
+	acpi_status                     status = AE_OK;
+	u8                              local_result = FALSE;
+
+
+	ACPI_FUNCTION_TRACE ("ex_do_logical_numeric_op");
+
+
+	switch (opcode) {
+	case AML_LAND_OP:               /* LAnd (Integer0, Integer1) */
+
+		if (integer0 && integer1) {
+			local_result = TRUE;
+		}
+		break;
+
+	case AML_LOR_OP:                /* LOr (Integer0, Integer1) */
+
+		if (integer0 || integer1) {
+			local_result = TRUE;
+		}
+		break;
+
+	default:
+		status = AE_AML_INTERNAL;
+		break;
+	}
+
+	/* Return the logical result and status */
+
+	*logical_result = local_result;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_do_logical_op
+ *
+ * PARAMETERS:  Opcode              - AML opcode
+ *              Operand0            - operand #0
+ *              Operand1            - operand #1
+ *              logical_result      - TRUE/FALSE result of the operation
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
+ *              functions here is to prevent a lot of pointer dereferencing
+ *              to obtain the operands and to simplify the generation of the
+ *              logical value. For the Numeric operators (LAnd and LOr), both
+ *              operands must be integers. For the other logical operators,
+ *              operands can be any combination of Integer/String/Buffer. The
+ *              first operand determines the type to which the second operand
+ *              will be converted.
+ *
+ *              Note: cleanest machine code seems to be produced by the code
+ *              below, rather than using statements of the form:
+ *                  Result = (Operand0 == Operand1);
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_do_logical_op (
+	u16                             opcode,
+	union acpi_operand_object       *operand0,
+	union acpi_operand_object       *operand1,
+	u8                              *logical_result)
+{
+	union acpi_operand_object       *local_operand1 = operand1;
+	acpi_integer                    integer0;
+	acpi_integer                    integer1;
+	u32                             length0;
+	u32                             length1;
+	acpi_status                     status = AE_OK;
+	u8                              local_result = FALSE;
+	int                             compare;
+
+
+	ACPI_FUNCTION_TRACE ("ex_do_logical_op");
+
+
+	/*
+	 * Convert the second operand if necessary.  The first operand
+	 * determines the type of the second operand, (See the Data Types
+	 * section of the ACPI 3.0+ specification.)  Both object types are
+	 * guaranteed to be either Integer/String/Buffer by the operand
+	 * resolution mechanism.
+	 */
+	switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+	case ACPI_TYPE_INTEGER:
+		status = acpi_ex_convert_to_integer (operand1, &local_operand1, 16);
+		break;
+
+	case ACPI_TYPE_STRING:
+		status = acpi_ex_convert_to_string (operand1, &local_operand1,
+				 ACPI_IMPLICIT_CONVERT_HEX);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		status = acpi_ex_convert_to_buffer (operand1, &local_operand1);
+		break;
+
+	default:
+		status = AE_AML_INTERNAL;
+		break;
+	}
+
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/*
+	 * Two cases: 1) Both Integers, 2) Both Strings or Buffers
+	 */
+	if (ACPI_GET_OBJECT_TYPE (operand0) == ACPI_TYPE_INTEGER) {
+		/*
+		 * 1) Both operands are of type integer
+		 *    Note: local_operand1 may have changed above
+		 */
+		integer0 = operand0->integer.value;
+		integer1 = local_operand1->integer.value;
+
+		switch (opcode) {
+		case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
+
+			if (integer0 == integer1) {
+				local_result = TRUE;
+			}
+			break;
+
+		case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
+
+			if (integer0 > integer1) {
+				local_result = TRUE;
+			}
+			break;
+
+		case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
+
+			if (integer0 < integer1) {
+				local_result = TRUE;
+			}
+			break;
+
+		default:
+			status = AE_AML_INTERNAL;
+			break;
+		}
+	}
+	else {
+		/*
+		 * 2) Both operands are Strings or both are Buffers
+		 *    Note: Code below takes advantage of common Buffer/String
+		 *          object fields. local_operand1 may have changed above. Use
+		 *          memcmp to handle nulls in buffers.
+		 */
+		length0 = operand0->buffer.length;
+		length1 = local_operand1->buffer.length;
+
+		/* Lexicographic compare: compare the data bytes */
+
+		compare = ACPI_MEMCMP ((const char * ) operand0->buffer.pointer,
+				 (const char * ) local_operand1->buffer.pointer,
+				 (length0 > length1) ? length1 : length0);
+
+		switch (opcode) {
+		case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
+
+			/* Length and all bytes must be equal */
+
+			if ((length0 == length1) &&
+				(compare == 0)) {
+				/* Length and all bytes match ==> TRUE */
+
+				local_result = TRUE;
+			}
+			break;
+
+		case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
+
+			if (compare > 0) {
+				local_result = TRUE;
+				goto cleanup;   /* TRUE */
+			}
+			if (compare < 0) {
+				goto cleanup;   /* FALSE */
+			}
+
+			/* Bytes match (to shortest length), compare lengths */
+
+			if (length0 > length1) {
+				local_result = TRUE;
+			}
+			break;
+
+		case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
+
+			if (compare > 0) {
+				goto cleanup;   /* FALSE */
+			}
+			if (compare < 0) {
+				local_result = TRUE;
+				goto cleanup;   /* TRUE */
+			}
+
+			/* Bytes match (to shortest length), compare lengths */
+
+			if (length0 < length1) {
+				local_result = TRUE;
+			}
+			break;
+
+		default:
+			status = AE_AML_INTERNAL;
+			break;
+		}
+	}
+
+cleanup:
+
+	/* New object was created if implicit conversion performed - delete */
+
+	if (local_operand1 != operand1) {
+		acpi_ut_remove_reference (local_operand1);
+	}
+
+	/* Return the logical result and status */
+
+	*logical_result = local_result;
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
new file mode 100644
index 0000000..68c4bb1
--- /dev/null
+++ b/drivers/acpi/executer/exmutex.c
@@ -0,0 +1,363 @@
+
+/******************************************************************************
+ *
+ * Module Name: exmutex - ASL Mutex Acquire/Release functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exmutex")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_unlink_mutex
+ *
+ * PARAMETERS:  obj_desc            - The mutex to be unlinked
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove a mutex from the "acquired_mutex" list
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_unlink_mutex (
+	union acpi_operand_object       *obj_desc)
+{
+	struct acpi_thread_state        *thread = obj_desc->mutex.owner_thread;
+
+
+	if (!thread) {
+		return;
+	}
+
+	/* Doubly linked list */
+
+	if (obj_desc->mutex.next) {
+		(obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev;
+	}
+
+	if (obj_desc->mutex.prev) {
+		(obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;
+	}
+	else {
+		thread->acquired_mutex_list = obj_desc->mutex.next;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_link_mutex
+ *
+ * PARAMETERS:  obj_desc            - The mutex to be linked
+ *              list_head           - head of the "acquired_mutex" list
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Add a mutex to the "acquired_mutex" list for this walk
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_link_mutex (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_thread_state        *thread)
+{
+	union acpi_operand_object       *list_head;
+
+
+	list_head = thread->acquired_mutex_list;
+
+	/* This object will be the first object in the list */
+
+	obj_desc->mutex.prev = NULL;
+	obj_desc->mutex.next = list_head;
+
+	/* Update old first object to point back to this object */
+
+	if (list_head) {
+		list_head->mutex.prev = obj_desc;
+	}
+
+	/* Update list head */
+
+	thread->acquired_mutex_list = obj_desc;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_acquire_mutex
+ *
+ * PARAMETERS:  time_desc           - The 'time to delay' object descriptor
+ *              obj_desc            - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire an AML mutex
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_acquire_mutex (
+	union acpi_operand_object       *time_desc,
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_acquire_mutex", obj_desc);
+
+
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Sanity check -- we must have a valid thread ID */
+
+	if (!walk_state->thread) {
+		ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n",
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
+		return_ACPI_STATUS (AE_AML_INTERNAL);
+	}
+
+	/*
+	 * Current Sync must be less than or equal to the sync level of the
+	 * mutex.  This mechanism provides some deadlock prevention
+	 */
+	if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
+		ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
+		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+	}
+
+	/* Support for multiple acquires by the owning thread */
+
+	if (obj_desc->mutex.owner_thread) {
+		/* Special case for Global Lock, allow all threads */
+
+		if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) ||
+			(obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) {
+			/*
+			 * The mutex is already owned by this thread,
+			 * just increment the acquisition depth
+			 */
+			obj_desc->mutex.acquisition_depth++;
+			return_ACPI_STATUS (AE_OK);
+		}
+	}
+
+	/* Acquire the mutex, wait if necessary */
+
+	status = acpi_ex_system_acquire_mutex (time_desc, obj_desc);
+	if (ACPI_FAILURE (status)) {
+		/* Includes failure from a timeout on time_desc */
+
+		return_ACPI_STATUS (status);
+	}
+
+	/* Have the mutex: update mutex and walk info and save the sync_level */
+
+	obj_desc->mutex.owner_thread     = walk_state->thread;
+	obj_desc->mutex.acquisition_depth = 1;
+	obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level;
+
+	walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
+
+	/* Link the mutex to the current thread for force-unlock at method exit */
+
+	acpi_ex_link_mutex (obj_desc, walk_state->thread);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_release_mutex
+ *
+ * PARAMETERS:  obj_desc            - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release a previously acquired Mutex.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_release_mutex (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ex_release_mutex");
+
+
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* The mutex must have been previously acquired in order to release it */
+
+	if (!obj_desc->mutex.owner_thread) {
+		ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], not acquired\n",
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
+		return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
+	}
+
+	/* Sanity check -- we must have a valid thread ID */
+
+	if (!walk_state->thread) {
+		ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], null thread info\n",
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
+		return_ACPI_STATUS (AE_AML_INTERNAL);
+	}
+
+	/*
+	 * The Mutex is owned, but this thread must be the owner.
+	 * Special case for Global Lock, any thread can release
+	 */
+	if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) &&
+		(obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) {
+		ACPI_REPORT_ERROR ((
+			"Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
+			walk_state->thread->thread_id,
+			acpi_ut_get_node_name (obj_desc->mutex.node),
+			obj_desc->mutex.owner_thread->thread_id));
+		return_ACPI_STATUS (AE_AML_NOT_OWNER);
+	}
+
+	/*
+	 * The sync level of the mutex must be less than or
+	 * equal to the current sync level
+	 */
+	if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
+		ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n",
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
+		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+	}
+
+	/* Match multiple Acquires with multiple Releases */
+
+	obj_desc->mutex.acquisition_depth--;
+	if (obj_desc->mutex.acquisition_depth != 0) {
+		/* Just decrement the depth and return */
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Unlink the mutex from the owner's list */
+
+	acpi_ex_unlink_mutex (obj_desc);
+
+	/* Release the mutex */
+
+	status = acpi_ex_system_release_mutex (obj_desc);
+
+	/* Update the mutex and walk state, restore sync_level before acquire */
+
+	obj_desc->mutex.owner_thread = NULL;
+	walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level;
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_release_all_mutexes
+ *
+ * PARAMETERS:  mutex_list            - Head of the mutex list
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release all mutexes in the list
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_release_all_mutexes (
+	struct acpi_thread_state        *thread)
+{
+	union acpi_operand_object       *next = thread->acquired_mutex_list;
+	union acpi_operand_object       *this;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Traverse the list of owned mutexes, releasing each one */
+
+	while (next) {
+		this = next;
+		next = this->mutex.next;
+
+		this->mutex.acquisition_depth = 1;
+		this->mutex.prev             = NULL;
+		this->mutex.next             = NULL;
+
+		 /* Release the mutex */
+
+		status = acpi_ex_system_release_mutex (this);
+		if (ACPI_FAILURE (status)) {
+			continue;
+		}
+
+		/* Mark mutex unowned */
+
+		this->mutex.owner_thread = NULL;
+
+		/* Update Thread sync_level (Last mutex is the important one) */
+
+		thread->current_sync_level = this->mutex.original_sync_level;
+	}
+}
+
+
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
new file mode 100644
index 0000000..7911c53
--- /dev/null
+++ b/drivers/acpi/executer/exnames.c
@@ -0,0 +1,427 @@
+
+/******************************************************************************
+ *
+ * Module Name: exnames - interpreter/scanner name load/execute
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exnames")
+
+
+/* AML Package Length encodings */
+
+#define ACPI_AML_PACKAGE_TYPE1   0x40
+#define ACPI_AML_PACKAGE_TYPE2   0x4000
+#define ACPI_AML_PACKAGE_TYPE3   0x400000
+#define ACPI_AML_PACKAGE_TYPE4   0x40000000
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_allocate_name_string
+ *
+ * PARAMETERS:  prefix_count        - Count of parent levels. Special cases:
+ *                                    (-1) = root,  0 = none
+ *              num_name_segs       - count of 4-character name segments
+ *
+ * RETURN:      A pointer to the allocated string segment.  This segment must
+ *              be deleted by the caller.
+ *
+ * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
+ *              string is long enough, and set up prefix if any.
+ *
+ ******************************************************************************/
+
+char *
+acpi_ex_allocate_name_string (
+	u32                             prefix_count,
+	u32                             num_name_segs)
+{
+	char                            *temp_ptr;
+	char                            *name_string;
+	u32                              size_needed;
+
+	ACPI_FUNCTION_TRACE ("ex_allocate_name_string");
+
+
+	/*
+	 * Allow room for all \ and ^ prefixes, all segments, and a multi_name_prefix.
+	 * Also, one byte for the null terminator.
+	 * This may actually be somewhat longer than needed.
+	 */
+	if (prefix_count == ACPI_UINT32_MAX) {
+		/* Special case for root */
+
+		size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
+	}
+	else {
+		size_needed = prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
+	}
+
+	/*
+	 * Allocate a buffer for the name.
+	 * This buffer must be deleted by the caller!
+	 */
+	name_string = ACPI_MEM_ALLOCATE (size_needed);
+	if (!name_string) {
+		ACPI_REPORT_ERROR (("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
+		return_PTR (NULL);
+	}
+
+	temp_ptr = name_string;
+
+	/* Set up Root or Parent prefixes if needed */
+
+	if (prefix_count == ACPI_UINT32_MAX) {
+		*temp_ptr++ = AML_ROOT_PREFIX;
+	}
+	else {
+		while (prefix_count--) {
+			*temp_ptr++ = AML_PARENT_PREFIX;
+		}
+	}
+
+
+	/* Set up Dual or Multi prefixes if needed */
+
+	if (num_name_segs > 2) {
+		/* Set up multi prefixes   */
+
+		*temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
+		*temp_ptr++ = (char) num_name_segs;
+	}
+	else if (2 == num_name_segs) {
+		/* Set up dual prefixes */
+
+		*temp_ptr++ = AML_DUAL_NAME_PREFIX;
+	}
+
+	/*
+	 * Terminate string following prefixes. acpi_ex_name_segment() will
+	 * append the segment(s)
+	 */
+	*temp_ptr = 0;
+
+	return_PTR (name_string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_name_segment
+ *
+ * PARAMETERS:  interpreter_mode    - Current running mode (load1/Load2/Exec)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a name segment (4 bytes)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_name_segment (
+	u8                              **in_aml_address,
+	char                            *name_string)
+{
+	char                            *aml_address = (void *) *in_aml_address;
+	acpi_status                     status = AE_OK;
+	u32                             index;
+	char                            char_buf[5];
+
+
+	ACPI_FUNCTION_TRACE ("ex_name_segment");
+
+
+	/*
+	 * If first character is a digit, then we know that we aren't looking at a
+	 * valid name segment
+	 */
+	char_buf[0] = *aml_address;
+
+	if ('0' <= char_buf[0] && char_buf[0] <= '9') {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "leading digit: %c\n", char_buf[0]));
+		return_ACPI_STATUS (AE_CTRL_PENDING);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
+
+	for (index = 0;
+		(index < ACPI_NAME_SIZE) && (acpi_ut_valid_acpi_character (*aml_address));
+		index++) {
+		char_buf[index] = *aml_address++;
+		ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", char_buf[index]));
+	}
+
+
+	/* Valid name segment  */
+
+	if (index == 4) {
+		/* Found 4 valid characters */
+
+		char_buf[4] = '\0';
+
+		if (name_string) {
+			ACPI_STRCAT (name_string, char_buf);
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Appended to - %s \n", name_string));
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"No Name string - %s \n", char_buf));
+		}
+	}
+	else if (index == 0) {
+		/*
+		 * First character was not a valid name character,
+		 * so we are looking at something other than a name.
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"Leading character is not alpha: %02Xh (not a name)\n",
+			char_buf[0]));
+		status = AE_CTRL_PENDING;
+	}
+	else {
+		/* Segment started with one or more valid characters, but fewer than 4 */
+
+		status = AE_AML_BAD_NAME;
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad character %02x in name, at %p\n",
+			*aml_address, aml_address));
+	}
+
+	*in_aml_address = (u8 *) aml_address;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_get_name_string
+ *
+ * PARAMETERS:  data_type           - Data type to be associated with this name
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get a name, including any prefixes.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_get_name_string (
+	acpi_object_type                data_type,
+	u8                              *in_aml_address,
+	char                            **out_name_string,
+	u32                             *out_name_length)
+{
+	acpi_status                     status = AE_OK;
+	u8                              *aml_address = in_aml_address;
+	char                            *name_string = NULL;
+	u32                             num_segments;
+	u32                             prefix_count = 0;
+	u8                              has_prefix = FALSE;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_get_name_string", aml_address);
+
+
+	if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type  ||
+		ACPI_TYPE_LOCAL_BANK_FIELD == data_type    ||
+		ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
+		/* Disallow prefixes for types associated with field_unit names */
+
+		name_string = acpi_ex_allocate_name_string (0, 1);
+		if (!name_string) {
+			status = AE_NO_MEMORY;
+		}
+		else {
+			status = acpi_ex_name_segment (&aml_address, name_string);
+		}
+	}
+	else {
+		/*
+		 * data_type is not a field name.
+		 * Examine first character of name for root or parent prefix operators
+		 */
+		switch (*aml_address) {
+		case AML_ROOT_PREFIX:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n", aml_address));
+
+			/*
+			 * Remember that we have a root_prefix --
+			 * see comment in acpi_ex_allocate_name_string()
+			 */
+			aml_address++;
+			prefix_count = ACPI_UINT32_MAX;
+			has_prefix = TRUE;
+			break;
+
+
+		case AML_PARENT_PREFIX:
+
+			/* Increment past possibly multiple parent prefixes */
+
+			do {
+				ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n", aml_address));
+
+				aml_address++;
+				prefix_count++;
+
+			} while (*aml_address == AML_PARENT_PREFIX);
+
+			has_prefix = TRUE;
+			break;
+
+
+		default:
+
+			/* Not a prefix character */
+
+			break;
+		}
+
+
+		/* Examine first character of name for name segment prefix operator */
+
+		switch (*aml_address) {
+		case AML_DUAL_NAME_PREFIX:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n", aml_address));
+
+			aml_address++;
+			name_string = acpi_ex_allocate_name_string (prefix_count, 2);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			/* Indicate that we processed a prefix */
+
+			has_prefix = TRUE;
+
+			status = acpi_ex_name_segment (&aml_address, name_string);
+			if (ACPI_SUCCESS (status)) {
+				status = acpi_ex_name_segment (&aml_address, name_string);
+			}
+			break;
+
+
+		case AML_MULTI_NAME_PREFIX_OP:
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n", aml_address));
+
+			/* Fetch count of segments remaining in name path */
+
+			aml_address++;
+			num_segments = *aml_address;
+
+			name_string = acpi_ex_allocate_name_string (prefix_count, num_segments);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			/* Indicate that we processed a prefix */
+
+			aml_address++;
+			has_prefix = TRUE;
+
+			while (num_segments &&
+					(status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
+				num_segments--;
+			}
+
+			break;
+
+
+		case 0:
+
+			/* null_name valid as of 8-12-98 ASL/AML Grammar Update */
+
+			if (prefix_count == ACPI_UINT32_MAX) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "name_seg is \"\\\" followed by NULL\n"));
+			}
+
+			/* Consume the NULL byte */
+
+			aml_address++;
+			name_string = acpi_ex_allocate_name_string (prefix_count, 0);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			break;
+
+
+		default:
+
+			/* Name segment string */
+
+			name_string = acpi_ex_allocate_name_string (prefix_count, 1);
+			if (!name_string) {
+				status = AE_NO_MEMORY;
+				break;
+			}
+
+			status = acpi_ex_name_segment (&aml_address, name_string);
+			break;
+		}
+	}
+
+	if (AE_CTRL_PENDING == status && has_prefix) {
+		/* Ran out of segments after processing a prefix */
+
+		ACPI_REPORT_ERROR (
+			("ex_do_name: Malformed Name at %p\n", name_string));
+		status = AE_AML_BAD_NAME;
+	}
+
+	*out_name_string = name_string;
+	*out_name_length = (u32) (aml_address - in_aml_address);
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
new file mode 100644
index 0000000..8482aef
--- /dev/null
+++ b/drivers/acpi/executer/exoparg1.c
@@ -0,0 +1,1013 @@
+
+/******************************************************************************
+ *
+ * Module Name: exoparg1 - AML execution - opcodes with 1 argument
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exoparg1")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ *      AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS:    The number of arguments (input operands) that are
+ *                    required for this opcode type (0 through 6 args).
+ * yT - TARGETS:      The number of targets (output operands) that are required
+ *                    for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ *                    as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_0A_0T_1R
+ *
+ * PARAMETERS:  walk_state          - Current state (contains AML opcode)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute operator with no operands, one return value
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_0A_0T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *return_desc = NULL;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/* Examine the AML opcode */
+
+	switch (walk_state->opcode) {
+	case AML_TIMER_OP:      /*  Timer () */
+
+		/* Create a return object of type Integer */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		return_desc->integer.value = acpi_os_get_timer ();
+		break;
+
+	default:                /*  Unknown opcode  */
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n",
+			walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		break;
+	}
+
+cleanup:
+
+	if (!walk_state->result_obj) {
+		walk_state->result_obj = return_desc;
+	}
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (return_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_1A_0T_0R
+ *
+ * PARAMETERS:  walk_state          - Current state (contains AML opcode)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
+ *              object stack
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_1A_0T_0R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/* Examine the AML opcode */
+
+	switch (walk_state->opcode) {
+	case AML_RELEASE_OP:    /*  Release (mutex_object) */
+
+		status = acpi_ex_release_mutex (operand[0], walk_state);
+		break;
+
+
+	case AML_RESET_OP:      /*  Reset (event_object) */
+
+		status = acpi_ex_system_reset_event (operand[0]);
+		break;
+
+
+	case AML_SIGNAL_OP:     /*  Signal (event_object) */
+
+		status = acpi_ex_system_signal_event (operand[0]);
+		break;
+
+
+	case AML_SLEEP_OP:      /*  Sleep (msec_time) */
+
+		status = acpi_ex_system_do_suspend (operand[0]->integer.value);
+		break;
+
+
+	case AML_STALL_OP:      /*  Stall (usec_time) */
+
+		status = acpi_ex_system_do_stall ((u32) operand[0]->integer.value);
+		break;
+
+
+	case AML_UNLOAD_OP:     /*  Unload (Handle) */
+
+		status = acpi_ex_unload_table (operand[0]);
+		break;
+
+
+	default:                /*  Unknown opcode  */
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n",
+			walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_1A_1T_0R
+ *
+ * PARAMETERS:  walk_state          - Current state (contains AML opcode)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute opcode with one argument, one target, and no
+ *              return value.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_1A_1T_0R (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/* Examine the AML opcode */
+
+	switch (walk_state->opcode) {
+	case AML_LOAD_OP:
+
+		status = acpi_ex_load_op (operand[0], operand[1], walk_state);
+		break;
+
+	default:                        /* Unknown opcode */
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n",
+			walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+cleanup:
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_1A_1T_1R
+ *
+ * PARAMETERS:  walk_state          - Current state (contains AML opcode)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute opcode with one argument, one target, and a
+ *              return value.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_1A_1T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *return_desc = NULL;
+	union acpi_operand_object       *return_desc2 = NULL;
+	u32                             temp32;
+	u32                             i;
+	acpi_integer                    power_of_ten;
+	acpi_integer                    digit;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/* Examine the AML opcode */
+
+	switch (walk_state->opcode) {
+	case AML_BIT_NOT_OP:
+	case AML_FIND_SET_LEFT_BIT_OP:
+	case AML_FIND_SET_RIGHT_BIT_OP:
+	case AML_FROM_BCD_OP:
+	case AML_TO_BCD_OP:
+	case AML_COND_REF_OF_OP:
+
+		/* Create a return object of type Integer for these opcodes */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		switch (walk_state->opcode) {
+		case AML_BIT_NOT_OP:            /* Not (Operand, Result)  */
+
+			return_desc->integer.value = ~operand[0]->integer.value;
+			break;
+
+
+		case AML_FIND_SET_LEFT_BIT_OP:  /* find_set_left_bit (Operand, Result) */
+
+			return_desc->integer.value = operand[0]->integer.value;
+
+			/*
+			 * Acpi specification describes Integer type as a little
+			 * endian unsigned value, so this boundary condition is valid.
+			 */
+			for (temp32 = 0; return_desc->integer.value &&
+					   temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
+				return_desc->integer.value >>= 1;
+			}
+
+			return_desc->integer.value = temp32;
+			break;
+
+
+		case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
+
+			return_desc->integer.value = operand[0]->integer.value;
+
+			/*
+			 * The Acpi specification describes Integer type as a little
+			 * endian unsigned value, so this boundary condition is valid.
+			 */
+			for (temp32 = 0; return_desc->integer.value &&
+					   temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
+				return_desc->integer.value <<= 1;
+			}
+
+			/* Since the bit position is one-based, subtract from 33 (65) */
+
+			return_desc->integer.value = temp32 == 0 ? 0 :
+					  (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
+			break;
+
+
+		case AML_FROM_BCD_OP:           /* from_bcd (BCDValue, Result) */
+
+			/*
+			 * The 64-bit ACPI integer can hold 16 4-bit BCD characters
+			 * (if table is 32-bit, integer can hold 8 BCD characters)
+			 * Convert each 4-bit BCD value
+			 */
+			power_of_ten = 1;
+			return_desc->integer.value = 0;
+			digit = operand[0]->integer.value;
+
+			/* Convert each BCD digit (each is one nybble wide) */
+
+			for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
+				/* Get the least significant 4-bit BCD digit */
+
+				temp32 = ((u32) digit) & 0xF;
+
+				/* Check the range of the digit */
+
+				if (temp32 > 9) {
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"BCD digit too large (not decimal): 0x%X\n",
+						temp32));
+
+					status = AE_AML_NUMERIC_OVERFLOW;
+					goto cleanup;
+				}
+
+				/* Sum the digit into the result with the current power of 10 */
+
+				return_desc->integer.value += (((acpi_integer) temp32) *
+						 power_of_ten);
+
+				/* Shift to next BCD digit */
+
+				digit >>= 4;
+
+				/* Next power of 10 */
+
+				power_of_ten *= 10;
+			}
+			break;
+
+
+		case AML_TO_BCD_OP:             /* to_bcd (Operand, Result) */
+
+			return_desc->integer.value = 0;
+			digit = operand[0]->integer.value;
+
+			/* Each BCD digit is one nybble wide */
+
+			for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
+				(void) acpi_ut_short_divide (digit, 10, &digit, &temp32);
+
+				/* Insert the BCD digit that resides in the remainder from above */
+
+				return_desc->integer.value |= (((acpi_integer) temp32) <<
+						   ACPI_MUL_4 (i));
+			}
+
+			/* Overflow if there is any data left in Digit */
+
+			if (digit > 0) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Integer too large to convert to BCD: %8.8X%8.8X\n",
+					ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
+				status = AE_AML_NUMERIC_OVERFLOW;
+				goto cleanup;
+			}
+			break;
+
+
+		case AML_COND_REF_OF_OP:        /* cond_ref_of (source_object, Result) */
+
+			/*
+			 * This op is a little strange because the internal return value is
+			 * different than the return value stored in the result descriptor
+			 * (There are really two return values)
+			 */
+			if ((struct acpi_namespace_node *) operand[0] == acpi_gbl_root_node) {
+				/*
+				 * This means that the object does not exist in the namespace,
+				 * return FALSE
+				 */
+				return_desc->integer.value = 0;
+				goto cleanup;
+			}
+
+			/* Get the object reference, store it, and remove our reference */
+
+			status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
+			if (ACPI_FAILURE (status)) {
+				goto cleanup;
+			}
+
+			status = acpi_ex_store (return_desc2, operand[1], walk_state);
+			acpi_ut_remove_reference (return_desc2);
+
+			/* The object exists in the namespace, return TRUE */
+
+			return_desc->integer.value = ACPI_INTEGER_MAX;
+			goto cleanup;
+
+
+		default:
+			/* No other opcodes get here */
+			break;
+		}
+		break;
+
+
+	case AML_STORE_OP:              /* Store (Source, Target) */
+
+		/*
+		 * A store operand is typically a number, string, buffer or lvalue
+		 * Be careful about deleting the source object,
+		 * since the object itself may have been stored.
+		 */
+		status = acpi_ex_store (operand[0], operand[1], walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* It is possible that the Store already produced a return object */
+
+		if (!walk_state->result_obj) {
+			/*
+			 * Normally, we would remove a reference on the Operand[0] parameter;
+			 * But since it is being used as the internal return object
+			 * (meaning we would normally increment it), the two cancel out,
+			 * and we simply don't do anything.
+			 */
+			walk_state->result_obj = operand[0];
+			walk_state->operands[0] = NULL; /* Prevent deletion */
+		}
+		return_ACPI_STATUS (status);
+
+
+	/*
+	 * ACPI 2.0 Opcodes
+	 */
+	case AML_COPY_OP:               /* Copy (Source, Target) */
+
+		status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc,
+				 walk_state);
+		break;
+
+
+	case AML_TO_DECSTRING_OP:       /* to_decimal_string (Data, Result) */
+
+		status = acpi_ex_convert_to_string (operand[0], &return_desc,
+				 ACPI_EXPLICIT_CONVERT_DECIMAL);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
+		break;
+
+
+	case AML_TO_HEXSTRING_OP:       /* to_hex_string (Data, Result) */
+
+		status = acpi_ex_convert_to_string (operand[0], &return_desc,
+				 ACPI_EXPLICIT_CONVERT_HEX);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
+		break;
+
+
+	case AML_TO_BUFFER_OP:          /* to_buffer (Data, Result) */
+
+		status = acpi_ex_convert_to_buffer (operand[0], &return_desc);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
+		break;
+
+
+	case AML_TO_INTEGER_OP:         /* to_integer (Data, Result) */
+
+		status = acpi_ex_convert_to_integer (operand[0], &return_desc,
+				 ACPI_ANY_BASE);
+		if (return_desc == operand[0]) {
+			/* No conversion performed, add ref to handle return value */
+			acpi_ut_add_reference (return_desc);
+		}
+		break;
+
+
+	case AML_SHIFT_LEFT_BIT_OP:     /* shift_left_bit (Source, bit_num) */
+	case AML_SHIFT_RIGHT_BIT_OP:    /* shift_right_bit (Source, bit_num) */
+
+		/*
+		 * These are two obsolete opcodes
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"%s is obsolete and not implemented\n",
+			acpi_ps_get_opcode_name (walk_state->opcode)));
+		status = AE_SUPPORT;
+		goto cleanup;
+
+
+	default:                        /* Unknown opcode */
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n",
+			walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+	if (ACPI_SUCCESS (status)) {
+		/*
+		 * Store the return value computed above into the target object
+		 */
+		status = acpi_ex_store (return_desc, operand[1], walk_state);
+	}
+
+
+cleanup:
+
+	if (!walk_state->result_obj) {
+		walk_state->result_obj = return_desc;
+	}
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (return_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_1A_0T_1R
+ *
+ * PARAMETERS:  walk_state          - Current state (contains AML opcode)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute opcode with one argument, no target, and a return value
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_1A_0T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *temp_desc;
+	union acpi_operand_object       *return_desc = NULL;
+	acpi_status                     status = AE_OK;
+	u32                             type;
+	acpi_integer                    value;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/* Examine the AML opcode */
+
+	switch (walk_state->opcode) {
+	case AML_LNOT_OP:               /* LNot (Operand) */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		/*
+		 * Set result to ONES (TRUE) if Value == 0.  Note:
+		 * return_desc->Integer.Value is initially == 0 (FALSE) from above.
+		 */
+		if (!operand[0]->integer.value) {
+			return_desc->integer.value = ACPI_INTEGER_MAX;
+		}
+		break;
+
+
+	case AML_DECREMENT_OP:          /* Decrement (Operand)  */
+	case AML_INCREMENT_OP:          /* Increment (Operand)  */
+
+		/*
+		 * Create a new integer.  Can't just get the base integer and
+		 * increment it because it may be an Arg or Field.
+		 */
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		/*
+		 * Since we are expecting a Reference operand, it can be either a
+		 * NS Node or an internal object.
+		 */
+		temp_desc = operand[0];
+		if (ACPI_GET_DESCRIPTOR_TYPE (temp_desc) == ACPI_DESC_TYPE_OPERAND) {
+			/* Internal reference object - prevent deletion */
+
+			acpi_ut_add_reference (temp_desc);
+		}
+
+		/*
+		 * Convert the Reference operand to an Integer (This removes a
+		 * reference on the Operand[0] object)
+		 *
+		 * NOTE:  We use LNOT_OP here in order to force resolution of the
+		 * reference operand to an actual integer.
+		 */
+		status = acpi_ex_resolve_operands (AML_LNOT_OP, &temp_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s: bad operand(s) %s\n",
+				acpi_ps_get_opcode_name (walk_state->opcode),
+				acpi_format_exception(status)));
+
+			goto cleanup;
+		}
+
+		/*
+		 * temp_desc is now guaranteed to be an Integer object --
+		 * Perform the actual increment or decrement
+		 */
+		if (walk_state->opcode == AML_INCREMENT_OP) {
+			return_desc->integer.value = temp_desc->integer.value +1;
+		}
+		else {
+			return_desc->integer.value = temp_desc->integer.value -1;
+		}
+
+		/* Finished with this Integer object */
+
+		acpi_ut_remove_reference (temp_desc);
+
+		/*
+		 * Store the result back (indirectly) through the original
+		 * Reference object
+		 */
+		status = acpi_ex_store (return_desc, operand[0], walk_state);
+		break;
+
+
+	case AML_TYPE_OP:               /* object_type (source_object) */
+
+		/*
+		 * Note: The operand is not resolved at this point because we want to
+		 * get the associated object, not its value.  For example, we don't want
+		 * to resolve a field_unit to its value, we want the actual field_unit
+		 * object.
+		 */
+
+		/* Get the type of the base object */
+
+		status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+		/* Allocate a descriptor to hold the type. */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		return_desc->integer.value = type;
+		break;
+
+
+	case AML_SIZE_OF_OP:            /* size_of (source_object) */
+
+		/*
+		 * Note: The operand is not resolved at this point because we want to
+		 * get the associated object, not its value.
+		 */
+
+		/* Get the base object */
+
+		status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		/*
+		 * The type of the base object must be integer, buffer, string, or
+		 * package.  All others are not supported.
+		 *
+		 * NOTE: Integer is not specifically supported by the ACPI spec,
+		 * but is supported implicitly via implicit operand conversion.
+		 * rather than bother with conversion, we just use the byte width
+		 * global (4 or 8 bytes).
+		 */
+		switch (type) {
+		case ACPI_TYPE_INTEGER:
+			value = acpi_gbl_integer_byte_width;
+			break;
+
+		case ACPI_TYPE_BUFFER:
+			value = temp_desc->buffer.length;
+			break;
+
+		case ACPI_TYPE_STRING:
+			value = temp_desc->string.length;
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+			value = temp_desc->package.count;
+			break;
+
+		default:
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n",
+				acpi_ut_get_type_name (type)));
+			status = AE_AML_OPERAND_TYPE;
+			goto cleanup;
+		}
+
+		/*
+		 * Now that we have the size of the object, create a result
+		 * object to hold the value
+		 */
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		return_desc->integer.value = value;
+		break;
+
+
+	case AML_REF_OF_OP:             /* ref_of (source_object) */
+
+		status = acpi_ex_get_object_reference (operand[0], &return_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+		break;
+
+
+	case AML_DEREF_OF_OP:           /* deref_of (obj_reference | String) */
+
+		/* Check for a method local or argument, or standalone String */
+
+		if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) != ACPI_DESC_TYPE_NAMED) {
+			switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
+			case ACPI_TYPE_LOCAL_REFERENCE:
+				/*
+				 * This is a deref_of (local_x | arg_x)
+				 *
+				 * Must resolve/dereference the local/arg reference first
+				 */
+				switch (operand[0]->reference.opcode) {
+				case AML_LOCAL_OP:
+				case AML_ARG_OP:
+
+					/* Set Operand[0] to the value of the local/arg */
+
+					status = acpi_ds_method_data_get_value (operand[0]->reference.opcode,
+							 operand[0]->reference.offset, walk_state, &temp_desc);
+					if (ACPI_FAILURE (status)) {
+						goto cleanup;
+					}
+
+					/*
+					 * Delete our reference to the input object and
+					 * point to the object just retrieved
+					 */
+					acpi_ut_remove_reference (operand[0]);
+					operand[0] = temp_desc;
+					break;
+
+				case AML_REF_OF_OP:
+
+					/* Get the object to which the reference refers */
+
+					temp_desc = operand[0]->reference.object;
+					acpi_ut_remove_reference (operand[0]);
+					operand[0] = temp_desc;
+					break;
+
+				default:
+
+					/* Must be an Index op - handled below */
+					break;
+				}
+				break;
+
+
+			case ACPI_TYPE_STRING:
+
+				/*
+				 * This is a deref_of (String). The string is a reference to a named ACPI object.
+				 *
+				 * 1) Find the owning Node
+				 * 2) Dereference the node to an actual object.  Could be a Field, so we nee
+				 *    to resolve the node to a value.
+				 */
+				status = acpi_ns_get_node_by_path (operand[0]->string.pointer,
+						  walk_state->scope_info->scope.node, ACPI_NS_SEARCH_PARENT,
+						  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc));
+				if (ACPI_FAILURE (status)) {
+					goto cleanup;
+				}
+
+				status = acpi_ex_resolve_node_to_value (
+						  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc), walk_state);
+				goto cleanup;
+
+
+			default:
+
+				status = AE_AML_OPERAND_TYPE;
+				goto cleanup;
+			}
+		}
+
+		/* Operand[0] may have changed from the code above */
+
+		if (ACPI_GET_DESCRIPTOR_TYPE (operand[0]) == ACPI_DESC_TYPE_NAMED) {
+			/*
+			 * This is a deref_of (object_reference)
+			 * Get the actual object from the Node (This is the dereference).
+			 * -- This case may only happen when a local_x or arg_x is dereferenced above.
+			 */
+			return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) operand[0]);
+		}
+		else {
+			/*
+			 * This must be a reference object produced by either the Index() or
+			 * ref_of() operator
+			 */
+			switch (operand[0]->reference.opcode) {
+			case AML_INDEX_OP:
+
+				/*
+				 * The target type for the Index operator must be
+				 * either a Buffer or a Package
+				 */
+				switch (operand[0]->reference.target_type) {
+				case ACPI_TYPE_BUFFER_FIELD:
+
+					temp_desc = operand[0]->reference.object;
+
+					/*
+					 * Create a new object that contains one element of the
+					 * buffer -- the element pointed to by the index.
+					 *
+					 * NOTE: index into a buffer is NOT a pointer to a
+					 * sub-buffer of the main buffer, it is only a pointer to a
+					 * single element (byte) of the buffer!
+					 */
+					return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+					if (!return_desc) {
+						status = AE_NO_MEMORY;
+						goto cleanup;
+					}
+
+					/*
+					 * Since we are returning the value of the buffer at the
+					 * indexed location, we don't need to add an additional
+					 * reference to the buffer itself.
+					 */
+					return_desc->integer.value =
+						temp_desc->buffer.pointer[operand[0]->reference.offset];
+					break;
+
+
+				case ACPI_TYPE_PACKAGE:
+
+					/*
+					 * Return the referenced element of the package.  We must add
+					 * another reference to the referenced object, however.
+					 */
+					return_desc = *(operand[0]->reference.where);
+					if (!return_desc) {
+						/*
+						 * We can't return a NULL dereferenced value.  This is
+						 * an uninitialized package element and is thus a
+						 * severe error.
+						 */
+						ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+							"NULL package element obj %p\n",
+							operand[0]));
+						status = AE_AML_UNINITIALIZED_ELEMENT;
+						goto cleanup;
+					}
+
+					acpi_ut_add_reference (return_desc);
+					break;
+
+
+				default:
+
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"Unknown Index target_type %X in obj %p\n",
+						operand[0]->reference.target_type, operand[0]));
+					status = AE_AML_OPERAND_TYPE;
+					goto cleanup;
+				}
+				break;
+
+
+			case AML_REF_OF_OP:
+
+				return_desc = operand[0]->reference.object;
+
+				if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) == ACPI_DESC_TYPE_NAMED) {
+
+					return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) return_desc);
+				}
+
+				/* Add another reference to the object! */
+
+				acpi_ut_add_reference (return_desc);
+				break;
+
+
+			default:
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Unknown opcode in ref(%p) - %X\n",
+					operand[0], operand[0]->reference.opcode));
+
+				status = AE_TYPE;
+				goto cleanup;
+			}
+		}
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n",
+			walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+cleanup:
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (return_desc);
+	}
+
+	walk_state->result_obj = return_desc;
+	return_ACPI_STATUS (status);
+}
+
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
new file mode 100644
index 0000000..8be4d80
--- /dev/null
+++ b/drivers/acpi/executer/exoparg2.c
@@ -0,0 +1,608 @@
+/******************************************************************************
+ *
+ * Module Name: exoparg2 - AML execution - opcodes with 2 arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acinterp.h>
+#include <acpi/acevents.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exoparg2")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ *      AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS:    The number of arguments (input operands) that are
+ *                    required for this opcode type (1 through 6 args).
+ * yT - TARGETS:      The number of targets (output operands) that are required
+ *                    for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ *                    as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_2A_0T_0R
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute opcode with two arguments, no target, and no return
+ *              value.
+ *
+ * ALLOCATION:  Deletes both operands
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_2A_0T_0R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	struct acpi_namespace_node      *node;
+	u32                             value;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_0R",
+			acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/* Examine the opcode */
+
+	switch (walk_state->opcode) {
+	case AML_NOTIFY_OP:         /* Notify (notify_object, notify_value) */
+
+		/* The first operand is a namespace node */
+
+		node = (struct acpi_namespace_node *) operand[0];
+
+		/* Second value is the notify value */
+
+		value = (u32) operand[1]->integer.value;
+
+		/* Notifies allowed on this object? */
+
+		if (!acpi_ev_is_notify_object (node)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Unexpected notify object type [%s]\n",
+					acpi_ut_get_type_name (node->type)));
+
+			status = AE_AML_OPERAND_TYPE;
+			break;
+		}
+
+#ifdef ACPI_GPE_NOTIFY_CHECK
+		/*
+		 * GPE method wake/notify check.  Here, we want to ensure that we
+		 * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx
+		 * GPE method during system runtime.  If we do, the GPE is marked
+		 * as "wake-only" and disabled.
+		 *
+		 * 1) Is the Notify() value == device_wake?
+		 * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
+		 * 3) Did the original GPE happen at system runtime?
+		 *    (versus during wake)
+		 *
+		 * If all three cases are true, this is a wake-only GPE that should
+		 * be disabled at runtime.
+		 */
+		if (value == 2)     /* device_wake */ {
+			status = acpi_ev_check_for_wake_only_gpe (walk_state->gpe_event_info);
+			if (ACPI_FAILURE (status)) {
+				/* AE_WAKE_ONLY_GPE only error, means ignore this notify */
+
+				return_ACPI_STATUS (AE_OK)
+			}
+		}
+#endif
+
+		/*
+		 * Dispatch the notify to the appropriate handler
+		 * NOTE: the request is queued for execution after this method
+		 * completes.  The notify handlers are NOT invoked synchronously
+		 * from this thread -- because handlers may in turn run other
+		 * control methods.
+		 */
+		status = acpi_ev_queue_notify_request (node, value);
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n",
+				walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_2A_2T_1R
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets
+ *              and one implicit return value.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_2A_2T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *return_desc1 = NULL;
+	union acpi_operand_object       *return_desc2 = NULL;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/*
+	 * Execute the opcode
+	 */
+	switch (walk_state->opcode) {
+	case AML_DIVIDE_OP:             /* Divide (Dividend, Divisor, remainder_result quotient_result) */
+
+		return_desc1 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc1) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		return_desc2 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc2) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		/* Quotient to return_desc1, remainder to return_desc2 */
+
+		status = acpi_ut_divide (operand[0]->integer.value,
+				   operand[1]->integer.value,
+				   &return_desc1->integer.value,
+				   &return_desc2->integer.value);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n",
+				walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+	/* Store the results to the target reference operands */
+
+	status = acpi_ex_store (return_desc2, operand[2], walk_state);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	status = acpi_ex_store (return_desc1, operand[3], walk_state);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Return the remainder */
+
+	walk_state->result_obj = return_desc1;
+
+
+cleanup:
+	/*
+	 * Since the remainder is not returned indirectly, remove a reference to
+	 * it. Only the quotient is returned indirectly.
+	 */
+	acpi_ut_remove_reference (return_desc2);
+
+	if (ACPI_FAILURE (status)) {
+		/* Delete the return object */
+
+		acpi_ut_remove_reference (return_desc1);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_2A_1T_1R
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute opcode with two arguments, one target, and a return
+ *              value.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_2A_1T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *return_desc = NULL;
+	u32                             index;
+	acpi_status                     status = AE_OK;
+	acpi_size                       length;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/*
+	 * Execute the opcode
+	 */
+	if (walk_state->op_info->flags & AML_MATH) {
+		/* All simple math opcodes (add, etc.) */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		return_desc->integer.value = acpi_ex_do_math_op (walk_state->opcode,
+				  operand[0]->integer.value,
+				  operand[1]->integer.value);
+		goto store_result_to_target;
+	}
+
+
+	switch (walk_state->opcode) {
+	case AML_MOD_OP:                /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		/* return_desc will contain the remainder */
+
+		status = acpi_ut_divide (operand[0]->integer.value,
+				   operand[1]->integer.value,
+				   NULL,
+				   &return_desc->integer.value);
+		break;
+
+
+	case AML_CONCAT_OP:             /* Concatenate (Data1, Data2, Result) */
+
+		status = acpi_ex_do_concatenate (operand[0], operand[1],
+				 &return_desc, walk_state);
+		break;
+
+
+	case AML_TO_STRING_OP:          /* to_string (Buffer, Length, Result) (ACPI 2.0) */
+
+		/*
+		 * Input object is guaranteed to be a buffer at this point (it may have
+		 * been converted.)  Copy the raw buffer data to a new object of type String.
+		 */
+
+		/*
+		 * Get the length of the new string. It is the smallest of:
+		 * 1) Length of the input buffer
+		 * 2) Max length as specified in the to_string operator
+		 * 3) Length of input buffer up to a zero byte (null terminator)
+		 *
+		 * NOTE: A length of zero is ok, and will create a zero-length, null
+		 *       terminated string.
+		 */
+		length = 0;
+		while ((length < operand[0]->buffer.length) &&
+			   (length < operand[1]->integer.value) &&
+			   (operand[0]->buffer.pointer[length])) {
+			length++;
+			if (length > ACPI_MAX_STRING_CONVERSION) {
+				status = AE_AML_STRING_LIMIT;
+				goto cleanup;
+			}
+		}
+
+		/* Allocate a new string object */
+
+		return_desc = acpi_ut_create_string_object (length);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		/* Copy the raw buffer data with no transform. NULL terminated already. */
+
+		ACPI_MEMCPY (return_desc->string.pointer,
+			operand[0]->buffer.pointer, length);
+		break;
+
+
+	case AML_CONCAT_RES_OP:         /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
+
+		status = acpi_ex_concat_template (operand[0], operand[1],
+				 &return_desc, walk_state);
+		break;
+
+
+	case AML_INDEX_OP:              /* Index (Source Index Result) */
+
+		/* Create the internal return object */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_REFERENCE);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		index = (u32) operand[1]->integer.value;
+
+		/*
+		 * At this point, the Source operand is a Package, Buffer, or String
+		 */
+		if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) {
+			/* Object to be indexed is a Package */
+
+			if (index >= operand[0]->package.count) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Index value (%X) beyond package end (%X)\n",
+					index, operand[0]->package.count));
+				status = AE_AML_PACKAGE_LIMIT;
+				goto cleanup;
+			}
+
+			return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
+			return_desc->reference.object    = operand[0];
+			return_desc->reference.where     = &operand[0]->package.elements [index];
+		}
+		else {
+			/* Object to be indexed is a Buffer/String */
+
+			if (index >= operand[0]->buffer.length) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Index value (%X) beyond end of buffer (%X)\n",
+					index, operand[0]->buffer.length));
+				status = AE_AML_BUFFER_LIMIT;
+				goto cleanup;
+			}
+
+			return_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD;
+			return_desc->reference.object    = operand[0];
+		}
+
+		/*
+		 * Add a reference to the target package/buffer/string for the life
+		 * of the index.
+		 */
+		acpi_ut_add_reference (operand[0]);
+
+		/* Complete the Index reference object */
+
+		return_desc->reference.opcode    = AML_INDEX_OP;
+		return_desc->reference.offset    = index;
+
+		/* Store the reference to the Target */
+
+		status = acpi_ex_store (return_desc, operand[2], walk_state);
+
+		/* Return the reference */
+
+		walk_state->result_obj = return_desc;
+		goto cleanup;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n",
+				walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		break;
+	}
+
+
+store_result_to_target:
+
+	if (ACPI_SUCCESS (status)) {
+		/*
+		 * Store the result of the operation (which is now in return_desc) into
+		 * the Target descriptor.
+		 */
+		status = acpi_ex_store (return_desc, operand[2], walk_state);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		if (!walk_state->result_obj) {
+			walk_state->result_obj = return_desc;
+		}
+	}
+
+
+cleanup:
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (return_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_2A_0T_1R
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_2A_0T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *return_desc = NULL;
+	acpi_status                     status = AE_OK;
+	u8                              logical_result = FALSE;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	/* Create the internal return object */
+
+	return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!return_desc) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/*
+	 * Execute the Opcode
+	 */
+	if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) /* logical_op (Operand0, Operand1) */ {
+		status = acpi_ex_do_logical_numeric_op (walk_state->opcode,
+				  operand[0]->integer.value, operand[1]->integer.value,
+				  &logical_result);
+		goto store_logical_result;
+	}
+	else if (walk_state->op_info->flags & AML_LOGICAL)  /* logical_op (Operand0, Operand1) */ {
+		status = acpi_ex_do_logical_op (walk_state->opcode, operand[0],
+				 operand[1], &logical_result);
+		goto store_logical_result;
+	}
+
+
+	switch (walk_state->opcode) {
+	case AML_ACQUIRE_OP:            /* Acquire (mutex_object, Timeout) */
+
+		status = acpi_ex_acquire_mutex (operand[1], operand[0], walk_state);
+		if (status == AE_TIME) {
+			logical_result = TRUE;      /* TRUE = Acquire timed out */
+			status = AE_OK;
+		}
+		break;
+
+
+	case AML_WAIT_OP:               /* Wait (event_object, Timeout) */
+
+		status = acpi_ex_system_wait_event (operand[1], operand[0]);
+		if (status == AE_TIME) {
+			logical_result = TRUE;      /* TRUE, Wait timed out */
+			status = AE_OK;
+		}
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n",
+			walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+store_logical_result:
+	/*
+	 * Set return value to according to logical_result. logical TRUE (all ones)
+	 * Default is FALSE (zero)
+	 */
+	if (logical_result) {
+		return_desc->integer.value = ACPI_INTEGER_MAX;
+	}
+
+	walk_state->result_obj = return_desc;
+
+
+cleanup:
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (return_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
new file mode 100644
index 0000000..29d0b16
--- /dev/null
+++ b/drivers/acpi/executer/exoparg3.c
@@ -0,0 +1,256 @@
+
+/******************************************************************************
+ *
+ * Module Name: exoparg3 - AML execution - opcodes with 3 arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exoparg3")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ *      AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS:    The number of arguments (input operands) that are
+ *                    required for this opcode type (1 through 6 args).
+ * yT - TARGETS:      The number of targets (output operands) that are required
+ *                    for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ *                    as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_3A_0T_0R
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Triadic operator (3 operands)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_3A_0T_0R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	struct acpi_signal_fatal_info   *fatal;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	switch (walk_state->opcode) {
+	case AML_FATAL_OP:          /* Fatal (fatal_type fatal_code fatal_arg)   */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
+			(u32) operand[0]->integer.value,
+			(u32) operand[1]->integer.value,
+			(u32) operand[2]->integer.value));
+
+		fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info));
+		if (fatal) {
+			fatal->type     = (u32) operand[0]->integer.value;
+			fatal->code     = (u32) operand[1]->integer.value;
+			fatal->argument = (u32) operand[2]->integer.value;
+		}
+
+		/*
+		 * Always signal the OS!
+		 */
+		status = acpi_os_signal (ACPI_SIGNAL_FATAL, fatal);
+
+		/* Might return while OS is shutting down, just continue */
+
+		ACPI_MEM_FREE (fatal);
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
+				walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+cleanup:
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_3A_1T_1R
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute Triadic operator (3 operands)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_3A_1T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *return_desc = NULL;
+	char                            *buffer;
+	acpi_status                     status = AE_OK;
+	acpi_native_uint                index;
+	acpi_size                       length;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	switch (walk_state->opcode) {
+	case AML_MID_OP:        /* Mid  (Source[0], Index[1], Length[2], Result[3]) */
+
+		/*
+		 * 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]));
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		/* Get the Integer values from the objects */
+
+		index = (acpi_native_uint) operand[1]->integer.value;
+		length = (acpi_size) operand[2]->integer.value;
+
+		/*
+		 * If the index is beyond the length of the String/Buffer, or if the
+		 * requested length is zero, return a zero-length String/Buffer
+		 */
+		if ((index < operand[0]->string.length) &&
+			(length > 0)) {
+			/* Truncate request if larger than the actual String/Buffer */
+
+			if ((index + length) >
+				operand[0]->string.length) {
+				length = (acpi_size) operand[0]->string.length - index;
+			}
+
+			/* Allocate a new buffer for the String/Buffer */
+
+			buffer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
+			if (!buffer) {
+				status = AE_NO_MEMORY;
+				goto cleanup;
+			}
+
+			/* Copy the portion requested */
+
+			ACPI_MEMCPY (buffer, operand[0]->string.pointer + index,
+					  length);
+
+			/* Set the length of the new String/Buffer */
+
+			return_desc->string.pointer = buffer;
+			return_desc->string.length = (u32) length;
+		}
+
+		/* Mark buffer initialized */
+
+		return_desc->buffer.flags |= AOPOBJ_DATA_VALID;
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
+				walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+	/* Store the result in the target */
+
+	status = acpi_ex_store (return_desc, operand[3], walk_state);
+
+cleanup:
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (return_desc);
+	}
+
+	/* Set the return object and exit */
+
+	if (!walk_state->result_obj) {
+		walk_state->result_obj = return_desc;
+	}
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
new file mode 100644
index 0000000..d326243
--- /dev/null
+++ b/drivers/acpi/executer/exoparg6.c
@@ -0,0 +1,336 @@
+
+/******************************************************************************
+ *
+ * Module Name: exoparg6 - AML execution - opcodes with 6 arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exoparg6")
+
+
+/*!
+ * Naming convention for AML interpreter execution routines.
+ *
+ * The routines that begin execution of AML opcodes are named with a common
+ * convention based upon the number of arguments, the number of target operands,
+ * and whether or not a value is returned:
+ *
+ *      AcpiExOpcode_xA_yT_zR
+ *
+ * Where:
+ *
+ * xA - ARGUMENTS:    The number of arguments (input operands) that are
+ *                    required for this opcode type (1 through 6 args).
+ * yT - TARGETS:      The number of targets (output operands) that are required
+ *                    for this opcode type (0, 1, or 2 targets).
+ * zR - RETURN VALUE: Indicates whether this opcode type returns a value
+ *                    as the function return (0 or 1).
+ *
+ * The AcpiExOpcode* functions are called via the Dispatcher component with
+ * fully resolved operands.
+!*/
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_do_match
+ *
+ * PARAMETERS:  match_op        - The AML match operand
+ *              package_obj     - Object from the target package
+ *              match_obj       - Object to be matched
+ *
+ * RETURN:      TRUE if the match is successful, FALSE otherwise
+ *
+ * DESCRIPTION: Implements the low-level match for the ASL Match operator.
+ *              Package elements will be implicitly converted to the type of
+ *              the match object (Integer/Buffer/String).
+ *
+ ******************************************************************************/
+
+u8
+acpi_ex_do_match (
+	u32                             match_op,
+	union acpi_operand_object       *package_obj,
+	union acpi_operand_object       *match_obj)
+{
+	u8                              logical_result = TRUE;
+	acpi_status                     status;
+
+
+	/*
+	 * Note: Since the package_obj/match_obj ordering is opposite to that of
+	 * the standard logical operators, we have to reverse them when we call
+	 * do_logical_op in order to make the implicit conversion rules work
+	 * correctly. However, this means we have to flip the entire equation
+	 * also. A bit ugly perhaps, but overall, better than fussing the
+	 * parameters around at runtime, over and over again.
+	 *
+	 * Below, P[i] refers to the package element, M refers to the Match object.
+	 */
+	switch (match_op) {
+	case MATCH_MTR:
+
+		/* Always true */
+
+		break;
+
+	case MATCH_MEQ:
+
+		/*
+		 * True if equal: (P[i] == M)
+		 * Change to:     (M == P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LEQUAL_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
+			return (FALSE);
+		}
+		break;
+
+	case MATCH_MLE:
+
+		/*
+		 * True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
+		 * Change to:                  (M >= P[i]) (M not_less than P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
+			return (FALSE);
+		}
+		logical_result = (u8) !logical_result;
+		break;
+
+	case MATCH_MLT:
+
+		/*
+		 * True if less than: (P[i] < M)
+		 * Change to:         (M > P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
+			return (FALSE);
+		}
+		break;
+
+	case MATCH_MGE:
+
+		/*
+		 * True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
+		 * Change to:                     (M <= P[i]) (M not_greater than P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
+			return (FALSE);
+		}
+		logical_result = (u8)!logical_result;
+		break;
+
+	case MATCH_MGT:
+
+		/*
+		 * True if greater than: (P[i] > M)
+		 * Change to:            (M < P[i])
+		 */
+		status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+				 &logical_result);
+		if (ACPI_FAILURE (status)) {
+			return (FALSE);
+		}
+		break;
+
+	default:
+
+		/* Undefined */
+
+		return (FALSE);
+	}
+
+	return logical_result;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_opcode_6A_0T_1R
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_opcode_6A_0T_1R (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       **operand = &walk_state->operands[0];
+	union acpi_operand_object       *return_desc = NULL;
+	acpi_status                     status = AE_OK;
+	u32                             index;
+	union acpi_operand_object       *this_element;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+
+
+	switch (walk_state->opcode) {
+	case AML_MATCH_OP:
+		/*
+		 * Match (search_pkg[0], match_op1[1], match_obj1[2],
+		 *                      match_op2[3], match_obj2[4], start_index[5])
+		 */
+
+		/* Validate both Match Term Operators (MTR, MEQ, etc.) */
+
+		if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
+			(operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Match operator out of range\n"));
+			status = AE_AML_OPERAND_VALUE;
+			goto cleanup;
+		}
+
+		/* Get the package start_index, validate against the package length */
+
+		index = (u32) operand[5]->integer.value;
+		if (index >= (u32) operand[0]->package.count) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n"));
+			status = AE_AML_PACKAGE_LIMIT;
+			goto cleanup;
+		}
+
+		/* Create an integer for the return value */
+
+		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+		if (!return_desc) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+
+		}
+
+		/* Default return value if no match found */
+
+		return_desc->integer.value = ACPI_INTEGER_MAX;
+
+		/*
+		 * Examine each element until a match is found. Both match conditions
+		 * must be satisfied for a match to occur. Within the loop,
+		 * "continue" signifies that the current element does not match
+		 * and the next should be examined.
+		 *
+		 * Upon finding a match, the loop will terminate via "break" at
+		 * the bottom.  If it terminates "normally", match_value will be
+		 * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
+		 * match was found.
+		 */
+		for ( ; index < operand[0]->package.count; index++) {
+			/* Get the current package element */
+
+			this_element = operand[0]->package.elements[index];
+
+			/* Treat any uninitialized (NULL) elements as non-matching */
+
+			if (!this_element) {
+				continue;
+			}
+
+			/*
+			 * Both match conditions must be satisfied. Execution of a continue
+			 * (proceed to next iteration of enclosing for loop) signifies a
+			 * non-match.
+			 */
+			if (!acpi_ex_do_match ((u32) operand[1]->integer.value,
+					   this_element, operand[2])) {
+				continue;
+			}
+
+			if (!acpi_ex_do_match ((u32) operand[3]->integer.value,
+					   this_element, operand[4])) {
+				continue;
+			}
+
+			/* Match found: Index is the return value */
+
+			return_desc->integer.value = index;
+			break;
+		}
+		break;
+
+
+	case AML_LOAD_TABLE_OP:
+
+		status = acpi_ex_load_table_op (walk_state, &return_desc);
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
+				walk_state->opcode));
+		status = AE_AML_BAD_OPCODE;
+		goto cleanup;
+	}
+
+
+	walk_state->result_obj = return_desc;
+
+
+cleanup:
+
+	/* Delete return object on error */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_remove_reference (return_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
new file mode 100644
index 0000000..264ef3b
--- /dev/null
+++ b/drivers/acpi/executer/exprep.c
@@ -0,0 +1,530 @@
+
+/******************************************************************************
+ *
+ * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exprep")
+
+
+#ifdef ACPI_UNDER_DEVELOPMENT
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_generate_access
+ *
+ * PARAMETERS:  field_bit_offset    - Start of field within parent region/buffer
+ *              field_bit_length    - Length of field in bits
+ *              region_length       - Length of parent in bytes
+ *
+ * RETURN:      Field granularity (8, 16, 32 or 64) and
+ *              byte_alignment (1, 2, 3, or 4)
+ *
+ * DESCRIPTION: Generate an optimal access width for fields defined with the
+ *              any_acc keyword.
+ *
+ * NOTE: Need to have the region_length in order to check for boundary
+ *       conditions (end-of-region).  However, the region_length is a deferred
+ *       operation.  Therefore, to complete this implementation, the generation
+ *       of this access width must be deferred until the region length has
+ *       been evaluated.
+ *
+ ******************************************************************************/
+
+static u32
+acpi_ex_generate_access (
+	u32                             field_bit_offset,
+	u32                             field_bit_length,
+	u32                             region_length)
+{
+	u32                             field_byte_length;
+	u32                             field_byte_offset;
+	u32                             field_byte_end_offset;
+	u32                             access_byte_width;
+	u32                             field_start_offset;
+	u32                             field_end_offset;
+	u32                             minimum_access_width = 0xFFFFFFFF;
+	u32                             minimum_accesses = 0xFFFFFFFF;
+	u32                             accesses;
+
+
+	ACPI_FUNCTION_TRACE ("ex_generate_access");
+
+
+	/* Round Field start offset and length to "minimal" byte boundaries */
+
+	field_byte_offset  = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8));
+	field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8));
+	field_byte_length  = field_byte_end_offset - field_byte_offset;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+			"Bit length %d, Bit offset %d\n",
+			field_bit_length, field_bit_offset));
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+			"Byte Length %d, Byte Offset %d, End Offset %d\n",
+			field_byte_length, field_byte_offset, field_byte_end_offset));
+
+	/*
+	 * Iterative search for the maximum access width that is both aligned
+	 * and does not go beyond the end of the region
+	 *
+	 * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes)
+	 */
+	for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) {
+		/*
+		 * 1) Round end offset up to next access boundary and make sure that this
+		 *    does not go beyond the end of the parent region.
+		 * 2) When the Access width is greater than the field_byte_length, we are done.
+		 *    (This does not optimize for the perfectly aligned case yet).
+		 */
+		if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) {
+			field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
+					  access_byte_width;
+			field_end_offset = ACPI_ROUND_UP   ((field_byte_length + field_byte_offset),
+					  access_byte_width) / access_byte_width;
+			accesses         = field_end_offset - field_start_offset;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+					"access_width %d end is within region\n", access_byte_width));
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+					"Field Start %d, Field End %d -- requires %d accesses\n",
+					field_start_offset, field_end_offset, accesses));
+
+			/* Single access is optimal */
+
+			if (accesses <= 1) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+						"Entire field can be accessed with one operation of size %d\n",
+						access_byte_width));
+				return_VALUE (access_byte_width);
+			}
+
+			/*
+			 * Fits in the region, but requires more than one read/write.
+			 * try the next wider access on next iteration
+			 */
+			if (accesses < minimum_accesses) {
+				minimum_accesses   = accesses;
+				minimum_access_width = access_byte_width;
+			}
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+					"access_width %d end is NOT within region\n", access_byte_width));
+			if (access_byte_width == 1) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+						"Field goes beyond end-of-region!\n"));
+				return_VALUE (0);     /* Field does not fit in the region at all */
+			}
+
+			/* This width goes beyond the end-of-region, back off to previous access */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+					"Backing off to previous optimal access width of %d\n",
+					minimum_access_width));
+			return_VALUE (minimum_access_width);
+		}
+	}
+
+	/* Could not read/write field with one operation, just use max access width */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+			"Cannot access field in one operation, using width 8\n"));
+	return_VALUE (8);
+}
+#endif /* ACPI_UNDER_DEVELOPMENT */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_decode_field_access
+ *
+ * PARAMETERS:  Access          - Encoded field access bits
+ *              Length          - Field length.
+ *
+ * RETURN:      Field granularity (8, 16, 32 or 64) and
+ *              byte_alignment (1, 2, 3, or 4)
+ *
+ * DESCRIPTION: Decode the access_type bits of a field definition.
+ *
+ ******************************************************************************/
+
+static u32
+acpi_ex_decode_field_access (
+	union acpi_operand_object       *obj_desc,
+	u8                              field_flags,
+	u32                             *return_byte_alignment)
+{
+	u32                             access;
+	u32                             byte_alignment;
+	u32                             bit_length;
+
+
+	ACPI_FUNCTION_TRACE ("ex_decode_field_access");
+
+
+	access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK);
+
+	switch (access) {
+	case AML_FIELD_ACCESS_ANY:
+
+#ifdef ACPI_UNDER_DEVELOPMENT
+		byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
+				 obj_desc->common_field.bit_length,
+				 0xFFFFFFFF /* Temp until we pass region_length as param */);
+		bit_length = byte_alignment * 8;
+#endif
+
+		byte_alignment = 1;
+		bit_length = 8;
+		break;
+
+	case AML_FIELD_ACCESS_BYTE:
+	case AML_FIELD_ACCESS_BUFFER:   /* ACPI 2.0 (SMBus Buffer) */
+		byte_alignment = 1;
+		bit_length    = 8;
+		break;
+
+	case AML_FIELD_ACCESS_WORD:
+		byte_alignment = 2;
+		bit_length    = 16;
+		break;
+
+	case AML_FIELD_ACCESS_DWORD:
+		byte_alignment = 4;
+		bit_length    = 32;
+		break;
+
+	case AML_FIELD_ACCESS_QWORD:    /* ACPI 2.0 */
+		byte_alignment = 8;
+		bit_length    = 64;
+		break;
+
+	default:
+		/* Invalid field access type */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown field access type %X\n",
+			access));
+		return_VALUE (0);
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == 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
+		 * implied by the field access type.
+		 */
+		byte_alignment = 1;
+	}
+
+	*return_byte_alignment = byte_alignment;
+	return_VALUE (bit_length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_prep_common_field_object
+ *
+ * PARAMETERS:  obj_desc            - The field object
+ *              field_flags         - Access, lock_rule, and update_rule.
+ *                                    The format of a field_flag is described
+ *                                    in the ACPI specification
+ *              field_bit_position  - Field start position
+ *              field_bit_length    - Field length in number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the areas of the field object that are common
+ *              to the various types of fields.  Note: This is very "sensitive"
+ *              code because we are solving the general case for field
+ *              alignment.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_prep_common_field_object (
+	union acpi_operand_object       *obj_desc,
+	u8                              field_flags,
+	u8                              field_attribute,
+	u32                             field_bit_position,
+	u32                             field_bit_length)
+{
+	u32                             access_bit_width;
+	u32                             byte_alignment;
+	u32                             nearest_byte_address;
+
+
+	ACPI_FUNCTION_TRACE ("ex_prep_common_field_object");
+
+
+	/*
+	 * Note: the structure being initialized is the
+	 * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common
+	 * area are initialized by this procedure.
+	 */
+	obj_desc->common_field.field_flags = field_flags;
+	obj_desc->common_field.attribute = field_attribute;
+	obj_desc->common_field.bit_length = field_bit_length;
+
+	/*
+	 * Decode the access type so we can compute offsets.  The access type gives
+	 * two pieces of information - the width of each field access and the
+	 * necessary byte_alignment (address granularity) of the access.
+	 *
+	 * For any_acc, the access_bit_width is the largest width that is both
+	 * necessary and possible in an attempt to access the whole field in one
+	 * I/O operation.  However, for any_acc, the byte_alignment is always one
+	 * byte.
+	 *
+	 * For all Buffer Fields, the byte_alignment is always one byte.
+	 *
+	 * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
+	 * the same (equivalent) as the byte_alignment.
+	 */
+	access_bit_width = acpi_ex_decode_field_access (obj_desc, field_flags,
+			  &byte_alignment);
+	if (!access_bit_width) {
+		return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+	}
+
+	/* Setup width (access granularity) fields */
+
+	obj_desc->common_field.access_byte_width = (u8)
+			ACPI_DIV_8 (access_bit_width); /* 1, 2, 4,  8 */
+
+	obj_desc->common_field.access_bit_width = (u8) access_bit_width;
+
+	/*
+	 * base_byte_offset is the address of the start of the field within the
+	 * region.  It is the byte address of the first *datum* (field-width data
+	 * unit) of the field. (i.e., the first datum that contains at least the
+	 * first *bit* of the field.)
+	 *
+	 * Note: byte_alignment is always either equal to the access_bit_width or 8
+	 * (Byte access), and it defines the addressing granularity of the parent
+	 * region or buffer.
+	 */
+	nearest_byte_address =
+			ACPI_ROUND_BITS_DOWN_TO_BYTES (field_bit_position);
+	obj_desc->common_field.base_byte_offset = (u32)
+			ACPI_ROUND_DOWN (nearest_byte_address, byte_alignment);
+
+	/*
+	 * start_field_bit_offset is the offset of the first bit of the field within
+	 * a field datum.
+	 */
+	obj_desc->common_field.start_field_bit_offset = (u8)
+		(field_bit_position - ACPI_MUL_8 (obj_desc->common_field.base_byte_offset));
+
+	/*
+	 * Does the entire field fit within a single field access element? (datum)
+	 * (i.e., without crossing a datum boundary)
+	 */
+	if ((obj_desc->common_field.start_field_bit_offset + field_bit_length) <=
+			(u16) access_bit_width) {
+		obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_prep_field_value
+ *
+ * PARAMETERS:  Node                - Owning Node
+ *              region_node         - Region in which field is being defined
+ *              field_flags         - Access, lock_rule, and update_rule.
+ *              field_bit_position  - Field start position
+ *              field_bit_length    - Field length in number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Construct an union acpi_operand_object of type def_field and
+ *              connect it to the parent Node.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_prep_field_value (
+	struct acpi_create_field_info   *info)
+{
+	union acpi_operand_object       *obj_desc;
+	u32                             type;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ex_prep_field_value");
+
+
+	/* Parameter validation */
+
+	if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) {
+		if (!info->region_node) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null region_node\n"));
+			return_ACPI_STATUS (AE_AML_NO_OPERAND);
+		}
+
+		type = acpi_ns_get_type (info->region_node);
+		if (type != ACPI_TYPE_REGION) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Needed Region, found type %X (%s)\n",
+				type, acpi_ut_get_type_name (type)));
+
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+	}
+
+	/* Allocate a new field object */
+
+	obj_desc = acpi_ut_create_internal_object (info->field_type);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Initialize areas of the object that are common to all fields */
+
+	obj_desc->common_field.node = info->field_node;
+	status = acpi_ex_prep_common_field_object (obj_desc, info->field_flags,
+			 info->attribute, info->field_bit_position, info->field_bit_length);
+	if (ACPI_FAILURE (status)) {
+		acpi_ut_delete_object_desc (obj_desc);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Initialize areas of the object that are specific to the field type */
+
+	switch (info->field_type) {
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+		obj_desc->field.region_obj   = acpi_ns_get_attached_object (info->region_node);
+
+		/* An additional reference for the container */
+
+		acpi_ut_add_reference (obj_desc->field.region_obj);
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+			"region_field: bit_off %X, Off %X, Gran %X, Region %p\n",
+			obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset,
+			obj_desc->field.access_byte_width, obj_desc->field.region_obj));
+		break;
+
+
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+		obj_desc->bank_field.value   = info->bank_value;
+		obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node);
+		obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (info->register_node);
+
+		/* An additional reference for the attached objects */
+
+		acpi_ut_add_reference (obj_desc->bank_field.region_obj);
+		acpi_ut_add_reference (obj_desc->bank_field.bank_obj);
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+			"Bank Field: bit_off %X, Off %X, Gran %X, Region %p, bank_reg %p\n",
+			obj_desc->bank_field.start_field_bit_offset,
+			obj_desc->bank_field.base_byte_offset,
+			obj_desc->field.access_byte_width,
+			obj_desc->bank_field.region_obj,
+			obj_desc->bank_field.bank_obj));
+		break;
+
+
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node);
+		obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node);
+		obj_desc->index_field.value  = (u32)
+			(info->field_bit_position / ACPI_MUL_8 (obj_desc->field.access_byte_width));
+
+		if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
+			ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
+			acpi_ut_delete_object_desc (obj_desc);
+			return_ACPI_STATUS (AE_AML_INTERNAL);
+		}
+
+		/* An additional reference for the attached objects */
+
+		acpi_ut_add_reference (obj_desc->index_field.data_obj);
+		acpi_ut_add_reference (obj_desc->index_field.index_obj);
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+			"index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
+			obj_desc->index_field.start_field_bit_offset,
+			obj_desc->index_field.base_byte_offset,
+			obj_desc->index_field.value,
+			obj_desc->field.access_byte_width,
+			obj_desc->index_field.index_obj,
+			obj_desc->index_field.data_obj));
+		break;
+
+	default:
+		/* No other types should get here */
+		break;
+	}
+
+	/*
+	 * Store the constructed descriptor (obj_desc) into the parent Node,
+	 * preserving the current type of that named_obj.
+	 */
+	status = acpi_ns_attach_object (info->field_node, obj_desc,
+			  acpi_ns_get_type (info->field_node));
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n",
+			info->field_node, acpi_ut_get_node_name (info->field_node), obj_desc));
+
+	/* Remove local reference to the object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
new file mode 100644
index 0000000..7cfd068
--- /dev/null
+++ b/drivers/acpi/executer/exregion.c
@@ -0,0 +1,528 @@
+
+/******************************************************************************
+ *
+ * Module Name: exregion - ACPI default op_region (address space) handlers
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exregion")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_memory_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              handler_context     - Pointer to Handler's context
+ *              region_context      - Pointer to context specific to the
+ *                                    accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the System Memory address space (Op Region)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_memory_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context)
+{
+	acpi_status                     status = AE_OK;
+	void                            *logical_addr_ptr = NULL;
+	struct acpi_mem_space_context   *mem_info = region_context;
+	u32                             length;
+	acpi_size                       window_size;
+#ifndef ACPI_MISALIGNED_TRANSFERS
+	u32                             remainder;
+#endif
+
+	ACPI_FUNCTION_TRACE ("ex_system_memory_space_handler");
+
+
+	/* Validate and translate the bit width */
+
+	switch (bit_width) {
+	case 8:
+		length = 1;
+		break;
+
+	case 16:
+		length = 2;
+		break;
+
+	case 32:
+		length = 4;
+		break;
+
+	case 64:
+		length = 8;
+		break;
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid system_memory width %d\n",
+			bit_width));
+		return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+	}
+
+
+#ifndef ACPI_MISALIGNED_TRANSFERS
+	/*
+	 * Hardware does not support non-aligned data transfers, we must verify
+	 * the request.
+	 */
+	(void) acpi_ut_short_divide ((acpi_integer) address, length, NULL, &remainder);
+	if (remainder != 0) {
+		return_ACPI_STATUS (AE_AML_ALIGNMENT);
+	}
+#endif
+
+	/*
+	 * Does the request fit into the cached memory mapping?
+	 * Is 1) Address below the current mapping? OR
+	 *    2) Address beyond the current mapping?
+	 */
+	if ((address < mem_info->mapped_physical_address) ||
+		(((acpi_integer) address + length) >
+			((acpi_integer) mem_info->mapped_physical_address + mem_info->mapped_length))) {
+		/*
+		 * The request cannot be resolved by the current memory mapping;
+		 * Delete the existing mapping and create a new one.
+		 */
+		if (mem_info->mapped_length) {
+			/* Valid mapping, delete it */
+
+			acpi_os_unmap_memory (mem_info->mapped_logical_address,
+					   mem_info->mapped_length);
+		}
+
+		/*
+		 * Don't attempt to map memory beyond the end of the region, and
+		 * constrain the maximum mapping size to something reasonable.
+		 */
+		window_size = (acpi_size) ((mem_info->address + mem_info->length) - address);
+		if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
+			window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
+		}
+
+		/* Create a new mapping starting at the address given */
+
+		status = acpi_os_map_memory (address, window_size,
+				  (void **) &mem_info->mapped_logical_address);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n",
+					ACPI_FORMAT_UINT64 (address), (u32) window_size));
+			mem_info->mapped_length = 0;
+			return_ACPI_STATUS (status);
+		}
+
+		/* Save the physical address and mapping size */
+
+		mem_info->mapped_physical_address = address;
+		mem_info->mapped_length = window_size;
+	}
+
+	/*
+	 * Generate a logical pointer corresponding to the address we want to
+	 * access
+	 */
+	logical_addr_ptr = mem_info->mapped_logical_address +
+			  ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+			ACPI_FORMAT_UINT64 (address)));
+
+   /*
+	* Perform the memory read or write
+	*
+	* Note: For machines that do not support non-aligned transfers, the target
+	* address was checked for alignment above.  We do not attempt to break the
+	* transfer up into smaller (byte-size) chunks because the AML specifically
+	* asked for a transfer width that the hardware may require.
+	*/
+	switch (function) {
+	case ACPI_READ:
+
+		*value = 0;
+		switch (bit_width) {
+		case 8:
+			*value = (acpi_integer) *((u8 *) logical_addr_ptr);
+			break;
+
+		case 16:
+			*value = (acpi_integer) *((u16 *) logical_addr_ptr);
+			break;
+
+		case 32:
+			*value = (acpi_integer) *((u32 *) logical_addr_ptr);
+			break;
+
+#if ACPI_MACHINE_WIDTH != 16
+		case 64:
+			*value = (acpi_integer) *((u64 *) logical_addr_ptr);
+			break;
+#endif
+		default:
+			/* bit_width was already validated */
+			break;
+		}
+		break;
+
+	case ACPI_WRITE:
+
+		switch (bit_width) {
+		case 8:
+			*(u8 *) logical_addr_ptr = (u8) *value;
+			break;
+
+		case 16:
+			*(u16 *) logical_addr_ptr = (u16) *value;
+			break;
+
+		case 32:
+			*(u32 *) logical_addr_ptr = (u32) *value;
+			break;
+
+#if ACPI_MACHINE_WIDTH != 16
+		case 64:
+			*(u64 *) logical_addr_ptr = (u64) *value;
+			break;
+#endif
+
+		default:
+			/* bit_width was already validated */
+			break;
+		}
+		break;
+
+	default:
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_io_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              handler_context     - Pointer to Handler's context
+ *              region_context      - Pointer to context specific to the
+ *                                    accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the System IO address space (Op Region)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_io_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context)
+{
+	acpi_status                     status = AE_OK;
+	u32                             value32;
+
+
+	ACPI_FUNCTION_TRACE ("ex_system_io_space_handler");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+			ACPI_FORMAT_UINT64 (address)));
+
+	/* Decode the function parameter */
+
+	switch (function) {
+	case ACPI_READ:
+
+		status = acpi_os_read_port ((acpi_io_address) address, &value32, bit_width);
+		*value = value32;
+		break;
+
+	case ACPI_WRITE:
+
+		status = acpi_os_write_port ((acpi_io_address) address, (u32) *value, bit_width);
+		break;
+
+	default:
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_pci_config_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              handler_context     - Pointer to Handler's context
+ *              region_context      - Pointer to context specific to the
+ *                                    accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the PCI Config address space (Op Region)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_pci_config_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_pci_id              *pci_id;
+	u16                             pci_register;
+
+
+	ACPI_FUNCTION_TRACE ("ex_pci_config_space_handler");
+
+
+	/*
+	 *  The arguments to acpi_os(Read|Write)pci_configuration are:
+	 *
+	 *  pci_segment is the PCI bus segment range 0-31
+	 *  pci_bus     is the PCI bus number range 0-255
+	 *  pci_device  is the PCI device number range 0-31
+	 *  pci_function is the PCI device function number
+	 *  pci_register is the Config space register range 0-255 bytes
+	 *
+	 *  Value - input value for write, output address for read
+	 *
+	 */
+	pci_id      = (struct acpi_pci_id *) region_context;
+	pci_register = (u16) (u32) address;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
+		function, bit_width, pci_id->segment, pci_id->bus, pci_id->device,
+		pci_id->function, pci_register));
+
+	switch (function) {
+	case ACPI_READ:
+
+		*value = 0;
+		status = acpi_os_read_pci_configuration (pci_id, pci_register, value, bit_width);
+		break;
+
+	case ACPI_WRITE:
+
+		status = acpi_os_write_pci_configuration (pci_id, pci_register, *value, bit_width);
+		break;
+
+	default:
+
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_cmos_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              handler_context     - Pointer to Handler's context
+ *              region_context      - Pointer to context specific to the
+ *                                    accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the CMOS address space (Op Region)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_cmos_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_cmos_space_handler");
+
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_pci_bar_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              handler_context     - Pointer to Handler's context
+ *              region_context      - Pointer to context specific to the
+ *                                    accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_pci_bar_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_pci_bar_space_handler");
+
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_data_table_space_handler
+ *
+ * PARAMETERS:  Function            - Read or Write operation
+ *              Address             - Where in the space to read or write
+ *              bit_width           - Field width in bits (8, 16, or 32)
+ *              Value               - Pointer to in or out value
+ *              handler_context     - Pointer to Handler's context
+ *              region_context      - Pointer to context specific to the
+ *                                    accessed region
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handler for the Data Table address space (Op Region)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_data_table_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context)
+{
+	acpi_status                     status = AE_OK;
+	u32                             byte_width = ACPI_DIV_8 (bit_width);
+	u32                             i;
+	char                            *logical_addr_ptr;
+
+
+	ACPI_FUNCTION_TRACE ("ex_data_table_space_handler");
+
+
+	logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address);
+
+
+   /* Perform the memory read or write */
+
+	switch (function) {
+	case ACPI_READ:
+
+		for (i = 0; i < byte_width; i++) {
+			((char *) value) [i] = logical_addr_ptr[i];
+		}
+		break;
+
+	case ACPI_WRITE:
+	default:
+
+		return_ACPI_STATUS (AE_SUPPORT);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
new file mode 100644
index 0000000..7936329
--- /dev/null
+++ b/drivers/acpi/executer/exresnte.c
@@ -0,0 +1,289 @@
+
+/******************************************************************************
+ *
+ * Module Name: exresnte - AML Interpreter object resolution
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exresnte")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_resolve_node_to_value
+ *
+ * PARAMETERS:  object_ptr      - Pointer to a location that contains
+ *                                a pointer to a NS node, and will receive a
+ *                                pointer to the resolved object.
+ *              walk_state      - Current state.  Valid only if executing AML
+ *                                code.  NULL if simply resolving an object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Resolve a Namespace node to a valued object
+ *
+ * Note: for some of the data types, the pointer attached to the Node
+ * can be either a pointer to an actual internal object or a pointer into the
+ * AML stream itself.  These types are currently:
+ *
+ *      ACPI_TYPE_INTEGER
+ *      ACPI_TYPE_STRING
+ *      ACPI_TYPE_BUFFER
+ *      ACPI_TYPE_MUTEX
+ *      ACPI_TYPE_PACKAGE
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_resolve_node_to_value (
+	struct acpi_namespace_node      **object_ptr,
+	struct acpi_walk_state          *walk_state)
+
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *source_desc;
+	union acpi_operand_object       *obj_desc = NULL;
+	struct acpi_namespace_node      *node;
+	acpi_object_type                entry_type;
+
+
+	ACPI_FUNCTION_TRACE ("ex_resolve_node_to_value");
+
+
+	/*
+	 * The stack pointer points to a struct acpi_namespace_node (Node).  Get the
+	 * object that is attached to the Node.
+	 */
+	node       = *object_ptr;
+	source_desc = acpi_ns_get_attached_object (node);
+	entry_type = acpi_ns_get_type ((acpi_handle) node);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Entry=%p source_desc=%p [%s]\n",
+		 node, source_desc, acpi_ut_get_type_name (entry_type)));
+
+	if ((entry_type == ACPI_TYPE_LOCAL_ALIAS) ||
+		(entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
+		/* There is always exactly one level of indirection */
+
+		node       = ACPI_CAST_PTR (struct acpi_namespace_node, node->object);
+		source_desc = acpi_ns_get_attached_object (node);
+		entry_type = acpi_ns_get_type ((acpi_handle) node);
+		*object_ptr = node;
+	}
+
+	/*
+	 * Several object types require no further processing:
+	 * 1) Devices rarely have an attached object, return the Node
+	 * 2) Method locals and arguments have a pseudo-Node
+	 */
+	if (entry_type == ACPI_TYPE_DEVICE ||
+		(node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	if (!source_desc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object attached to node %p\n",
+			node));
+		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+	}
+
+	/*
+	 * Action is based on the type of the Node, which indicates the type
+	 * of the attached object or pointer
+	 */
+	switch (entry_type) {
+	case ACPI_TYPE_PACKAGE:
+
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_PACKAGE) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Package, type %s\n",
+				acpi_ut_get_object_type_name (source_desc)));
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		status = acpi_ds_get_package_arguments (source_desc);
+		if (ACPI_SUCCESS (status)) {
+			/* Return an additional reference to the object */
+
+			obj_desc = source_desc;
+			acpi_ut_add_reference (obj_desc);
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Buffer, type %s\n",
+				acpi_ut_get_object_type_name (source_desc)));
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		status = acpi_ds_get_buffer_arguments (source_desc);
+		if (ACPI_SUCCESS (status)) {
+			/* Return an additional reference to the object */
+
+			obj_desc = source_desc;
+			acpi_ut_add_reference (obj_desc);
+		}
+		break;
+
+
+	case ACPI_TYPE_STRING:
+
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a String, type %s\n",
+				acpi_ut_get_object_type_name (source_desc)));
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Return an additional reference to the object */
+
+		obj_desc = source_desc;
+		acpi_ut_add_reference (obj_desc);
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Object not a Integer, type %s\n",
+				acpi_ut_get_object_type_name (source_desc)));
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Return an additional reference to the object */
+
+		obj_desc = source_desc;
+		acpi_ut_add_reference (obj_desc);
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read Node=%p source_desc=%p Type=%X\n",
+			node, source_desc, entry_type));
+
+		status = acpi_ex_read_data_from_field (walk_state, source_desc, &obj_desc);
+		break;
+
+	/*
+	 * For these objects, just return the object attached to the Node
+	 */
+	case ACPI_TYPE_MUTEX:
+	case ACPI_TYPE_METHOD:
+	case ACPI_TYPE_POWER:
+	case ACPI_TYPE_PROCESSOR:
+	case ACPI_TYPE_THERMAL:
+	case ACPI_TYPE_EVENT:
+	case ACPI_TYPE_REGION:
+
+		/* Return an additional reference to the object */
+
+		obj_desc = source_desc;
+		acpi_ut_add_reference (obj_desc);
+		break;
+
+
+	/* TYPE_ANY is untyped, and thus there is no object associated with it */
+
+	case ACPI_TYPE_ANY:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Untyped entry %p, no attached object!\n",
+			node));
+
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);  /* Cannot be AE_TYPE */
+
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		switch (source_desc->reference.opcode) {
+		case AML_LOAD_OP:
+
+			/* This is a ddb_handle */
+			/* Return an additional reference to the object */
+
+			obj_desc = source_desc;
+			acpi_ut_add_reference (obj_desc);
+			break;
+
+		default:
+			/* No named references are allowed here */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X (%s)\n",
+				source_desc->reference.opcode,
+				acpi_ps_get_opcode_name (source_desc->reference.opcode)));
+
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+		break;
+
+
+	/* Default case is for unknown types */
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Node %p - Unknown object type %X\n",
+			node, entry_type));
+
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+
+	} /* switch (entry_type) */
+
+
+	/* Put the object descriptor on the stack */
+
+	*object_ptr = (void *) obj_desc;
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
new file mode 100644
index 0000000..7be6049
--- /dev/null
+++ b/drivers/acpi/executer/exresolv.c
@@ -0,0 +1,546 @@
+
+/******************************************************************************
+ *
+ * Module Name: exresolv - AML Interpreter object resolution
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exresolv")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_resolve_to_value
+ *
+ * PARAMETERS:  **stack_ptr         - Points to entry on obj_stack, which can
+ *                                    be either an (union acpi_operand_object *)
+ *                                    or an acpi_handle.
+ *              walk_state          - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert Reference objects to values
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_resolve_to_value (
+	union acpi_operand_object       **stack_ptr,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_resolve_to_value", stack_ptr);
+
+
+	if (!stack_ptr || !*stack_ptr) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
+		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+	}
+
+	/*
+	 * The entity pointed to by the stack_ptr can be either
+	 * 1) A valid union acpi_operand_object, or
+	 * 2) A struct acpi_namespace_node (named_obj)
+	 */
+	if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
+		status = acpi_ex_resolve_object_to_value (stack_ptr, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
+	 * was called (i.e., we can't use an _else_ here.)
+	 */
+	if (ACPI_GET_DESCRIPTOR_TYPE (*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
+		status = acpi_ex_resolve_node_to_value (
+				  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, stack_ptr),
+				  walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_resolve_object_to_value
+ *
+ * PARAMETERS:  stack_ptr       - Pointer to a stack location that contains a
+ *                                ptr to an internal object.
+ *              walk_state      - Current method state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve the value from an internal object.  The Reference type
+ *              uses the associated AML opcode to determine the value.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_resolve_object_to_value (
+	union acpi_operand_object       **stack_ptr,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *stack_desc;
+	void                            *temp_node;
+	union acpi_operand_object       *obj_desc;
+	u16                             opcode;
+
+
+	ACPI_FUNCTION_TRACE ("ex_resolve_object_to_value");
+
+
+	stack_desc = *stack_ptr;
+
+	/* This is an union acpi_operand_object    */
+
+	switch (ACPI_GET_OBJECT_TYPE (stack_desc)) {
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		opcode = stack_desc->reference.opcode;
+
+		switch (opcode) {
+		case AML_NAME_OP:
+
+			/*
+			 * Convert indirect name ptr to a direct name ptr.
+			 * Then, acpi_ex_resolve_node_to_value can be used to get the value
+			 */
+			temp_node = stack_desc->reference.object;
+
+			/* Delete the Reference Object */
+
+			acpi_ut_remove_reference (stack_desc);
+
+			/* Put direct name pointer onto stack and exit */
+
+			(*stack_ptr) = temp_node;
+			break;
+
+
+		case AML_LOCAL_OP:
+		case AML_ARG_OP:
+
+			/*
+			 * Get the local from the method's state info
+			 * Note: this increments the local's object reference count
+			 */
+			status = acpi_ds_method_data_get_value (opcode,
+					  stack_desc->reference.offset, walk_state, &obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] value_obj is %p\n",
+				stack_desc->reference.offset, obj_desc));
+
+			/*
+			 * Now we can delete the original Reference Object and
+			 * replace it with the resolved value
+			 */
+			acpi_ut_remove_reference (stack_desc);
+			*stack_ptr = obj_desc;
+			break;
+
+
+		case AML_INDEX_OP:
+
+			switch (stack_desc->reference.target_type) {
+			case ACPI_TYPE_BUFFER_FIELD:
+
+				/* Just return - leave the Reference on the stack */
+				break;
+
+
+			case ACPI_TYPE_PACKAGE:
+
+				obj_desc = *stack_desc->reference.where;
+				if (obj_desc) {
+					/*
+					 * Valid obj descriptor, copy pointer to return value
+					 * (i.e., dereference the package index)
+					 * Delete the ref object, increment the returned object
+					 */
+					acpi_ut_remove_reference (stack_desc);
+					acpi_ut_add_reference (obj_desc);
+					*stack_ptr = obj_desc;
+				}
+				else {
+					/*
+					 * A NULL object descriptor means an unitialized element of
+					 * the package, can't dereference it
+					 */
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"Attempt to deref an Index to NULL pkg element Idx=%p\n",
+						stack_desc));
+					status = AE_AML_UNINITIALIZED_ELEMENT;
+				}
+				break;
+
+
+			default:
+
+				/* Invalid reference object */
+
+				ACPI_REPORT_ERROR ((
+					"During resolve, Unknown target_type %X in Index/Reference obj %p\n",
+					stack_desc->reference.target_type, stack_desc));
+				status = AE_AML_INTERNAL;
+				break;
+			}
+			break;
+
+
+		case AML_REF_OF_OP:
+		case AML_DEBUG_OP:
+		case AML_LOAD_OP:
+
+			/* Just leave the object as-is */
+
+			break;
+
+
+		default:
+
+			ACPI_REPORT_ERROR (("During resolve, Unknown Reference opcode %X (%s) in %p\n",
+				opcode, acpi_ps_get_opcode_name (opcode), stack_desc));
+			status = AE_AML_INTERNAL;
+			break;
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		status = acpi_ds_get_buffer_arguments (stack_desc);
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		status = acpi_ds_get_package_arguments (stack_desc);
+		break;
+
+
+	/*
+	 * These cases may never happen here, but just in case..
+	 */
+	case ACPI_TYPE_BUFFER_FIELD:
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read source_desc=%p Type=%X\n",
+			stack_desc, ACPI_GET_OBJECT_TYPE (stack_desc)));
+
+		status = acpi_ex_read_data_from_field (walk_state, stack_desc, &obj_desc);
+		*stack_ptr = (void *) obj_desc;
+		break;
+
+	default:
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_resolve_multiple
+ *
+ * PARAMETERS:  walk_state          - Current state (contains AML opcode)
+ *              Operand             - Starting point for resolution
+ *              return_type         - Where the object type is returned
+ *              return_desc         - Where the resolved object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return the base object and type.  Traverse a reference list if
+ *              necessary to get to the base object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_resolve_multiple (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *operand,
+	acpi_object_type                *return_type,
+	union acpi_operand_object       **return_desc)
+{
+	union acpi_operand_object       *obj_desc = (void *) operand;
+	struct acpi_namespace_node      *node;
+	acpi_object_type                type;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple");
+
+
+	/*
+	 * Operand can be either a namespace node or an operand descriptor
+	 */
+	switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+	case ACPI_DESC_TYPE_OPERAND:
+		type = obj_desc->common.type;
+		break;
+
+	case ACPI_DESC_TYPE_NAMED:
+		type = ((struct acpi_namespace_node *) obj_desc)->type;
+		obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
+
+		/* If we had an Alias node, use the attached object for type info */
+
+		if (type == ACPI_TYPE_LOCAL_ALIAS) {
+			type = ((struct acpi_namespace_node *) obj_desc)->type;
+			obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
+		}
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+	}
+
+
+	/*
+	 * If type is anything other than a reference, we are done
+	 */
+	if (type != ACPI_TYPE_LOCAL_REFERENCE) {
+		goto exit;
+	}
+
+	/*
+	 * For reference objects created via the ref_of or Index operators,
+	 * we need to get to the base object (as per the ACPI 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) {
+		switch (obj_desc->reference.opcode) {
+		case AML_REF_OF_OP:
+
+			/* Dereference the reference pointer */
+
+			node = obj_desc->reference.object;
+
+			/* All "References" point to a NS node */
+
+			if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
+				ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+						node, acpi_ut_get_descriptor_name (node)));
+				return_ACPI_STATUS (AE_AML_INTERNAL);
+			}
+
+			/* Get the attached object */
+
+			obj_desc = acpi_ns_get_attached_object (node);
+			if (!obj_desc) {
+				/* No object, use the NS node type */
+
+				type = acpi_ns_get_type (node);
+				goto exit;
+			}
+
+			/* Check for circular references */
+
+			if (obj_desc == operand) {
+				return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
+			}
+			break;
+
+
+		case AML_INDEX_OP:
+
+			/* Get the type of this reference (index into another object) */
+
+			type = obj_desc->reference.target_type;
+			if (type != ACPI_TYPE_PACKAGE) {
+				goto exit;
+			}
+
+			/*
+			 * The main object is a package, we want to get the type
+			 * of the individual package element that is referenced by
+			 * the index.
+			 *
+			 * This could of course in turn be another reference object.
+			 */
+			obj_desc = *(obj_desc->reference.where);
+			if (!obj_desc) {
+				/* NULL package elements are allowed */
+
+				type = 0; /* Uninitialized */
+				goto exit;
+			}
+			break;
+
+
+		case AML_INT_NAMEPATH_OP:
+
+			/* Dereference the reference pointer */
+
+			node = obj_desc->reference.node;
+
+			/* All "References" point to a NS node */
+
+			if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
+				ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+						node, acpi_ut_get_descriptor_name (node)));
+			   return_ACPI_STATUS (AE_AML_INTERNAL);
+			}
+
+			/* Get the attached object */
+
+			obj_desc = acpi_ns_get_attached_object (node);
+			if (!obj_desc) {
+				/* No object, use the NS node type */
+
+				type = acpi_ns_get_type (node);
+				goto exit;
+			}
+
+			/* Check for circular references */
+
+			if (obj_desc == operand) {
+				return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
+			}
+			break;
+
+
+		case AML_LOCAL_OP:
+		case AML_ARG_OP:
+
+			if (return_desc) {
+				status = acpi_ds_method_data_get_value (obj_desc->reference.opcode,
+						  obj_desc->reference.offset, walk_state, &obj_desc);
+				if (ACPI_FAILURE (status)) {
+					return_ACPI_STATUS (status);
+				}
+				acpi_ut_remove_reference (obj_desc);
+			}
+			else {
+				status = acpi_ds_method_data_get_node (obj_desc->reference.opcode,
+						 obj_desc->reference.offset, walk_state, &node);
+				if (ACPI_FAILURE (status)) {
+					return_ACPI_STATUS (status);
+				}
+
+				obj_desc = acpi_ns_get_attached_object (node);
+				if (!obj_desc) {
+					type = ACPI_TYPE_ANY;
+					goto exit;
+				}
+			}
+			break;
+
+
+		case AML_DEBUG_OP:
+
+			/* The Debug Object is of type "debug_object" */
+
+			type = ACPI_TYPE_DEBUG_OBJECT;
+			goto exit;
+
+
+		default:
+
+			ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
+				obj_desc->reference.opcode));
+			return_ACPI_STATUS (AE_AML_INTERNAL);
+		}
+	}
+
+	/*
+	 * 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);
+
+
+exit:
+	/* Convert internal types to external types */
+
+	switch (type) {
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		type = ACPI_TYPE_FIELD_UNIT;
+		break;
+
+	case ACPI_TYPE_LOCAL_SCOPE:
+
+		/* Per ACPI Specification, Scope is untyped */
+
+		type = ACPI_TYPE_ANY;
+		break;
+
+	default:
+		/* No change to Type required */
+		break;
+	}
+
+	*return_type = type;
+	if (return_desc) {
+		*return_desc = obj_desc;
+	}
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
new file mode 100644
index 0000000..c928902
--- /dev/null
+++ b/drivers/acpi/executer/exresop.c
@@ -0,0 +1,661 @@
+
+/******************************************************************************
+ *
+ * Module Name: exresop - AML Interpreter operand/object resolution
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acparser.h>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exresop")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_check_object_type
+ *
+ * PARAMETERS:  type_needed         Object type needed
+ *              this_type           Actual object type
+ *              Object              Object pointer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check required type against actual type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_check_object_type (
+	acpi_object_type                type_needed,
+	acpi_object_type                this_type,
+	void                            *object)
+{
+	ACPI_FUNCTION_NAME ("ex_check_object_type");
+
+
+	if (type_needed == ACPI_TYPE_ANY) {
+		/* All types OK, so we don't perform any typechecks */
+
+		return (AE_OK);
+	}
+
+	if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {
+		/*
+		 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
+		 * objects and thus allow them to be targets.  (As per the ACPI
+		 * specification, a store to a constant is a noop.)
+		 */
+		if ((this_type == ACPI_TYPE_INTEGER) &&
+			(((union acpi_operand_object *) object)->common.flags & AOPOBJ_AML_CONSTANT)) {
+			return (AE_OK);
+		}
+	}
+
+	if (type_needed != this_type) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Needed [%s], found [%s] %p\n",
+			acpi_ut_get_type_name (type_needed),
+			acpi_ut_get_type_name (this_type), object));
+
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_resolve_operands
+ *
+ * PARAMETERS:  Opcode              - Opcode being interpreted
+ *              stack_ptr           - Pointer to the operand stack to be
+ *                                    resolved
+ *              walk_state          - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert multiple input operands to the types required by the
+ *              target operator.
+ *
+ *      Each 5-bit group in arg_types represents one required
+ *      operand and indicates the required Type. The corresponding operand
+ *      will be converted to the required type if possible, otherwise we
+ *      abort with an exception.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_resolve_operands (
+	u16                             opcode,
+	union acpi_operand_object       **stack_ptr,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status = AE_OK;
+	u8                              object_type;
+	void                            *temp_node;
+	u32                             arg_types;
+	const struct acpi_opcode_info   *op_info;
+	u32                             this_arg_type;
+	acpi_object_type                type_needed;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ex_resolve_operands", opcode);
+
+
+	op_info = acpi_ps_get_opcode_info (opcode);
+	if (op_info->class == AML_CLASS_UNKNOWN) {
+		return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+	}
+
+	arg_types = op_info->runtime_args;
+	if (arg_types == ARGI_INVALID_OPCODE) {
+		ACPI_REPORT_ERROR (("resolve_operands: %X is not a valid AML opcode\n",
+			opcode));
+
+		return_ACPI_STATUS (AE_AML_INTERNAL);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] required_operand_types=%8.8X \n",
+		opcode, op_info->name, arg_types));
+
+	/*
+	 * Normal exit is with (arg_types == 0) at end of argument list.
+	 * Function will return an exception from within the loop upon
+	 * finding an entry which is not (or cannot be converted
+	 * to) the required type; if stack underflows; or upon
+	 * finding a NULL stack entry (which should not happen).
+	 */
+	while (GET_CURRENT_ARG_TYPE (arg_types)) {
+		if (!stack_ptr || !*stack_ptr) {
+			ACPI_REPORT_ERROR (("resolve_operands: Null stack entry at %p\n",
+				stack_ptr));
+
+			return_ACPI_STATUS (AE_AML_INTERNAL);
+		}
+
+		/* Extract useful items */
+
+		obj_desc = *stack_ptr;
+
+		/* Decode the descriptor type */
+
+		switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+		case ACPI_DESC_TYPE_NAMED:
+
+			/* Node */
+
+			object_type = ((struct acpi_namespace_node *) obj_desc)->type;
+			break;
+
+
+		case ACPI_DESC_TYPE_OPERAND:
+
+			/* ACPI internal object */
+
+			object_type = ACPI_GET_OBJECT_TYPE (obj_desc);
+
+			/* Check for bad acpi_object_type */
+
+			if (!acpi_ut_valid_object_type (object_type)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad operand object type [%X]\n",
+					object_type));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+
+			if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
+				/*
+				 * Decode the Reference
+				 */
+				op_info = acpi_ps_get_opcode_info (opcode);
+				if (op_info->class == AML_CLASS_UNKNOWN) {
+					return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+				}
+
+				switch (obj_desc->reference.opcode) {
+				case AML_DEBUG_OP:
+				case AML_NAME_OP:
+				case AML_INDEX_OP:
+				case AML_REF_OF_OP:
+				case AML_ARG_OP:
+				case AML_LOCAL_OP:
+				case AML_LOAD_OP:   /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+
+					ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+						"Operand is a Reference, ref_opcode [%s]\n",
+						(acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name)));
+					break;
+
+				default:
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"Operand is a Reference, Unknown Reference Opcode %X [%s]\n",
+						obj_desc->reference.opcode,
+						(acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name));
+
+					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+				}
+			}
+			break;
+
+
+		default:
+
+			/* Invalid descriptor */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Invalid descriptor %p [%s]\n",
+					obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
+
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+
+		/*
+		 * Get one argument type, point to the next
+		 */
+		this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
+		INCREMENT_ARG_LIST (arg_types);
+
+		/*
+		 * Handle cases where the object does not need to be
+		 * resolved to a value
+		 */
+		switch (this_arg_type) {
+		case ARGI_REF_OR_STRING:        /* Can be a String or Reference */
+
+			if ((ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) &&
+				(ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_STRING)) {
+				/*
+				 * String found - the string references a named object and must be
+				 * resolved to a node
+				 */
+				goto next_operand;
+			}
+
+			/* Else not a string - fall through to the normal Reference case below */
+			/*lint -fallthrough */
+
+		case ARGI_REFERENCE:            /* References: */
+		case ARGI_INTEGER_REF:
+		case ARGI_OBJECT_REF:
+		case ARGI_DEVICE_REF:
+		case ARGI_TARGETREF:            /* Allows implicit conversion rules before store */
+		case ARGI_FIXED_TARGET:         /* No implicit conversion before store to target */
+		case ARGI_SIMPLE_TARGET:        /* Name, Local, or Arg - no implicit conversion  */
+
+			/* Need an operand of type ACPI_TYPE_LOCAL_REFERENCE */
+
+			if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) /* Node (name) ptr OK as-is */ {
+				goto next_operand;
+			}
+
+			status = acpi_ex_check_object_type (ACPI_TYPE_LOCAL_REFERENCE,
+					  object_type, obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			if (AML_NAME_OP == obj_desc->reference.opcode) {
+				/*
+				 * Convert an indirect name ptr to direct name ptr and put
+				 * it on the stack
+				 */
+				temp_node = obj_desc->reference.object;
+				acpi_ut_remove_reference (obj_desc);
+				(*stack_ptr) = temp_node;
+			}
+			goto next_operand;
+
+
+		case ARGI_DATAREFOBJ:  /* Store operator only */
+
+			/*
+			 * We don't want to resolve index_op reference objects during
+			 * a store because this would be an implicit de_ref_of operation.
+			 * Instead, we just want to store the reference object.
+			 * -- All others must be resolved below.
+			 */
+			if ((opcode == AML_STORE_OP) &&
+				(ACPI_GET_OBJECT_TYPE (*stack_ptr) == ACPI_TYPE_LOCAL_REFERENCE) &&
+				((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
+				goto next_operand;
+			}
+			break;
+
+		default:
+			/* All cases covered above */
+			break;
+		}
+
+
+		/*
+		 * Resolve this object to a value
+		 */
+		status = acpi_ex_resolve_to_value (stack_ptr, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* Get the resolved object */
+
+		obj_desc = *stack_ptr;
+
+		/*
+		 * Check the resulting object (value) type
+		 */
+		switch (this_arg_type) {
+		/*
+		 * For the simple cases, only one type of resolved object
+		 * is allowed
+		 */
+		case ARGI_MUTEX:
+
+			/* Need an operand of type ACPI_TYPE_MUTEX */
+
+			type_needed = ACPI_TYPE_MUTEX;
+			break;
+
+		case ARGI_EVENT:
+
+			/* Need an operand of type ACPI_TYPE_EVENT */
+
+			type_needed = ACPI_TYPE_EVENT;
+			break;
+
+		case ARGI_PACKAGE:   /* Package */
+
+			/* Need an operand of type ACPI_TYPE_PACKAGE */
+
+			type_needed = ACPI_TYPE_PACKAGE;
+			break;
+
+		case ARGI_ANYTYPE:
+
+			/* Any operand type will do */
+
+			type_needed = ACPI_TYPE_ANY;
+			break;
+
+		case ARGI_DDBHANDLE:
+
+			/* Need an operand of type ACPI_TYPE_DDB_HANDLE */
+
+			type_needed = ACPI_TYPE_LOCAL_REFERENCE;
+			break;
+
+
+		/*
+		 * The more complex cases allow multiple resolved object types
+		 */
+		case ARGI_INTEGER:   /* Number */
+
+			/*
+			 * Need an operand of type ACPI_TYPE_INTEGER,
+			 * But we can implicitly convert from a STRING or BUFFER
+			 * Aka - "Implicit Source Operand Conversion"
+			 */
+			status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, 16);
+			if (ACPI_FAILURE (status)) {
+				if (status == AE_TYPE) {
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"Needed [Integer/String/Buffer], found [%s] %p\n",
+						acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+				}
+
+				return_ACPI_STATUS (status);
+			}
+			goto next_operand;
+
+
+		case ARGI_BUFFER:
+
+			/*
+			 * Need an operand of type ACPI_TYPE_BUFFER,
+			 * But we can implicitly convert from a STRING or INTEGER
+			 * Aka - "Implicit Source Operand Conversion"
+			 */
+			status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr);
+			if (ACPI_FAILURE (status)) {
+				if (status == AE_TYPE) {
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"Needed [Integer/String/Buffer], found [%s] %p\n",
+						acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+				}
+
+				return_ACPI_STATUS (status);
+			}
+			goto next_operand;
+
+
+		case ARGI_STRING:
+
+			/*
+			 * Need an operand of type ACPI_TYPE_STRING,
+			 * But we can implicitly convert from a BUFFER or INTEGER
+			 * Aka - "Implicit Source Operand Conversion"
+			 */
+			status = acpi_ex_convert_to_string (obj_desc, stack_ptr,
+					 ACPI_IMPLICIT_CONVERT_HEX);
+			if (ACPI_FAILURE (status)) {
+				if (status == AE_TYPE) {
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"Needed [Integer/String/Buffer], found [%s] %p\n",
+						acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+					return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+				}
+
+				return_ACPI_STATUS (status);
+			}
+			goto next_operand;
+
+
+		case ARGI_COMPUTEDATA:
+
+			/* Need an operand of type INTEGER, STRING or BUFFER */
+
+			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+			case ACPI_TYPE_INTEGER:
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_BUFFER:
+
+				/* Valid operand */
+			   break;
+
+			default:
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Needed [Integer/String/Buffer], found [%s] %p\n",
+					acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+
+
+		case ARGI_BUFFER_OR_STRING:
+
+			/* Need an operand of type STRING or BUFFER */
+
+			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_BUFFER:
+
+				/* Valid operand */
+			   break;
+
+			case ACPI_TYPE_INTEGER:
+
+				/* Highest priority conversion is to type Buffer */
+
+				status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr);
+				if (ACPI_FAILURE (status)) {
+					return_ACPI_STATUS (status);
+				}
+				break;
+
+			default:
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Needed [Integer/String/Buffer], found [%s] %p\n",
+					acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+
+
+		case ARGI_DATAOBJECT:
+			/*
+			 * ARGI_DATAOBJECT is only used by the size_of operator.
+			 * Need a buffer, string, package, or ref_of reference.
+			 *
+			 * The only reference allowed here is a direct reference to
+			 * a namespace node.
+			 */
+			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+			case ACPI_TYPE_PACKAGE:
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_BUFFER:
+			case ACPI_TYPE_LOCAL_REFERENCE:
+
+				/* Valid operand */
+				break;
+
+			default:
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Needed [Buffer/String/Package/Reference], found [%s] %p\n",
+					acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+
+
+		case ARGI_COMPLEXOBJ:
+
+			/* Need a buffer or package or (ACPI 2.0) String */
+
+			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+			case ACPI_TYPE_PACKAGE:
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_BUFFER:
+
+				/* Valid operand */
+				break;
+
+			default:
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Needed [Buffer/String/Package], found [%s] %p\n",
+					acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+
+
+		case ARGI_REGION_OR_FIELD:
+
+			/* Need an operand of type ACPI_TYPE_REGION or a FIELD in a region */
+
+			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+			case ACPI_TYPE_REGION:
+			case ACPI_TYPE_LOCAL_REGION_FIELD:
+			case ACPI_TYPE_LOCAL_BANK_FIELD:
+			case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+				/* Valid operand */
+				break;
+
+			default:
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Needed [Region/region_field], found [%s] %p\n",
+					acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+
+
+		case ARGI_DATAREFOBJ:
+
+			/* Used by the Store() operator only */
+
+			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+			case ACPI_TYPE_INTEGER:
+			case ACPI_TYPE_PACKAGE:
+			case ACPI_TYPE_STRING:
+			case ACPI_TYPE_BUFFER:
+			case ACPI_TYPE_BUFFER_FIELD:
+			case ACPI_TYPE_LOCAL_REFERENCE:
+			case ACPI_TYPE_LOCAL_REGION_FIELD:
+			case ACPI_TYPE_LOCAL_BANK_FIELD:
+			case ACPI_TYPE_LOCAL_INDEX_FIELD:
+			case ACPI_TYPE_DDB_HANDLE:
+
+				/* Valid operand */
+				break;
+
+			default:
+
+				if (acpi_gbl_enable_interpreter_slack) {
+					/*
+					 * Enable original behavior of Store(), allowing any and all
+					 * objects as the source operand.  The ACPI spec does not
+					 * allow this, however.
+					 */
+					break;
+				}
+
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n",
+					acpi_ut_get_object_type_name (obj_desc), obj_desc));
+
+				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
+
+
+		default:
+
+			/* Unknown type */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Internal - Unknown ARGI (required operand) type %X\n",
+				this_arg_type));
+
+			return_ACPI_STATUS (AE_BAD_PARAMETER);
+		}
+
+		/*
+		 * Make sure that the original object was resolved to the
+		 * required object type (Simple cases only).
+		 */
+		status = acpi_ex_check_object_type (type_needed,
+				  ACPI_GET_OBJECT_TYPE (*stack_ptr), *stack_ptr);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+next_operand:
+		/*
+		 * If more operands needed, decrement stack_ptr to point
+		 * to next operand on stack
+		 */
+		if (GET_CURRENT_ARG_TYPE (arg_types)) {
+			stack_ptr--;
+		}
+
+	}   /* while (*Types) */
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
new file mode 100644
index 0000000..e0fc6ab
--- /dev/null
+++ b/drivers/acpi/executer/exstore.c
@@ -0,0 +1,536 @@
+
+/******************************************************************************
+ *
+ * Module Name: exstore - AML Interpreter object store support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exstore")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_store
+ *
+ * PARAMETERS:  *source_desc        - Value to be stored
+ *              *dest_desc          - Where to store it.  Must be an NS node
+ *                                    or an union acpi_operand_object of type
+ *                                    Reference;
+ *              walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the value described by source_desc into the location
+ *              described by dest_desc. Called by various interpreter
+ *              functions to store the result of an operation into
+ *              the destination operand -- not just simply the actual "Store"
+ *              ASL operator.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_store (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *dest_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *ref_desc = dest_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_store", dest_desc);
+
+
+	/* Validate parameters */
+
+	if (!source_desc || !dest_desc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null parameter\n"));
+		return_ACPI_STATUS (AE_AML_NO_OPERAND);
+	}
+
+	/* dest_desc can be either a namespace node or an ACPI object */
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (dest_desc) == ACPI_DESC_TYPE_NAMED) {
+		/*
+		 * Dest is a namespace node,
+		 * Storing an object into a Named node.
+		 */
+		status = acpi_ex_store_object_to_node (source_desc,
+				 (struct acpi_namespace_node *) dest_desc, walk_state,
+				 ACPI_IMPLICIT_CONVERSION);
+
+		return_ACPI_STATUS (status);
+	}
+
+	/* Destination object must be a Reference or a Constant object */
+
+	switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
+	case ACPI_TYPE_LOCAL_REFERENCE:
+		break;
+
+	case ACPI_TYPE_INTEGER:
+
+		/* Allow stores to Constants -- a Noop as per ACPI spec */
+
+		if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
+			return_ACPI_STATUS (AE_OK);
+		}
+
+		/*lint -fallthrough */
+
+	default:
+
+		/* Destination is not a Reference object */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Target is not a Reference or Constant object - %s [%p]\n",
+			acpi_ut_get_object_type_name (dest_desc), dest_desc));
+
+		ACPI_DUMP_STACK_ENTRY (source_desc);
+		ACPI_DUMP_STACK_ENTRY (dest_desc);
+		ACPI_DUMP_OPERANDS (&dest_desc, ACPI_IMODE_EXECUTE, "ex_store",
+				  2, "Target is not a Reference or Constant object");
+
+		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+	}
+
+	/*
+	 * Examine the Reference opcode.  These cases are handled:
+	 *
+	 * 1) Store to Name (Change the object associated with a name)
+	 * 2) Store to an indexed area of a Buffer or Package
+	 * 3) Store to a Method Local or Arg
+	 * 4) Store to the debug object
+	 */
+	switch (ref_desc->reference.opcode) {
+	case AML_NAME_OP:
+	case AML_REF_OF_OP:
+
+		/* Storing an object into a Name "container" */
+
+		status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object,
+				  walk_state, ACPI_IMPLICIT_CONVERSION);
+		break;
+
+
+	case AML_INDEX_OP:
+
+		/* Storing to an Index (pointer into a packager or buffer) */
+
+		status = acpi_ex_store_object_to_index (source_desc, ref_desc, walk_state);
+		break;
+
+
+	case AML_LOCAL_OP:
+	case AML_ARG_OP:
+
+		/* Store to a method local/arg  */
+
+		status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
+				  ref_desc->reference.offset, source_desc, walk_state);
+		break;
+
+
+	case AML_DEBUG_OP:
+
+		/*
+		 * Storing to the Debug object causes the value stored to be
+		 * displayed and otherwise has no effect -- see ACPI Specification
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"**** Write to Debug Object: Object %p %s ****:\n\n",
+			source_desc, acpi_ut_get_object_type_name (source_desc)));
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
+			acpi_ut_get_object_type_name (source_desc)));
+
+		if (!acpi_ut_valid_internal_object (source_desc)) {
+		   ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
+			   "%p, Invalid Internal Object!\n", source_desc));
+		   break;
+		}
+
+		switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+		case ACPI_TYPE_INTEGER:
+
+			if (acpi_gbl_integer_byte_width == 4) {
+				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
+					(u32) source_desc->integer.value));
+			}
+			else {
+				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
+					ACPI_FORMAT_UINT64 (source_desc->integer.value)));
+			}
+			break;
+
+
+		case ACPI_TYPE_BUFFER:
+
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
+				(u32) source_desc->buffer.length));
+			ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
+				(source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
+			break;
+
+
+		case ACPI_TYPE_STRING:
+
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
+				source_desc->string.length, source_desc->string.pointer));
+			break;
+
+
+		case ACPI_TYPE_PACKAGE:
+
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] Elements Ptr - %p\n",
+				source_desc->package.count, source_desc->package.elements));
+			break;
+
+
+		default:
+
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
+				source_desc));
+			break;
+		}
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("ex_store: Unknown Reference opcode %X\n",
+			ref_desc->reference.opcode));
+		ACPI_DUMP_ENTRY (ref_desc, ACPI_LV_ERROR);
+
+		status = AE_AML_INTERNAL;
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_store_object_to_index
+ *
+ * PARAMETERS:  *source_desc            - Value to be stored
+ *              *dest_desc              - Named object to receive the value
+ *              walk_state              - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the object to indexed Buffer or Package element
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_store_object_to_index (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *index_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *new_desc;
+	u8                              value = 0;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ex_store_object_to_index");
+
+
+	/*
+	 * Destination must be a reference pointer, and
+	 * must point to either a buffer or a package
+	 */
+	switch (index_desc->reference.target_type) {
+	case ACPI_TYPE_PACKAGE:
+		/*
+		 * Storing to a package element. Copy the object and replace
+		 * any existing object with the new object. No implicit
+		 * conversion is performed.
+		 *
+		 * The object at *(index_desc->Reference.Where) is the
+		 * element within the package that is to be modified.
+		 * The parent package object is at index_desc->Reference.Object
+		 */
+		obj_desc = *(index_desc->reference.where);
+
+		status = acpi_ut_copy_iobject_to_iobject (source_desc, &new_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		if (obj_desc) {
+			/* Decrement reference count by the ref count of the parent package */
+
+			for (i = 0; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
+				acpi_ut_remove_reference (obj_desc);
+			}
+		}
+
+		*(index_desc->reference.where) = new_desc;
+
+		/* Increment reference count by the ref count of the parent package -1 */
+
+		for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
+			acpi_ut_add_reference (new_desc);
+		}
+
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		/*
+		 * Store into a Buffer or String (not actually a real buffer_field)
+		 * at a location defined by an Index.
+		 *
+		 * The first 8-bit element of the source object is written to the
+		 * 8-bit Buffer location defined by the Index destination object,
+		 * according to the ACPI 2.0 specification.
+		 */
+
+		/*
+		 * Make sure the target is a Buffer or String. An error should
+		 * not happen here, since the reference_object was constructed
+		 * 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)) {
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		/*
+		 * The assignment of the individual elements will be slightly
+		 * different for each source type.
+		 */
+		switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+		case ACPI_TYPE_INTEGER:
+
+			/* Use the least-significant byte of the integer */
+
+			value = (u8) (source_desc->integer.value);
+			break;
+
+		case ACPI_TYPE_BUFFER:
+		case ACPI_TYPE_STRING:
+
+			/* Note: Takes advantage of common string/buffer fields */
+
+			value = source_desc->buffer.pointer[0];
+			break;
+
+		default:
+
+			/* All other types are invalid */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Source must be Integer/Buffer/String type, not %s\n",
+				acpi_ut_get_object_type_name (source_desc)));
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Store the source value into the target buffer byte */
+
+		obj_desc->buffer.pointer[index_desc->reference.offset] = value;
+		break;
+
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Target is not a Package or buffer_field\n"));
+		status = AE_AML_OPERAND_TYPE;
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_store_object_to_node
+ *
+ * PARAMETERS:  source_desc             - Value to be stored
+ *              Node                    - Named object to receive the value
+ *              walk_state              - Current walk state
+ *              implicit_conversion     - Perform implicit conversion (yes/no)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store the object to the named object.
+ *
+ *              The Assignment of an object to a named object is handled here
+ *              The value passed in will replace the current value (if any)
+ *              with the input value.
+ *
+ *              When storing into an object the data is converted to the
+ *              target object type then stored in the object.  This means
+ *              that the target object type (for an initialized target) will
+ *              not be changed by a store operation.
+ *
+ *              Assumes parameters are already validated.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_store_object_to_node (
+	union acpi_operand_object       *source_desc,
+	struct acpi_namespace_node      *node,
+	struct acpi_walk_state          *walk_state,
+	u8                              implicit_conversion)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *target_desc;
+	union acpi_operand_object       *new_desc;
+	acpi_object_type                target_type;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc);
+
+
+	/*
+	 * Get current type of the node, and object attached to Node
+	 */
+	target_type = acpi_ns_get_type (node);
+	target_desc = acpi_ns_get_attached_object (node);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
+		source_desc, acpi_ut_get_object_type_name (source_desc),
+			  node, acpi_ut_get_type_name (target_type)));
+
+	/*
+	 * Resolve the source object to an actual value
+	 * (If it is a reference object)
+	 */
+	status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* If no implicit conversion, drop into the default case below */
+
+	if (!implicit_conversion) {
+		/* Force execution of default (no implicit conversion) */
+
+		target_type = ACPI_TYPE_ANY;
+	}
+
+	/*
+	 * Do the actual store operation
+	 */
+	switch (target_type) {
+	case ACPI_TYPE_BUFFER_FIELD:
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+		/*
+		 * For fields, copy the source data to the target field.
+		 */
+		status = acpi_ex_write_data_to_field (source_desc, target_desc, &walk_state->result_obj);
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
+
+		/*
+		 * These target types are all of type Integer/String/Buffer, and
+		 * therefore support implicit conversion before the store.
+		 *
+		 * Copy and/or convert the source object to a new target object
+		 */
+		status = acpi_ex_store_object_to_object (source_desc, target_desc, &new_desc, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		if (new_desc != target_desc) {
+			/*
+			 * Store the new new_desc as the new value of the Name, and set
+			 * the Name's type to that of the value being stored in it.
+			 * source_desc reference count is incremented by attach_object.
+			 *
+			 * Note: This may change the type of the node if an explicit store
+			 * has been performed such that the node/object type has been
+			 * changed.
+			 */
+			status = acpi_ns_attach_object (node, new_desc, new_desc->common.type);
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"Store %s into %s via Convert/Attach\n",
+				acpi_ut_get_object_type_name (source_desc),
+				acpi_ut_get_object_type_name (new_desc)));
+		}
+		break;
+
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Storing %s (%p) directly into node (%p), no implicit conversion\n",
+			acpi_ut_get_object_type_name (source_desc), source_desc, node));
+
+		/* 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));
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
new file mode 100644
index 0000000..d3677fe
--- /dev/null
+++ b/drivers/acpi/executer/exstoren.c
@@ -0,0 +1,306 @@
+
+/******************************************************************************
+ *
+ * Module Name: exstoren - AML Interpreter object store support,
+ *                        Store to Node (namespace object)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exstoren")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_resolve_object
+ *
+ * PARAMETERS:  source_desc_ptr     - Pointer to the source object
+ *              target_type         - Current type of the target
+ *              walk_state          - Current walk state
+ *
+ * RETURN:      Status, resolved object in source_desc_ptr.
+ *
+ * DESCRIPTION: Resolve an object.  If the object is a reference, dereference
+ *              it and return the actual object in the source_desc_ptr.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_resolve_object (
+	union acpi_operand_object       **source_desc_ptr,
+	acpi_object_type                target_type,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *source_desc = *source_desc_ptr;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_resolve_object");
+
+
+	/*
+	 * Ensure we have a Target that can be stored to
+	 */
+	switch (target_type) {
+	case ACPI_TYPE_BUFFER_FIELD:
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+		/*
+		 * These cases all require only Integers or values that
+		 * can be converted to Integers (Strings or Buffers)
+		 */
+
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
+
+		/*
+		 * Stores into a Field/Region or into a Integer/Buffer/String
+		 * 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) {
+			/* Resolve a reference object first */
+
+			status = acpi_ex_resolve_to_value (source_desc_ptr, walk_state);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+		}
+
+		/* For copy_object, no further validation necessary */
+
+		if (walk_state->opcode == AML_COPY_OP) {
+			break;
+		}
+
+		/*
+		 * 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.opcode == AML_LOAD_OP))) {
+			/*
+			 * Conversion successful but still not a valid type
+			 */
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
+				acpi_ut_get_object_type_name (source_desc),
+				acpi_ut_get_type_name (target_type)));
+			status = AE_AML_OPERAND_TYPE;
+		}
+		break;
+
+
+	case ACPI_TYPE_LOCAL_ALIAS:
+	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
+
+		/*
+		 * Aliases are resolved by acpi_ex_prep_operands
+		 */
+		ACPI_REPORT_ERROR (("Store into Alias - should never happen\n"));
+		status = AE_AML_INTERNAL;
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+	default:
+
+		/*
+		 * All other types than Alias and the various Fields come here,
+		 * including the untyped case - ACPI_TYPE_ANY.
+		 */
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_store_object_to_object
+ *
+ * PARAMETERS:  source_desc         - Object to store
+ *              dest_desc           - Object to receive a copy of the source
+ *              new_desc            - New object if dest_desc is obsoleted
+ *              walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: "Store" an object to another object.  This may include
+ *              converting the source type to the target type (implicit
+ *              conversion), and a copy of the value of the source to
+ *              the target.
+ *
+ *              The Assignment of an object to another (not named) object
+ *              is handled here.
+ *              The Source passed in will replace the current value (if any)
+ *              with the input value.
+ *
+ *              When storing into an object the data is converted to the
+ *              target object type then stored in the object.  This means
+ *              that the target object type (for an initialized target) will
+ *              not be changed by a store operation.
+ *
+ *              This module allows destination types of Number, String,
+ *              Buffer, and Package.
+ *
+ *              Assumes parameters are already validated.  NOTE: source_desc
+ *              resolution (from a reference object) must be performed by
+ *              the caller if necessary.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_store_object_to_object (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *dest_desc,
+	union acpi_operand_object       **new_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *actual_src_desc;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
+
+
+	actual_src_desc = source_desc;
+	if (!dest_desc) {
+		/*
+		 * There is no destination object (An uninitialized node or
+		 * package element), so we can simply copy the source object
+		 * creating a new destination object
+		 */
+		status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, new_desc, walk_state);
+		return_ACPI_STATUS (status);
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
+		/*
+		 * The source type does not match the type of the destination.
+		 * Perform the "implicit conversion" of the source to the current type
+		 * of the target as per the ACPI specification.
+		 *
+		 * If no conversion performed, actual_src_desc = source_desc.
+		 * 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);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		if (source_desc == actual_src_desc) {
+			/*
+			 * No conversion was performed. Return the source_desc as the
+			 * new object.
+			 */
+			*new_desc = source_desc;
+			return_ACPI_STATUS (AE_OK);
+		}
+	}
+
+	/*
+	 * 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)) {
+	case ACPI_TYPE_INTEGER:
+
+		dest_desc->integer.value = actual_src_desc->integer.value;
+
+		/* Truncate value if we are executing from a 32-bit ACPI table */
+
+		acpi_ex_truncate_for32bit_table (dest_desc);
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		status = acpi_ex_store_string_to_string (actual_src_desc, dest_desc);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		/*
+		 * Note: There is different store behavior depending on the original
+		 * source type
+		 */
+		status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+
+		status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc,
+				 walk_state);
+		break;
+
+	default:
+		/*
+		 * All other types come here.
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Store into type %s not implemented\n",
+			acpi_ut_get_object_type_name (dest_desc)));
+
+		status = AE_NOT_IMPLEMENTED;
+		break;
+	}
+
+	if (actual_src_desc != source_desc) {
+		/* Delete the intermediate (temporary) source object */
+
+		acpi_ut_remove_reference (actual_src_desc);
+	}
+
+	*new_desc = dest_desc;
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
new file mode 100644
index 0000000..05e1eca
--- /dev/null
+++ b/drivers/acpi/executer/exstorob.c
@@ -0,0 +1,216 @@
+
+/******************************************************************************
+ *
+ * Module Name: exstorob - AML Interpreter object store support, store to object
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exstorob")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_store_buffer_to_buffer
+ *
+ * PARAMETERS:  source_desc         - Source object to copy
+ *              target_desc         - Destination object of the copy
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy a buffer object to another buffer object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_store_buffer_to_buffer (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *target_desc)
+{
+	u32                             length;
+	u8                              *buffer;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_store_buffer_to_buffer", source_desc);
+
+
+	/* We know that source_desc is a buffer by now */
+
+	buffer = (u8 *) source_desc->buffer.pointer;
+	length = source_desc->buffer.length;
+
+	/*
+	 * If target is a buffer of length zero or is a static buffer,
+	 * allocate a new buffer of the proper length
+	 */
+	if ((target_desc->buffer.length == 0) ||
+		(target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
+		target_desc->buffer.pointer = ACPI_MEM_ALLOCATE (length);
+		if (!target_desc->buffer.pointer) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		target_desc->buffer.length = length;
+	}
+
+	/* Copy source buffer to target buffer */
+
+	if (length <= target_desc->buffer.length) {
+		/* Clear existing buffer and copy in the new one */
+
+		ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
+		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
+
+#ifdef ACPI_OBSOLETE_BEHAVIOR
+		/*
+		 * NOTE: ACPI versions up to 3.0 specified that the buffer must be
+		 * truncated if the string is smaller than the buffer.  However, "other"
+		 * implementations of ACPI never did this and thus became the defacto
+		 * standard. ACPi 3.0_a changes this behavior such that the buffer
+		 * is no longer truncated.
+		 */
+
+		/*
+		 * OBSOLETE BEHAVIOR:
+		 * If the original source was a string, we must truncate the buffer,
+		 * according to the ACPI spec.  Integer-to-Buffer and Buffer-to-Buffer
+		 * copy must not truncate the original buffer.
+		 */
+		if (original_src_type == ACPI_TYPE_STRING) {
+			/* Set the new length of the target */
+
+			target_desc->buffer.length = length;
+		}
+#endif
+	}
+	else {
+		/* Truncate the source, copy only what will fit */
+
+		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length);
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"Truncating source buffer from %X to %X\n",
+			length, target_desc->buffer.length));
+	}
+
+	/* Copy flags */
+
+	target_desc->buffer.flags = source_desc->buffer.flags;
+	target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_store_string_to_string
+ *
+ * PARAMETERS:  source_desc         - Source object to copy
+ *              target_desc         - Destination object of the copy
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy a String object to another String object
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_store_string_to_string (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *target_desc)
+{
+	u32                             length;
+	u8                              *buffer;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc);
+
+
+	/* We know that source_desc is a string by now */
+
+	buffer = (u8 *) source_desc->string.pointer;
+	length = source_desc->string.length;
+
+	/*
+	 * Replace existing string value if it will fit and the string
+	 * pointer is not a static pointer (part of an ACPI table)
+	 */
+	if ((length < target_desc->string.length) &&
+	   (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+		/*
+		 * String will fit in existing non-static buffer.
+		 * Clear old string and copy in the new one
+		 */
+		ACPI_MEMSET (target_desc->string.pointer, 0, (acpi_size) target_desc->string.length + 1);
+		ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
+	}
+	else {
+		/*
+		 * Free the current buffer, then allocate a new buffer
+		 * large enough to hold the value
+		 */
+		if (target_desc->string.pointer &&
+		   (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+			/* Only free if not a pointer into the DSDT */
+
+			ACPI_MEM_FREE (target_desc->string.pointer);
+		}
+
+		target_desc->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
+		if (!target_desc->string.pointer) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
+		ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
+	}
+
+	/* Set the new target length */
+
+	target_desc->string.length = length;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
new file mode 100644
index 0000000..f92efc5
--- /dev/null
+++ b/drivers/acpi/executer/exsystem.c
@@ -0,0 +1,378 @@
+
+/******************************************************************************
+ *
+ * Module Name: exsystem - Interface to OS services
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exsystem")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_wait_semaphore
+ *
+ * PARAMETERS:  Semaphore           - OSD semaphore to wait on
+ *              Timeout             - Max time to wait
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Implements a semaphore wait with a check to see if the
+ *              semaphore is available immediately.  If it is not, the
+ *              interpreter is released.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_wait_semaphore (
+	acpi_handle                     semaphore,
+	u16                             timeout)
+{
+	acpi_status                     status;
+	acpi_status                     status2;
+
+
+	ACPI_FUNCTION_TRACE ("ex_system_wait_semaphore");
+
+
+	status = acpi_os_wait_semaphore (semaphore, 1, 0);
+	if (ACPI_SUCCESS (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (status == AE_TIME) {
+		/* We must wait, so unlock the interpreter */
+
+		acpi_ex_exit_interpreter ();
+
+		status = acpi_os_wait_semaphore (semaphore, 1, timeout);
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*** Thread awake after blocking, %s\n",
+			acpi_format_exception (status)));
+
+		/* Reacquire the interpreter */
+
+		status2 = acpi_ex_enter_interpreter ();
+		if (ACPI_FAILURE (status2)) {
+			/* Report fatal error, could not acquire interpreter */
+
+			return_ACPI_STATUS (status2);
+		}
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_do_stall
+ *
+ * PARAMETERS:  how_long            - The amount of time to stall,
+ *                                    in microseconds
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Suspend running thread for specified amount of time.
+ *              Note: ACPI specification requires that Stall() does not
+ *              relinquish the processor, and delays longer than 100 usec
+ *              should use Sleep() instead.  We allow stalls up to 255 usec
+ *              for compatibility with other interpreters and existing BIOSs.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_do_stall (
+	u32                             how_long)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (how_long > 255) /* 255 microseconds */ {
+		/*
+		 * Longer than 255 usec, this is an error
+		 *
+		 * (ACPI specifies 100 usec as max, but this gives some slack in
+		 * order to support existing BIOSs)
+		 */
+		ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
+		status = AE_AML_OPERAND_VALUE;
+	}
+	else {
+		acpi_os_stall (how_long);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_do_suspend
+ *
+ * PARAMETERS:  how_long            - The amount of time to suspend,
+ *                                    in milliseconds
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Suspend running thread for specified amount of time.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_do_suspend (
+	acpi_integer                    how_long)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Since this thread will sleep, we must release the interpreter */
+
+	acpi_ex_exit_interpreter ();
+
+	acpi_os_sleep (how_long);
+
+	/* And now we must get the interpreter again */
+
+	status = acpi_ex_enter_interpreter ();
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_acquire_mutex
+ *
+ * PARAMETERS:  *time_desc          - The 'time to delay' object descriptor
+ *              *obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.  This function will cause a lock to be generated
+ *              for the Mutex pointed to by obj_desc.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_acquire_mutex (
+	union acpi_operand_object       *time_desc,
+	union acpi_operand_object       *obj_desc)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc);
+
+
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Support for the _GL_ Mutex object -- go get the global lock
+	 */
+	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
+		status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
+			  (u16) time_desc->integer.value);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_release_mutex
+ *
+ * PARAMETERS:  *obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.  This operation is a request to release a
+ *              previously acquired Mutex.  If the Mutex variable is set then
+ *              it will be decremented.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_release_mutex (
+	union acpi_operand_object       *obj_desc)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_system_release_mutex");
+
+
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Support for the _GL_ Mutex object -- release the global lock
+	 */
+	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
+		status = acpi_ev_release_global_lock ();
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_signal_event
+ *
+ * PARAMETERS:  *obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      AE_OK
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_signal_event (
+	union acpi_operand_object       *obj_desc)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_system_signal_event");
+
+
+	if (obj_desc) {
+		status = acpi_os_signal_semaphore (obj_desc->event.semaphore, 1);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_wait_event
+ *
+ * PARAMETERS:  *time_desc          - The 'time to delay' object descriptor
+ *              *obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Provides an access point to perform synchronization operations
+ *              within the AML.  This operation is a request to wait for an
+ *              event.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_wait_event (
+	union acpi_operand_object       *time_desc,
+	union acpi_operand_object       *obj_desc)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ex_system_wait_event");
+
+
+	if (obj_desc) {
+		status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore,
+				  (u16) time_desc->integer.value);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_system_reset_event
+ *
+ * PARAMETERS:  *obj_desc           - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reset an event to a known state.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_system_reset_event (
+	union acpi_operand_object       *obj_desc)
+{
+	acpi_status                     status = AE_OK;
+	void                            *temp_semaphore;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * We are going to simply delete the existing semaphore and
+	 * create a new one!
+	 */
+	status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
+	if (ACPI_SUCCESS (status)) {
+		(void) acpi_os_delete_semaphore (obj_desc->event.semaphore);
+		obj_desc->event.semaphore = temp_semaphore;
+	}
+
+	return (status);
+}
+
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
new file mode 100644
index 0000000..40c6abb
--- /dev/null
+++ b/drivers/acpi/executer/exutils.c
@@ -0,0 +1,378 @@
+
+/******************************************************************************
+ *
+ * Module Name: exutils - interpreter/scanner utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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.
+ */
+
+
+/*
+ * DEFINE_AML_GLOBALS is tested in amlcode.h
+ * to determine whether certain global names should be "defined" or only
+ * "declared" in the current compilation.  This enhances maintainability
+ * by enabling a single header file to embody all knowledge of the names
+ * in question.
+ *
+ * Exactly one module of any executable should #define DEFINE_GLOBALS
+ * before #including the header files which use this convention.  The
+ * names in question will be defined and initialized in that module,
+ * and declared as extern in all other modules which #include those
+ * header files.
+ */
+
+#define DEFINE_AML_GLOBALS
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_EXECUTER
+	 ACPI_MODULE_NAME    ("exutils")
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_enter_interpreter
+ *
+ * PARAMETERS:  None
+ *
+ * DESCRIPTION: Enter the interpreter execution region.  Failure to enter
+ *              the interpreter region is a fatal system error
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_enter_interpreter (void)
+{
+	acpi_status                     status;
+
+	ACPI_FUNCTION_TRACE ("ex_enter_interpreter");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EXECUTE);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not acquire interpreter mutex\n"));
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_exit_interpreter
+ *
+ * PARAMETERS:  None
+ *
+ * DESCRIPTION: Exit the interpreter execution region
+ *
+ * Cases where the interpreter is unlocked:
+ *      1) Completion of the execution of a control method
+ *      2) Method blocked on a Sleep() AML opcode
+ *      3) Method blocked on an Acquire() AML opcode
+ *      4) Method blocked on a Wait() AML opcode
+ *      5) Method blocked to acquire the global lock
+ *      6) Method blocked to execute a serialized control method that is
+ *          already executing
+ *      7) About to invoke a user-installed opregion handler
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_exit_interpreter (void)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ex_exit_interpreter");
+
+
+	status = acpi_ut_release_mutex (ACPI_MTX_EXECUTE);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not release interpreter mutex\n"));
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_truncate_for32bit_table
+ *
+ * PARAMETERS:  obj_desc        - Object to be truncated
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
+ *              belongs to a 32-bit ACPI table.
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_truncate_for32bit_table (
+	union acpi_operand_object       *obj_desc)
+{
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * Object must be a valid number and we must be executing
+	 * a control method
+	 */
+	if ((!obj_desc) ||
+		(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER)) {
+		return;
+	}
+
+	if (acpi_gbl_integer_byte_width == 4) {
+		/*
+		 * We are running a method that exists in a 32-bit ACPI table.
+		 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
+		 */
+		obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_acquire_global_lock
+ *
+ * PARAMETERS:  field_flags           - Flags with Lock rule:
+ *                                      always_lock or never_lock
+ *
+ * RETURN:      TRUE/FALSE indicating whether the lock was actually acquired
+ *
+ * DESCRIPTION: Obtain the global lock and keep track of this fact via two
+ *              methods.  A global variable keeps the state of the lock, and
+ *              the state is returned to the caller.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ex_acquire_global_lock (
+	u32                             field_flags)
+{
+	u8                              locked = FALSE;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ex_acquire_global_lock");
+
+
+	/* Only attempt lock if the always_lock bit is set */
+
+	if (field_flags & AML_FIELD_LOCK_RULE_MASK) {
+		/* We should attempt to get the lock, wait forever */
+
+		status = acpi_ev_acquire_global_lock (ACPI_WAIT_FOREVER);
+		if (ACPI_SUCCESS (status)) {
+			locked = TRUE;
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not acquire Global Lock, %s\n",
+				acpi_format_exception (status)));
+		}
+	}
+
+	return_VALUE (locked);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_release_global_lock
+ *
+ * PARAMETERS:  locked_by_me    - Return value from corresponding call to
+ *                                acquire_global_lock.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release the global lock if it is locked.
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_release_global_lock (
+	u8                              locked_by_me)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ex_release_global_lock");
+
+
+	/* Only attempt unlock if the caller locked it */
+
+	if (locked_by_me) {
+		/* OK, now release the lock */
+
+		status = acpi_ev_release_global_lock ();
+		if (ACPI_FAILURE (status)) {
+			/* Report the error, but there isn't much else we can do */
+
+			ACPI_REPORT_ERROR (("Could not release ACPI Global Lock, %s\n",
+				acpi_format_exception (status)));
+		}
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_digits_needed
+ *
+ * PARAMETERS:  Value           - Value to be represented
+ *              Base            - Base of representation
+ *
+ * RETURN:      the number of digits needed to represent Value in Base
+ *
+ ******************************************************************************/
+
+u32
+acpi_ex_digits_needed (
+	acpi_integer                    value,
+	u32                             base)
+{
+	u32                             num_digits;
+	acpi_integer                    current_value;
+
+
+	ACPI_FUNCTION_TRACE ("ex_digits_needed");
+
+
+	/* acpi_integer is unsigned, so we don't worry about a '-' prefix */
+
+	if (value == 0) {
+		return_VALUE (1);
+	}
+
+	current_value = value;
+	num_digits = 0;
+
+	/* Count the digits in the requested base */
+
+	while (current_value) {
+		(void) acpi_ut_short_divide (current_value, base, &current_value, NULL);
+		num_digits++;
+	}
+
+	return_VALUE (num_digits);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_eisa_id_to_string
+ *
+ * PARAMETERS:  numeric_id      - EISA ID to be converted
+ *              out_string      - Where to put the converted string (8 bytes)
+ *
+ * DESCRIPTION: Convert a numeric EISA ID to string representation
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_eisa_id_to_string (
+	u32                             numeric_id,
+	char                            *out_string)
+{
+	u32                             eisa_id;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Swap ID to big-endian to get contiguous bits */
+
+	eisa_id = acpi_ut_dword_byte_swap (numeric_id);
+
+	out_string[0] = (char) ('@' + (((unsigned long) eisa_id >> 26) & 0x1f));
+	out_string[1] = (char) ('@' + ((eisa_id >> 21) & 0x1f));
+	out_string[2] = (char) ('@' + ((eisa_id >> 16) & 0x1f));
+	out_string[3] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 12);
+	out_string[4] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 8);
+	out_string[5] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 4);
+	out_string[6] = acpi_ut_hex_to_ascii_char ((acpi_integer) eisa_id, 0);
+	out_string[7] = 0;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_unsigned_integer_to_string
+ *
+ * PARAMETERS:  Value           - Value to be converted
+ *              out_string      - Where to put the converted string (8 bytes)
+ *
+ * RETURN:      Convert a number to string representation
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_unsigned_integer_to_string (
+	acpi_integer                    value,
+	char                            *out_string)
+{
+	u32                             count;
+	u32                             digits_needed;
+	u32                             remainder;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	digits_needed = acpi_ex_digits_needed (value, 10);
+	out_string[digits_needed] = 0;
+
+	for (count = digits_needed; count > 0; count--) {
+		(void) acpi_ut_short_divide (value, 10, &value, &remainder);
+		out_string[count-1] = (char) ('0' + remainder);\
+	}
+}
+
+#endif
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
new file mode 100644
index 0000000..14192ee
--- /dev/null
+++ b/drivers/acpi/fan.c
@@ -0,0 +1,302 @@
+/*
+ *  acpi_fan.c - ACPI Fan Driver ($Revision: 29 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define ACPI_FAN_COMPONENT		0x00200000
+#define ACPI_FAN_CLASS			"fan"
+#define ACPI_FAN_HID			"PNP0C0B"
+#define ACPI_FAN_DRIVER_NAME		"ACPI Fan Driver"
+#define ACPI_FAN_DEVICE_NAME		"Fan"
+#define ACPI_FAN_FILE_STATE		"state"
+#define ACPI_FAN_NOTIFY_STATUS		0x80
+
+#define _COMPONENT		ACPI_FAN_COMPONENT
+ACPI_MODULE_NAME		("acpi_fan")
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static int acpi_fan_add (struct acpi_device *device);
+static int acpi_fan_remove (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_fan_driver = {
+	.name =		ACPI_FAN_DRIVER_NAME,
+	.class =	ACPI_FAN_CLASS,
+	.ids =		ACPI_FAN_HID,
+	.ops =		{
+				.add =		acpi_fan_add,
+				.remove =	acpi_fan_remove,
+			},
+};
+
+struct acpi_fan {
+	acpi_handle		handle;
+};
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_fan_dir;
+
+
+static int
+acpi_fan_read_state (struct seq_file *seq, void *offset)
+{
+	struct acpi_fan		*fan = seq->private;
+	int			state = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_fan_read_state");
+
+	if (fan) {
+		if (acpi_bus_get_power(fan->handle, &state))
+			seq_printf(seq, "status:                  ERROR\n");
+		else
+			seq_printf(seq, "status:                  %s\n",
+				     !state?"on":"off");
+	}
+	return_VALUE(0);
+}
+
+static int acpi_fan_state_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_fan_read_state, PDE(inode)->data);
+}
+
+static ssize_t
+acpi_fan_write_state (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	int			result = 0;
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_fan		*fan = (struct acpi_fan *) m->private;
+	char			state_string[12] = {'\0'};
+
+	ACPI_FUNCTION_TRACE("acpi_fan_write_state");
+
+	if (!fan || (count > sizeof(state_string) - 1))
+		return_VALUE(-EINVAL);
+	
+	if (copy_from_user(state_string, buffer, count))
+		return_VALUE(-EFAULT);
+	
+	state_string[count] = '\0';
+	
+	result = acpi_bus_set_power(fan->handle, 
+		simple_strtoul(state_string, NULL, 0));
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(count);
+}
+
+static struct file_operations acpi_fan_state_ops = {
+	.open		= acpi_fan_state_open_fs,
+	.read		= seq_read,
+	.write		= acpi_fan_write_state,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner = THIS_MODULE,
+};
+
+static int
+acpi_fan_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_fan_add_fs");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_fan_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
+	}
+
+	/* 'status' [R/W] */
+	entry = create_proc_entry(ACPI_FAN_FILE_STATE,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_FAN_FILE_STATE));
+	else {
+		entry->proc_fops = &acpi_fan_state_ops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_fan_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_fan_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_FAN_FILE_STATE,
+				  acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device), acpi_fan_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_fan_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	struct acpi_fan		*fan = NULL;
+	int			state = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_fan_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL);
+	if (!fan)
+		return_VALUE(-ENOMEM);
+	memset(fan, 0, sizeof(struct acpi_fan));
+
+	fan->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_FAN_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
+	acpi_driver_data(device) = fan;
+
+	result = acpi_bus_get_power(fan->handle, &state);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error reading power state\n"));
+		goto end;
+	}
+
+	result = acpi_fan_add_fs(device);
+	if (result)
+		goto end;
+
+	printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
+		acpi_device_name(device), acpi_device_bid(device),
+		!device->power.state?"on":"off");
+
+end:
+	if (result)
+		kfree(fan);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_fan_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	struct acpi_fan		*fan = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_fan_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	fan = (struct acpi_fan *) acpi_driver_data(device);
+
+	acpi_fan_remove_fs(device);
+
+	kfree(fan);
+
+	return_VALUE(0);
+}
+
+
+static int __init
+acpi_fan_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_fan_init");
+
+	acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
+	if (!acpi_fan_dir)
+		return_VALUE(-ENODEV);
+	acpi_fan_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_fan_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+
+static void __exit
+acpi_fan_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_fan_exit");
+
+	acpi_bus_unregister_driver(&acpi_fan_driver);
+
+	remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+
+module_init(acpi_fan_init);
+module_exit(acpi_fan_exit);
+
diff --git a/drivers/acpi/hardware/Makefile b/drivers/acpi/hardware/Makefile
new file mode 100644
index 0000000..438ad373
--- /dev/null
+++ b/drivers/acpi/hardware/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := hwacpi.o  hwgpe.o  hwregs.o  hwsleep.o
+
+obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
new file mode 100644
index 0000000..529e922
--- /dev/null
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -0,0 +1,230 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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>
+
+
+#define _COMPONENT          ACPI_HARDWARE
+	 ACPI_MODULE_NAME    ("hwacpi")
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize and validate various ACPI registers
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_initialize (
+	void)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("hw_initialize");
+
+
+	/* We must have the ACPI tables by the time we get here */
+
+	if (!acpi_gbl_FADT) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "A FADT is not loaded\n"));
+
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	/* Sanity check the FADT for valid values */
+
+	status = acpi_ut_validate_fadt ();
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_set_mode
+ *
+ * PARAMETERS:  Mode            - SYS_MODE_ACPI or SYS_MODE_LEGACY
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Transitions the system into the requested mode.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_set_mode (
+	u32                             mode)
+{
+
+	acpi_status                     status;
+	u32                             retry;
+
+
+	ACPI_FUNCTION_TRACE ("hw_set_mode");
+
+	/*
+	 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
+	 * system does not support mode transition.
+	 */
+	if (!acpi_gbl_FADT->smi_cmd) {
+		ACPI_REPORT_ERROR (("No SMI_CMD in FADT, mode transition failed.\n"));
+		return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+	}
+
+	/*
+	 * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
+	 * in FADT: If it is zero, enabling or disabling is not supported.
+	 * As old systems may have used zero for mode transition,
+	 * we make sure both the numbers are zero to determine these
+	 * transitions are not supported.
+	 */
+	if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
+		ACPI_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\n"));
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	switch (mode) {
+	case ACPI_SYS_MODE_ACPI:
+
+		/* BIOS should have disabled ALL fixed and GP events */
+
+		status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd,
+				  (u32) acpi_gbl_FADT->acpi_enable, 8);
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n"));
+		break;
+
+	case ACPI_SYS_MODE_LEGACY:
+
+		/*
+		 * BIOS should clear all fixed status bits and restore fixed event
+		 * enable bits to default
+		 */
+		status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd,
+				 (u32) acpi_gbl_FADT->acpi_disable, 8);
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+				 "Attempting to enable Legacy (non-ACPI) mode\n"));
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Some hardware takes a LONG time to switch modes. Give them 3 sec to
+	 * do so, but allow faster systems to proceed more quickly.
+	 */
+	retry = 3000;
+	while (retry) {
+		if (acpi_hw_get_mode() == mode) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode));
+			return_ACPI_STATUS (AE_OK);
+		}
+		acpi_os_stall(1000);
+		retry--;
+	}
+
+	ACPI_REPORT_ERROR (("Hardware never changed modes\n"));
+	return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_get_mode
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      SYS_MODE_ACPI or SYS_MODE_LEGACY
+ *
+ * DESCRIPTION: Return current operating state of system.  Determined by
+ *              querying the SCI_EN bit.
+ *
+ ******************************************************************************/
+
+u32
+acpi_hw_get_mode (void)
+{
+	acpi_status                     status;
+	u32                             value;
+
+
+	ACPI_FUNCTION_TRACE ("hw_get_mode");
+
+
+	/*
+	 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
+	 * system does not support mode transition.
+	 */
+	if (!acpi_gbl_FADT->smi_cmd) {
+		return_VALUE (ACPI_SYS_MODE_ACPI);
+	}
+
+	status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_VALUE (ACPI_SYS_MODE_LEGACY);
+	}
+
+	if (value) {
+		return_VALUE (ACPI_SYS_MODE_ACPI);
+	}
+	else {
+		return_VALUE (ACPI_SYS_MODE_LEGACY);
+	}
+}
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
new file mode 100644
index 0000000..9ac1d63
--- /dev/null
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -0,0 +1,444 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwgpe - Low level GPE enable/disable/clear functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_HARDWARE
+	 ACPI_MODULE_NAME    ("hwgpe")
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_write_gpe_enable_reg
+ *
+ * PARAMETERS:  gpe_event_info      - Info block for the GPE to be enabled
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write a GPE enable register.  Note: The bit for this GPE must
+ *              already be cleared or set in the parent register
+ *              enable_for_run mask.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_write_gpe_enable_reg (
+	struct acpi_gpe_event_info      *gpe_event_info)
+{
+	struct acpi_gpe_register_info   *gpe_register_info;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Get the info block for the entire GPE register */
+
+	gpe_register_info = gpe_event_info->register_info;
+	if (!gpe_register_info) {
+		return (AE_NOT_EXIST);
+	}
+
+	/* Write the entire GPE (runtime) enable register */
+
+	status = acpi_hw_low_level_write (8, gpe_register_info->enable_for_run,
+			  &gpe_register_info->enable_address);
+
+	return (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_clear_gpe
+ *
+ * PARAMETERS:  gpe_event_info      - Info block for the GPE to be cleared
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear the status bit for a single GPE.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_clear_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * Write a one to the appropriate bit in the status register to
+	 * clear this GPE.
+	 */
+	status = acpi_hw_low_level_write (8, gpe_event_info->register_bit,
+			  &gpe_event_info->register_info->status_address);
+
+	return (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_get_gpe_status
+ *
+ * PARAMETERS:  gpe_event_info      - Info block for the GPE to queried
+ *              event_status        - Where the GPE status is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return the status of a single GPE.
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_hw_get_gpe_status (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	acpi_event_status               *event_status)
+{
+	u32                             in_byte;
+	u8                              register_bit;
+	struct acpi_gpe_register_info   *gpe_register_info;
+	acpi_status                     status;
+	acpi_event_status               local_event_status = 0;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (!event_status) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Get the info block for the entire GPE register */
+
+	gpe_register_info = gpe_event_info->register_info;
+
+	/* Get the register bitmask for this GPE */
+
+	register_bit = gpe_event_info->register_bit;
+
+	/* GPE currently enabled? (enabled for runtime?) */
+
+	if (register_bit & gpe_register_info->enable_for_run) {
+		local_event_status |= ACPI_EVENT_FLAG_ENABLED;
+	}
+
+	/* GPE enabled for wake? */
+
+	if (register_bit & gpe_register_info->enable_for_wake) {
+		local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
+	}
+
+	/* GPE currently active (status bit == 1)? */
+
+	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
+	if (register_bit & in_byte) {
+		local_event_status |= ACPI_EVENT_FLAG_SET;
+	}
+
+	/* Set return value */
+
+	(*event_status) = local_event_status;
+
+
+unlock_and_exit:
+	return (status);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_disable_gpe_block
+ *
+ * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
+ *              gpe_block           - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable all GPEs within a GPE block
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_disable_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	u32                             i;
+	acpi_status                     status;
+
+
+	/* Examine each GPE Register within the block */
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		/* Disable all GPEs in this register */
+
+		status = acpi_hw_low_level_write (8, 0x00,
+				 &gpe_block->register_info[i].enable_address);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_clear_gpe_block
+ *
+ * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
+ *              gpe_block           - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear status bits for all GPEs within a GPE block
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_clear_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	u32                             i;
+	acpi_status                     status;
+
+
+	/* Examine each GPE Register within the block */
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		/* Clear status on all GPEs in this register */
+
+		status = acpi_hw_low_level_write (8, 0xFF,
+				 &gpe_block->register_info[i].status_address);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_enable_runtime_gpe_block
+ *
+ * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
+ *              gpe_block           - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable all "runtime" GPEs within a GPE block. (Includes
+ *              combination wake/run GPEs.)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_enable_runtime_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	u32                             i;
+	acpi_status                     status;
+
+
+	/* NOTE: assumes that all GPEs are currently disabled */
+
+	/* Examine each GPE Register within the block */
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		if (!gpe_block->register_info[i].enable_for_run) {
+			continue;
+		}
+
+		/* Enable all "runtime" GPEs in this register */
+
+		status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_run,
+				 &gpe_block->register_info[i].enable_address);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_enable_wakeup_gpe_block
+ *
+ * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
+ *              gpe_block           - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable all "wake" GPEs within a GPE block.  (Includes
+ *              combination wake/run GPEs.)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_enable_wakeup_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	u32                             i;
+	acpi_status                     status;
+
+
+	/* Examine each GPE Register within the block */
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		if (!gpe_block->register_info[i].enable_for_wake) {
+			continue;
+		}
+
+		/* Enable all "wake" GPEs in this register */
+
+		status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_wake,
+				 &gpe_block->register_info[i].enable_address);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_disable_all_gpes
+ *
+ * PARAMETERS:  Flags           - ACPI_NOT_ISR or ACPI_ISR
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable and clear all GPEs
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_disable_all_gpes (
+	u32                             flags)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("hw_disable_all_gpes");
+
+
+	status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, flags);
+	status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, flags);
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_enable_all_runtime_gpes
+ *
+ * PARAMETERS:  Flags           - ACPI_NOT_ISR or ACPI_ISR
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable all GPEs of the given type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_enable_all_runtime_gpes (
+	u32                             flags)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("hw_enable_all_runtime_gpes");
+
+
+	status = acpi_ev_walk_gpe_list (acpi_hw_enable_runtime_gpe_block, flags);
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_enable_all_wakeup_gpes
+ *
+ * PARAMETERS:  Flags           - ACPI_NOT_ISR or ACPI_ISR
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable all GPEs of the given type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_enable_all_wakeup_gpes (
+	u32                             flags)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("hw_enable_all_wakeup_gpes");
+
+
+	status = acpi_ev_walk_gpe_list (acpi_hw_enable_wakeup_gpe_block, flags);
+	return_ACPI_STATUS (status);
+}
+
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
new file mode 100644
index 0000000..91af0c2
--- /dev/null
+++ b/drivers/acpi/hardware/hwregs.c
@@ -0,0 +1,850 @@
+
+/*******************************************************************************
+ *
+ * Module Name: hwregs - Read/write access functions for the various ACPI
+ *                       control and status registers.
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_HARDWARE
+	 ACPI_MODULE_NAME    ("hwregs")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_clear_acpi_status
+ *
+ * PARAMETERS:  Flags           - Lock the hardware or not
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Clears all fixed and general purpose status bits
+ *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_clear_acpi_status (
+	u32                             flags)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("hw_clear_acpi_status");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
+		ACPI_BITMASK_ALL_FIXED_STATUS,
+		(u16) acpi_gbl_FADT->xpm1a_evt_blk.address));
+
+	if (flags & ACPI_MTX_LOCK) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, 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_evt_blk.address) {
+		status = acpi_hw_low_level_write (16, ACPI_BITMASK_ALL_FIXED_STATUS,
+				 &acpi_gbl_FADT->xpm1b_evt_blk);
+		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, ACPI_ISR);
+
+unlock_and_exit:
+	if (flags & ACPI_MTX_LOCK) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_sleep_type_data
+ *
+ * PARAMETERS:  sleep_state         - Numeric sleep state
+ *              *sleep_type_a        - Where SLP_TYPa is returned
+ *              *sleep_type_b        - Where SLP_TYPb is returned
+ *
+ * RETURN:      Status - ACPI status
+ *
+ * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
+ *              state.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_sleep_type_data (
+	u8                              sleep_state,
+	u8                              *sleep_type_a,
+	u8                              *sleep_type_b)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_parameter_info      info;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data");
+
+
+	/*
+	 * Validate parameters
+	 */
+	if ((sleep_state > ACPI_S_STATES_MAX) ||
+		!sleep_type_a || !sleep_type_b) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Evaluate the namespace object containing the values for this state
+	 */
+	info.parameters = NULL;
+	status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state],
+			  &info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n",
+			acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state]));
+
+		return_ACPI_STATUS (status);
+	}
+
+	/* Must have a return object */
+
+	if (!info.return_object) {
+		ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
+		status = AE_NOT_EXIST;
+	}
+
+	/* It must be of type Package */
+
+	else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) {
+		ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
+		status = AE_AML_OPERAND_TYPE;
+	}
+
+	/* The package must have at least two elements */
+
+	else if (info.return_object->package.count < 2) {
+		ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
+		status = AE_AML_NO_OPERAND;
+	}
+
+	/* The first two elements must both be of type Integer */
+
+	else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) ||
+			 (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) {
+		ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
+			acpi_ut_get_object_type_name (info.return_object->package.elements[0]),
+			acpi_ut_get_object_type_name (info.return_object->package.elements[1])));
+		status = AE_AML_OPERAND_TYPE;
+	}
+	else {
+		/*
+		 * Valid _Sx_ package size, type, and value
+		 */
+		*sleep_type_a = (u8) (info.return_object->package.elements[0])->integer.value;
+		*sleep_type_b = (u8) (info.return_object->package.elements[1])->integer.value;
+	}
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
+			acpi_gbl_sleep_state_names[sleep_state], info.return_object,
+			acpi_ut_get_object_type_name (info.return_object)));
+	}
+
+	acpi_ut_remove_reference (info.return_object);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_get_sleep_type_data);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_get_register_bit_mask
+ *
+ * PARAMETERS:  register_id         - Index of ACPI Register to access
+ *
+ * RETURN:      The bit mask to be used when accessing the register
+ *
+ * DESCRIPTION: Map register_id into a register bit mask.
+ *
+ ******************************************************************************/
+
+struct acpi_bit_register_info *
+acpi_hw_get_bit_register_info (
+	u32                             register_id)
+{
+	ACPI_FUNCTION_NAME ("hw_get_bit_register_info");
+
+
+	if (register_id > ACPI_BITREG_MAX) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid bit_register ID: %X\n", register_id));
+		return (NULL);
+	}
+
+	return (&acpi_gbl_bit_register_info[register_id]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_register
+ *
+ * PARAMETERS:  register_id     - ID of ACPI bit_register to access
+ *              return_value    - Value that was read from the register
+ *              Flags           - Lock the hardware or not
+ *
+ * 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,
+	u32                             flags)
+{
+	u32                             register_value = 0;
+	struct acpi_bit_register_info   *bit_reg_info;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_register");
+
+
+	/* 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) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (flags & ACPI_MTX_LOCK) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Read from the register */
+
+	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
+			  bit_reg_info->parent_register, &register_value);
+
+	if (flags & ACPI_MTX_LOCK) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+	}
+
+	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));
+	}
+
+	return_ACPI_STATUS (status);
+}
+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
+ *              Flags           - Lock the hardware or not
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: ACPI Bit Register write function.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_set_register (
+	u32                             register_id,
+	u32                             value,
+	u32                             flags)
+{
+	u32                             register_value = 0;
+	struct acpi_bit_register_info   *bit_reg_info;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("acpi_set_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_REPORT_ERROR (("Bad ACPI HW register_id: %X\n", register_id));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (flags & ACPI_MTX_LOCK) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Always do a register read first so we can insert the new bits  */
+
+	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
+			  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.
+	 */
+	switch (bit_reg_info->parent_register) {
+	case 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.
+		 */
+		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_MTX_DO_NOT_LOCK,
+					 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_MTX_DO_NOT_LOCK,
+				  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_MTX_DO_NOT_LOCK,
+				  ACPI_REGISTER_PM1_CONTROL, (u16) register_value);
+		break;
+
+
+	case ACPI_REGISTER_PM2_CONTROL:
+
+		status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
+				 ACPI_REGISTER_PM2_CONTROL, &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_cnt_blk.address)));
+
+		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_cnt_blk.address)));
+
+		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+				   ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
+		break;
+
+
+	default:
+		break;
+	}
+
+
+unlock_and_exit:
+
+	if (flags & ACPI_MTX_LOCK) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+	}
+
+	/* 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);
+}
+EXPORT_SYMBOL(acpi_set_register);
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_register_read
+ *
+ * PARAMETERS:  use_lock            - Mutex hw access
+ *              register_id         - register_iD + Offset
+ *              return_value        - Value that was read from the register
+ *
+ * RETURN:      Status and the value read.
+ *
+ * DESCRIPTION: Acpi register read function.  Registers are read at the
+ *              given offset.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_register_read (
+	u8                              use_lock,
+	u32                             register_id,
+	u32                             *return_value)
+{
+	u32                             value1 = 0;
+	u32                             value2 = 0;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("hw_register_read");
+
+
+	if (ACPI_MTX_LOCK == use_lock) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	switch (register_id) {
+	case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
+
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk);
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk);
+		value1 |= value2;
+		break;
+
+
+	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access */
+
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_xpm1a_enable);
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_xpm1b_enable);
+		value1 |= value2;
+		break;
+
+
+	case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
+
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk);
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk);
+		value1 |= value2;
+		break;
+
+
+	case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
+
+		status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk);
+		break;
+
+
+	case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
+
+		status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk);
+		break;
+
+	case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
+
+		status = acpi_os_read_port (acpi_gbl_FADT->smi_cmd, &value1, 8);
+		break;
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", register_id));
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+unlock_and_exit:
+	if (ACPI_MTX_LOCK == use_lock) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+	}
+
+	if (ACPI_SUCCESS (status)) {
+		*return_value = value1;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_register_write
+ *
+ * PARAMETERS:  use_lock            - Mutex hw access
+ *              register_id         - register_iD + Offset
+ *              Value               - The value to write
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acpi register Write function.  Registers are written at the
+ *              given offset.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_register_write (
+	u8                              use_lock,
+	u32                             register_id,
+	u32                             value)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("hw_register_write");
+
+
+	if (ACPI_MTX_LOCK == use_lock) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	switch (register_id) {
+	case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk);
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk);
+		break;
+
+
+	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1a_enable);
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1b_enable);
+		break;
+
+
+	case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
+		break;
+
+
+	case ACPI_REGISTER_PM1A_CONTROL:         /* 16-bit access */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
+		break;
+
+
+	case ACPI_REGISTER_PM1B_CONTROL:         /* 16-bit access */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
+		break;
+
+
+	case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
+
+		status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk);
+		break;
+
+
+	case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
+
+		status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk);
+		break;
+
+
+	case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
+
+		/* SMI_CMD is currently always in IO space */
+
+		status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, value, 8);
+		break;
+
+
+	default:
+		status = AE_BAD_PARAMETER;
+		break;
+	}
+
+unlock_and_exit:
+	if (ACPI_MTX_LOCK == use_lock) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_HARDWARE);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_low_level_read
+ *
+ * PARAMETERS:  Width               - 8, 16, or 32
+ *              Value               - Where the value is returned
+ *              Reg                 - GAS register structure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read from either memory or IO space.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_low_level_read (
+	u32                             width,
+	u32                             *value,
+	struct acpi_generic_address     *reg)
+{
+	u64                             address;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_NAME ("hw_low_level_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.
+	 */
+	if (!reg) {
+		return (AE_OK);
+	}
+
+	/* Get a local copy of the address.  Handles possible alignment issues */
+
+	ACPI_MOVE_64_TO_64 (&address, &reg->address);
+	if (!address) {
+		return (AE_OK);
+	}
+	*value = 0;
+
+	/*
+	 * Two address spaces supported: Memory or IO.
+	 * PCI_Config is not supported here because the GAS struct is insufficient
+	 */
+	switch (reg->address_space_id) {
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+
+		status = acpi_os_read_memory (
+				 (acpi_physical_address) address,
+				 value, width);
+		break;
+
+
+	case ACPI_ADR_SPACE_SYSTEM_IO:
+
+		status = acpi_os_read_port ((acpi_io_address) address,
+				 value, width);
+		break;
+
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unsupported address space: %X\n", reg->address_space_id));
+		return (AE_BAD_PARAMETER);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
+			*value, width,
+			ACPI_FORMAT_UINT64 (address),
+			acpi_ut_get_region_name (reg->address_space_id)));
+
+	return (status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_low_level_write
+ *
+ * PARAMETERS:  Width               - 8, 16, or 32
+ *              Value               - To be written
+ *              Reg                 - GAS register structure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write to either memory or IO space.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_hw_low_level_write (
+	u32                             width,
+	u32                             value,
+	struct acpi_generic_address     *reg)
+{
+	u64                             address;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_NAME ("hw_low_level_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.
+	 */
+	if (!reg) {
+		return (AE_OK);
+	}
+
+	/* Get a local copy of the address.  Handles possible alignment issues */
+
+	ACPI_MOVE_64_TO_64 (&address, &reg->address);
+	if (!address) {
+		return (AE_OK);
+	}
+
+	/*
+	 * Two address spaces supported: Memory or IO.
+	 * PCI_Config is not supported here because the GAS struct is insufficient
+	 */
+	switch (reg->address_space_id) {
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+
+		status = acpi_os_write_memory (
+				 (acpi_physical_address) address,
+				 value, width);
+		break;
+
+
+	case ACPI_ADR_SPACE_SYSTEM_IO:
+
+		status = acpi_os_write_port ((acpi_io_address) address,
+				 value, width);
+		break;
+
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unsupported address space: %X\n", reg->address_space_id));
+		return (AE_BAD_PARAMETER);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
+			value, width,
+			ACPI_FORMAT_UINT64 (address),
+			acpi_ut_get_region_name (reg->address_space_id)));
+
+	return (status);
+}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
new file mode 100644
index 0000000..77b3e9a
--- /dev/null
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -0,0 +1,582 @@
+
+/******************************************************************************
+ *
+ * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+
+#define _COMPONENT          ACPI_HARDWARE
+	 ACPI_MODULE_NAME    ("hwsleep")
+
+
+#define METHOD_NAME__BFS        "\\_BFS"
+#define METHOD_NAME__GTS        "\\_GTS"
+#define METHOD_NAME__PTS        "\\_PTS"
+#define METHOD_NAME__SST        "\\_SI._SST"
+#define METHOD_NAME__WAK        "\\_WAK"
+
+#define ACPI_SST_INDICATOR_OFF  0
+#define ACPI_SST_WORKING        1
+#define ACPI_SST_WAKING         2
+#define ACPI_SST_SLEEPING       3
+#define ACPI_SST_SLEEP_CONTEXT  4
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_set_firmware_waking_vector
+ *
+ * PARAMETERS:  physical_address    - Physical address of ACPI real mode
+ *                                    entry point.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: access function for d_firmware_waking_vector field in FACS
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_set_firmware_waking_vector (
+	acpi_physical_address physical_address)
+{
+
+	ACPI_FUNCTION_TRACE ("acpi_set_firmware_waking_vector");
+
+
+	/* Set the vector */
+
+	if (acpi_gbl_common_fACS.vector_width == 32) {
+		*(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector))
+				= (u32) physical_address;
+	}
+	else {
+		*acpi_gbl_common_fACS.firmware_waking_vector
+				= physical_address;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_firmware_waking_vector
+ *
+ * PARAMETERS:  *physical_address   - Output buffer where contents of
+ *                                    the firmware_waking_vector field of
+ *                                    the FACS will be stored.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Access function for firmware_waking_vector field in FACS
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_get_firmware_waking_vector (
+	acpi_physical_address *physical_address)
+{
+
+	ACPI_FUNCTION_TRACE ("acpi_get_firmware_waking_vector");
+
+
+	if (!physical_address) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Get the vector */
+
+	if (acpi_gbl_common_fACS.vector_width == 32) {
+		*physical_address = (acpi_physical_address)
+			*(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector));
+	}
+	else {
+		*physical_address =
+			*acpi_gbl_common_fACS.firmware_waking_vector;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+#endif
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_enter_sleep_state_prep
+ *
+ * PARAMETERS:  sleep_state         - Which sleep state to enter
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231)
+ *              This function must execute with interrupts enabled.
+ *              We break sleeping into 2 stages so that OSPM can handle
+ *              various OS-specific tasks between the two steps.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enter_sleep_state_prep (
+	u8                          sleep_state)
+{
+	acpi_status                 status;
+	struct acpi_object_list     arg_list;
+	union acpi_object           arg;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_prep");
+
+
+	/*
+	 * _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);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Setup parameter object */
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = sleep_state;
+
+	/* Run the _PTS and _GTS methods */
+
+	status = acpi_evaluate_object (NULL, METHOD_NAME__PTS, &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_evaluate_object (NULL, METHOD_NAME__GTS, &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Setup the argument to _SST */
+
+	switch (sleep_state) {
+	case ACPI_STATE_S0:
+		arg.integer.value = ACPI_SST_WORKING;
+		break;
+
+	case ACPI_STATE_S1:
+	case ACPI_STATE_S2:
+	case ACPI_STATE_S3:
+		arg.integer.value = ACPI_SST_SLEEPING;
+		break;
+
+	case ACPI_STATE_S4:
+		arg.integer.value = ACPI_SST_SLEEP_CONTEXT;
+		break;
+
+	default:
+		arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */
+		break;
+	}
+
+	/* Set the system indicators to show the desired sleep state. */
+
+	status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_enter_sleep_state
+ *
+ * PARAMETERS:  sleep_state         - Which sleep state to enter
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
+ *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+acpi_status asmlinkage
+acpi_enter_sleep_state (
+	u8                              sleep_state)
+{
+	u32                             PM1Acontrol;
+	u32                             PM1Bcontrol;
+	struct acpi_bit_register_info   *sleep_type_reg_info;
+	struct acpi_bit_register_info   *sleep_enable_reg_info;
+	u32                             in_value;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state");
+
+
+	if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
+		(acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
+		ACPI_REPORT_ERROR (("Sleep values out of range: A=%X B=%X\n",
+			acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
+		return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+	}
+
+	sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
+	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, ACPI_MTX_DO_NOT_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Clear all fixed and general purpose status bits */
+
+	status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * 1) Disable/Clear all GPEs
+	 * 2) Enable all wakeup GPEs
+	 */
+	status = acpi_hw_disable_all_gpes (ACPI_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	acpi_gbl_system_awake_and_running = FALSE;
+
+	status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get current value of PM1A control */
+
+	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+	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 */
+
+	PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask);
+	PM1Bcontrol = PM1Acontrol;
+
+	/* Insert 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);
+
+	/*
+	 * We split the writes of SLP_TYP and SLP_EN to workaround
+	 * poorly implemented hardware.
+	 */
+
+	/* Write #1: fill in SLP_TYP data */
+
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Insert SLP_ENABLE bit */
+
+	PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
+	PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
+
+	/* Write #2: SLP_TYP + SLP_EN */
+
+	ACPI_FLUSH_CPU_CACHE ();
+
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (sleep_state > ACPI_STATE_S3) {
+		/*
+		 * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that
+		 * we are still executing!)
+		 *
+		 * 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
+		 * away entirely.
+		 */
+		acpi_os_stall (10000000);
+
+		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL,
+				 sleep_enable_reg_info->access_bit_mask);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Wait until we enter sleep state */
+
+	do {
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/* Spin until we wake */
+
+	} while (!in_value);
+
+	return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_enter_sleep_state);
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_enter_sleep_state_s4bios
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform a S4 bios request.
+ *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+acpi_status asmlinkage
+acpi_enter_sleep_state_s4bios (
+	void)
+{
+	u32                             in_value;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
+
+
+	status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * 1) Disable/Clear all GPEs
+	 * 2) Enable all wakeup GPEs
+	 */
+	status = acpi_hw_disable_all_gpes (ACPI_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	acpi_gbl_system_awake_and_running = FALSE;
+
+	status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	ACPI_FLUSH_CPU_CACHE ();
+
+	status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8);
+
+	do {
+		acpi_os_stall(1000);
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	} while (!in_value);
+
+	return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_leave_sleep_state
+ *
+ * PARAMETERS:  sleep_state         - Which sleep state we just exited
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
+ *              Called with interrupts ENABLED.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_leave_sleep_state (
+	u8                              sleep_state)
+{
+	struct acpi_object_list         arg_list;
+	union acpi_object               arg;
+	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;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state");
+
+
+	/*
+	 * Set SLP_TYPE and SLP_EN to state S0.
+	 * This is unclear from the ACPI Spec, but it is required
+	 * by some machines.
+	 */
+	status = acpi_get_sleep_type_data (ACPI_STATE_S0,
+			  &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b);
+	if (ACPI_SUCCESS (status)) {
+		sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
+		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_MTX_DO_NOT_LOCK,
+				 ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+		if (ACPI_SUCCESS (status)) {
+			/* Clear SLP_EN and SLP_TYP fields */
+
+			PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
+					   sleep_enable_reg_info->access_bit_mask);
+			PM1Bcontrol = PM1Acontrol;
+
+			/* Insert 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);
+
+			/* Just ignore any errors */
+
+			(void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+					  ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+			(void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+					  ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+		}
+	}
+
+	/* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
+
+	acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
+
+	/* Setup parameter object */
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+
+	/* Ignore any errors from these methods */
+
+	arg.integer.value = ACPI_SST_WAKING;
+	status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+	}
+
+	arg.integer.value = sleep_state;
+	status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
+	}
+
+	status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status)));
+	}
+	/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
+
+	/*
+	 * Restore the GPEs:
+	 * 1) Disable/Clear all GPEs
+	 * 2) Enable all runtime GPEs
+	 */
+	status = acpi_hw_disable_all_gpes (ACPI_NOT_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	acpi_gbl_system_awake_and_running = TRUE;
+
+	status = acpi_hw_enable_all_runtime_gpes (ACPI_NOT_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Enable power button */
+
+	(void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
+			1, ACPI_MTX_DO_NOT_LOCK);
+	(void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
+			1, ACPI_MTX_DO_NOT_LOCK);
+
+	arg.integer.value = ACPI_SST_WORKING;
+	status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+	}
+
+	return_ACPI_STATUS (status);
+}
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
new file mode 100644
index 0000000..1906167
--- /dev/null
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -0,0 +1,203 @@
+
+/******************************************************************************
+ *
+ * Name: hwtimer.c - ACPI Power Management Timer Interface
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+
+#define _COMPONENT          ACPI_HARDWARE
+	 ACPI_MODULE_NAME    ("hwtimer")
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_timer_resolution
+ *
+ * PARAMETERS:  Resolution          - Where the resolution is returned
+ *
+ * RETURN:      Status and timer resolution
+ *
+ * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_timer_resolution (
+	u32                             *resolution)
+{
+	ACPI_FUNCTION_TRACE ("acpi_get_timer_resolution");
+
+
+	if (!resolution) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (0 == acpi_gbl_FADT->tmr_val_ext) {
+		*resolution = 24;
+	}
+	else {
+		*resolution = 32;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_timer
+ *
+ * PARAMETERS:  Ticks               - Where the timer value is returned
+ *
+ * RETURN:      Status and current ticks
+ *
+ * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_timer (
+	u32                             *ticks)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_timer");
+
+
+	if (!ticks) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk);
+
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_get_timer);
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_timer_duration
+ *
+ * PARAMETERS:  start_ticks         - Starting timestamp
+ *              end_ticks           - End timestamp
+ *              time_elapsed        - Where the elapsed time is returned
+ *
+ * RETURN:      Status and time_elapsed
+ *
+ * DESCRIPTION: Computes the time elapsed (in microseconds) between two
+ *              PM Timer time stamps, taking into account the possibility of
+ *              rollovers, the timer resolution, and timer frequency.
+ *
+ *              The PM Timer's clock ticks at roughly 3.6 times per
+ *              _microsecond_, and its clock continues through Cx state
+ *              transitions (unlike many CPU timestamp counters) -- making it
+ *              a versatile and accurate timer.
+ *
+ *              Note that this function accommodates only a single timer
+ *              rollover.  Thus for 24-bit timers, this function should only
+ *              be used for calculating durations less than ~4.6 seconds
+ *              (~20 minutes for 32-bit timers) -- calculations below:
+ *
+ *              2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
+ *              2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_timer_duration (
+	u32                             start_ticks,
+	u32                             end_ticks,
+	u32                             *time_elapsed)
+{
+	acpi_status                     status;
+	u32                             delta_ticks;
+	acpi_integer                    quotient;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_timer_duration");
+
+
+	if (!time_elapsed) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Compute Tick Delta:
+	 * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
+	 */
+	if (start_ticks < end_ticks) {
+		delta_ticks = end_ticks - start_ticks;
+	}
+	else if (start_ticks > end_ticks) {
+		if (0 == acpi_gbl_FADT->tmr_val_ext) {
+			/* 24-bit Timer */
+
+			delta_ticks = (((0x00FFFFFF - start_ticks) + end_ticks) & 0x00FFFFFF);
+		}
+		else {
+			/* 32-bit Timer */
+
+			delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks;
+		}
+	}
+	else /* start_ticks == end_ticks */ {
+		*time_elapsed = 0;
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * Compute Duration (Requires a 64-bit multiply and divide):
+	 *
+	 * time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY;
+	 */
+	status = acpi_ut_short_divide (((u64) delta_ticks) * 1000000,
+			 PM_TIMER_FREQUENCY, &quotient, NULL);
+
+	*time_elapsed = (u32) quotient;
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_get_timer_duration);
+
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
new file mode 100644
index 0000000..0fb731a
--- /dev/null
+++ b/drivers/acpi/ibm_acpi.c
@@ -0,0 +1,1242 @@
+/*
+ *  ibm_acpi.c - IBM ThinkPad ACPI Extras
+ *
+ *
+ *  Copyright (C) 2004 Borislav Deianov
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Changelog:
+ *
+ *  2004-08-09	0.1	initial release, support for X series
+ *  2004-08-14	0.2	support for T series, X20
+ *			bluetooth enable/disable
+ *			hotkey events disabled by default
+ *			removed fan control, currently useless
+ *  2004-08-17	0.3	support for R40
+ *			lcd off, brightness control
+ *			thinklight on/off
+ *  2004-09-16	0.4	support for module parameters
+ *			hotkey mask can be prefixed by 0x
+ *			video output switching
+ *			video expansion control
+ *			ultrabay eject support
+ *			removed lcd brightness/on/off control, didn't work
+ *  2004-10-18	0.5	thinklight support on A21e, G40, R32, T20, T21, X20
+ *			proc file format changed
+ *			video_switch command
+ *			experimental cmos control
+ *			experimental led control
+ *			experimental acpi sounds
+ *  2004-10-19	0.6	use acpi_bus_register_driver() to claim HKEY device
+ *  2004-10-23	0.7	fix module loading on A21e, A22p, T20, T21, X20
+ *			fix LED control on A21e
+ *  2004-11-08	0.8	fix init error case, don't return from a macro
+ *				thanks to Chris Wright <chrisw@osdl.org>
+ */
+
+#define IBM_VERSION "0.8"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_drivers.h>
+#include <acpi/acnamesp.h>
+
+#define IBM_NAME "ibm"
+#define IBM_DESC "IBM ThinkPad ACPI Extras"
+#define IBM_FILE "ibm_acpi"
+#define IBM_URL "http://ibm-acpi.sf.net/"
+
+#define IBM_DIR IBM_NAME
+
+#define IBM_LOG IBM_FILE ": "
+#define IBM_ERR	   KERN_ERR    IBM_LOG
+#define IBM_NOTICE KERN_NOTICE IBM_LOG
+#define IBM_INFO   KERN_INFO   IBM_LOG
+#define IBM_DEBUG  KERN_DEBUG  IBM_LOG
+
+#define IBM_MAX_ACPI_ARGS 3
+
+#define __unused __attribute__ ((unused))
+
+static int experimental;
+module_param(experimental, int, 0);
+
+static acpi_handle root_handle = NULL;
+
+#define IBM_HANDLE(object, parent, paths...)			\
+	static acpi_handle  object##_handle;			\
+	static acpi_handle *object##_parent = &parent##_handle;	\
+	static char        *object##_paths[] = { paths }
+
+IBM_HANDLE(ec, root,
+	   "\\_SB.PCI0.ISA.EC",    /* A21e, A22p, T20, T21, X20 */
+	   "\\_SB.PCI0.LPC.EC",    /* all others */
+);
+
+IBM_HANDLE(vid, root, 
+	   "\\_SB.PCI0.VID",       /* A21e, G40, X30, X40 */
+	   "\\_SB.PCI0.AGP.VID",   /* all others */
+);
+
+IBM_HANDLE(cmos, root,
+	   "\\UCMS",               /* R50, R50p, R51, T4x, X31, X40 */
+	   "\\CMOS",               /* A3x, G40, R32, T23, T30, X22, X24, X30 */
+	   "\\CMS",                /* R40, R40e */
+);                                 /* A21e, A22p, T20, T21, X20 */
+
+IBM_HANDLE(dock, root,
+	   "\\_SB.GDCK",           /* X30, X31, X40 */
+	   "\\_SB.PCI0.DOCK",      /* A22p, T20, T21, X20 */
+	   "\\_SB.PCI0.PCI1.DOCK", /* all others */
+);                                 /* A21e, G40, R32, R40, R40e */
+
+IBM_HANDLE(bay, root,
+	   "\\_SB.PCI0.IDE0.SCND.MSTR");      /* all except A21e */
+IBM_HANDLE(bayej, root,
+	   "\\_SB.PCI0.IDE0.SCND.MSTR._EJ0"); /* all except A2x, A3x */
+
+IBM_HANDLE(lght, root, "\\LGHT");  /* A21e, A22p, T20, T21, X20 */
+IBM_HANDLE(hkey, ec,   "HKEY");    /* all */
+IBM_HANDLE(led,  ec,   "LED");     /* all except A21e, A22p, T20, T21, X20 */
+IBM_HANDLE(sysl, ec,   "SYSL");    /* A21e, A22p, T20, T21, X20 */
+IBM_HANDLE(bled, ec,   "BLED");    /* A22p, T20, T21, X20 */
+IBM_HANDLE(beep, ec,   "BEEP");    /* all models */
+
+struct ibm_struct {
+	char *name;
+
+	char *hid;
+	struct acpi_driver *driver;
+	
+	int  (*init)   (struct ibm_struct *);
+	int  (*read)   (struct ibm_struct *, char *);
+	int  (*write)  (struct ibm_struct *, char *);
+	void (*exit)   (struct ibm_struct *);
+
+	void (*notify) (struct ibm_struct *, u32);	
+	acpi_handle *handle;
+	int type;
+	struct acpi_device *device;
+
+	int driver_registered;
+	int proc_created;
+	int init_called;
+	int notify_installed;
+
+	int supported;
+	union {
+		struct {
+			int status;
+			int mask;
+		} hotkey;
+		struct {
+			int autoswitch;
+		} video;
+	} state;
+
+	int experimental;
+};
+
+static struct proc_dir_entry *proc_dir = NULL;
+
+#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
+#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
+#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
+
+static int acpi_evalf(acpi_handle handle,
+		      void *res, char *method, char *fmt, ...)
+{
+	char *fmt0 = fmt;
+        struct acpi_object_list	params;
+        union acpi_object	in_objs[IBM_MAX_ACPI_ARGS];
+        struct acpi_buffer	result;
+        union acpi_object	out_obj;
+        acpi_status		status;
+	va_list			ap;
+	char			res_type;
+	int			success;
+	int			quiet;
+
+	if (!*fmt) {
+		printk(IBM_ERR "acpi_evalf() called with empty format\n");
+		return 0;
+	}
+
+	if (*fmt == 'q') {
+		quiet = 1;
+		fmt++;
+	} else
+		quiet = 0;
+
+	res_type = *(fmt++);
+
+	params.count = 0;
+	params.pointer = &in_objs[0];
+
+	va_start(ap, fmt);
+	while (*fmt) {
+		char c = *(fmt++);
+		switch (c) {
+		case 'd':	/* int */
+			in_objs[params.count].integer.value = va_arg(ap, int);
+			in_objs[params.count++].type = ACPI_TYPE_INTEGER;
+			break;
+		/* add more types as needed */
+		default:
+			printk(IBM_ERR "acpi_evalf() called "
+			       "with invalid format character '%c'\n", c);
+			return 0;
+		}
+	}
+	va_end(ap);
+
+	result.length = sizeof(out_obj);
+	result.pointer = &out_obj;
+
+	status = acpi_evaluate_object(handle, method, &params, &result);
+
+	switch (res_type) {
+	case 'd':	/* int */
+		if (res)
+			*(int *)res = out_obj.integer.value;
+		success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER;
+		break;
+	case 'v':	/* void */
+		success = status == AE_OK;
+		break;
+	/* add more types as needed */
+	default:
+		printk(IBM_ERR "acpi_evalf() called "
+		       "with invalid format character '%c'\n", res_type);
+		return 0;
+	}
+
+	if (!success && !quiet)
+		printk(IBM_ERR "acpi_evalf(%s, %s, ...) failed: %d\n",
+		       method, fmt0, status);
+
+	return success;
+}
+
+static void __unused acpi_print_int(acpi_handle handle, char *method)
+{
+	int i;
+
+	if (acpi_evalf(handle, &i, method, "d"))
+		printk(IBM_INFO "%s = 0x%x\n", method, i);
+	else
+		printk(IBM_ERR "error calling %s\n", method);
+}
+
+static char *next_cmd(char **cmds)
+{
+	char *start = *cmds;
+	char *end;
+
+	while ((end = strchr(start, ',')) && end == start)
+		start = end + 1;
+
+	if (!end)
+		return NULL;
+
+	*end = 0;
+	*cmds = end + 1;
+	return start;
+}
+
+static int driver_init(struct ibm_struct *ibm)
+{
+	printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
+	printk(IBM_INFO "%s\n", IBM_URL);
+
+	return 0;
+}
+
+static int driver_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+
+	len += sprintf(p + len, "driver:\t\t%s\n", IBM_DESC);
+	len += sprintf(p + len, "version:\t%s\n", IBM_VERSION);
+
+	return len;
+}
+
+static int hotkey_get(struct ibm_struct *ibm, int *status, int *mask)
+{
+	if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
+		return -EIO;
+	if (ibm->supported) {
+		if (!acpi_evalf(hkey_handle, mask, "DHKN", "qd"))
+			return -EIO;
+	} else {
+		*mask = ibm->state.hotkey.mask;
+	}
+	return 0;
+}
+
+static int hotkey_set(struct ibm_struct *ibm, int status, int mask)
+{
+	int i;
+
+	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
+		return -EIO;
+
+	if (!ibm->supported)
+		return 0;
+
+	for (i=0; i<32; i++) {
+		int bit = ((1 << i) & mask) != 0;
+		if (!acpi_evalf(hkey_handle, NULL, "MHKM", "vdd", i+1, bit))
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int hotkey_init(struct ibm_struct *ibm)
+{
+	int ret;
+
+	ibm->supported = 1;
+	ret = hotkey_get(ibm,
+			 &ibm->state.hotkey.status,
+			 &ibm->state.hotkey.mask);
+	if (ret < 0) {
+		/* mask not supported on A21e, A22p, T20, T21, X20, X22, X24 */
+		ibm->supported = 0;
+		ret = hotkey_get(ibm,
+				 &ibm->state.hotkey.status,
+				 &ibm->state.hotkey.mask);
+	}
+
+	return ret;
+}	
+
+static int hotkey_read(struct ibm_struct *ibm, char *p)
+{
+	int status, mask;
+	int len = 0;
+
+	if (hotkey_get(ibm, &status, &mask) < 0)
+		return -EIO;
+
+	len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
+	if (ibm->supported) {
+		len += sprintf(p + len, "mask:\t\t0x%04x\n", mask);
+		len += sprintf(p + len,
+			       "commands:\tenable, disable, reset, <mask>\n");
+	} else {
+		len += sprintf(p + len, "mask:\t\tnot supported\n");
+		len += sprintf(p + len, "commands:\tenable, disable, reset\n");
+	}
+
+	return len;
+}
+
+static int hotkey_write(struct ibm_struct *ibm, char *buf)
+{
+	int status, mask;
+	char *cmd;
+	int do_cmd = 0;
+
+	if (hotkey_get(ibm, &status, &mask) < 0)
+		return -ENODEV;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (strlencmp(cmd, "enable") == 0) {
+			status = 1;
+		} else if (strlencmp(cmd, "disable") == 0) {
+			status = 0;
+		} else if (strlencmp(cmd, "reset") == 0) {
+			status = ibm->state.hotkey.status;
+			mask   = ibm->state.hotkey.mask;
+		} else if (sscanf(cmd, "0x%x", &mask) == 1) {
+			/* mask set */
+		} else if (sscanf(cmd, "%x", &mask) == 1) {
+			/* mask set */
+		} else
+			return -EINVAL;
+		do_cmd = 1;
+	}
+
+	if (do_cmd && hotkey_set(ibm, status, mask) < 0)
+		return -EIO;
+
+	return 0;
+}	
+
+static void hotkey_exit(struct ibm_struct *ibm)
+{
+	hotkey_set(ibm, ibm->state.hotkey.status, ibm->state.hotkey.mask);
+}
+
+static void hotkey_notify(struct ibm_struct *ibm, u32 event)
+{
+	int hkey;
+
+	if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
+		acpi_bus_generate_event(ibm->device, event, hkey);
+	else {
+		printk(IBM_ERR "unknown hotkey event %d\n", event);
+		acpi_bus_generate_event(ibm->device, event, 0);
+	}	
+}
+
+static int bluetooth_init(struct ibm_struct *ibm)
+{
+	/* bluetooth not supported on A21e, G40, T20, T21, X20 */
+	ibm->supported = acpi_evalf(hkey_handle, NULL, "GBDC", "qv");
+
+	return 0;
+}
+
+static int bluetooth_status(struct ibm_struct *ibm)
+{
+	int status;
+
+	if (!ibm->supported || !acpi_evalf(hkey_handle, &status, "GBDC", "d"))
+		status = 0;
+
+	return status;
+}
+
+static int bluetooth_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+	int status = bluetooth_status(ibm);
+
+	if (!ibm->supported)
+		len += sprintf(p + len, "status:\t\tnot supported\n");
+	else if (!(status & 1))
+		len += sprintf(p + len, "status:\t\tnot installed\n");
+	else {
+		len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 1));
+		len += sprintf(p + len, "commands:\tenable, disable\n");
+	}
+
+	return len;
+}
+
+static int bluetooth_write(struct ibm_struct *ibm, char *buf)
+{
+	int status = bluetooth_status(ibm);
+	char *cmd;
+	int do_cmd = 0;
+
+	if (!ibm->supported)
+		return -EINVAL;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (strlencmp(cmd, "enable") == 0) {
+			status |= 2;
+		} else if (strlencmp(cmd, "disable") == 0) {
+			status &= ~2;
+		} else
+			return -EINVAL;
+		do_cmd = 1;
+	}
+
+	if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
+	    return -EIO;
+
+	return 0;
+}
+
+static int video_init(struct ibm_struct *ibm)
+{
+	if (!acpi_evalf(vid_handle,
+			&ibm->state.video.autoswitch, "^VDEE", "d"))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int video_status(struct ibm_struct *ibm)
+{
+	int status = 0;
+	int i;
+
+	acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
+	if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
+		status |= 0x02 * i;
+
+	acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0);
+	if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
+		status |= 0x01 * i;
+	if (acpi_evalf(NULL, &i, "\\VCDD", "d"))
+		status |= 0x08 * i;
+
+	if (acpi_evalf(vid_handle, &i, "^VDEE", "d"))
+		status |= 0x10 * (i & 1);
+
+	return status;
+}
+
+static int video_read(struct ibm_struct *ibm, char *p)
+{
+	int status = video_status(ibm);
+	int len = 0;
+
+	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
+	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
+	len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
+	len += sprintf(p + len, "auto:\t\t%s\n", enabled(status, 4));
+	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable, "
+		       "crt_enable, crt_disable\n");
+	len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable, "
+		       "auto_enable, auto_disable\n");
+	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
+
+	return len;
+}
+
+static int video_write(struct ibm_struct *ibm, char *buf)
+{
+	char *cmd;
+	int enable, disable, status;
+
+	enable = disable = 0;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (strlencmp(cmd, "lcd_enable") == 0) {
+			enable |= 0x01;
+		} else if (strlencmp(cmd, "lcd_disable") == 0) {
+			disable |= 0x01;
+		} else if (strlencmp(cmd, "crt_enable") == 0) {
+			enable |= 0x02;
+		} else if (strlencmp(cmd, "crt_disable") == 0) {
+			disable |= 0x02;
+		} else if (strlencmp(cmd, "dvi_enable") == 0) {
+			enable |= 0x08;
+		} else if (strlencmp(cmd, "dvi_disable") == 0) {
+			disable |= 0x08;
+		} else if (strlencmp(cmd, "auto_enable") == 0) {
+			if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
+				return -EIO;
+		} else if (strlencmp(cmd, "auto_disable") == 0) {
+			if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 0))
+				return -EIO;
+		} else if (strlencmp(cmd, "video_switch") == 0) {
+			int autoswitch;
+			if (!acpi_evalf(vid_handle, &autoswitch, "^VDEE", "d"))
+				return -EIO;
+			if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
+				return -EIO;
+			if (!acpi_evalf(vid_handle, NULL, "VSWT", "v"))
+				return -EIO;
+			if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd",
+					autoswitch))
+				return -EIO;
+		} else if (strlencmp(cmd, "expand_toggle") == 0) {
+			if (!acpi_evalf(NULL, NULL, "\\VEXP", "v"))
+				return -EIO;
+		} else
+			return -EINVAL;
+	}
+
+	if (enable || disable) {
+		status = (video_status(ibm) & 0x0f & ~disable) | enable;
+		if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80))
+			return -EIO;
+		if (!acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1))
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static void video_exit(struct ibm_struct *ibm)
+{
+	acpi_evalf(vid_handle, NULL, "_DOS", "vd",
+		   ibm->state.video.autoswitch);
+}
+
+static int light_init(struct ibm_struct *ibm)
+{
+	/* kblt not supported on G40, R32, X20 */
+	ibm->supported = acpi_evalf(ec_handle, NULL, "KBLT", "qv");
+
+	return 0;
+}
+
+static int light_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+	int status = 0;
+
+	if (ibm->supported) {
+		if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
+			return -EIO;
+		len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
+	} else
+		len += sprintf(p + len, "status:\t\tunknown\n");
+
+	len += sprintf(p + len, "commands:\ton, off\n");
+
+	return len;
+}
+
+static int light_write(struct ibm_struct *ibm, char *buf)
+{
+	int cmos_cmd, lght_cmd;
+	char *cmd;
+	int success;
+	
+	while ((cmd = next_cmd(&buf))) {
+		if (strlencmp(cmd, "on") == 0) {
+			cmos_cmd = 0x0c;
+			lght_cmd = 1;
+		} else if (strlencmp(cmd, "off") == 0) {
+			cmos_cmd = 0x0d;
+			lght_cmd = 0;
+		} else
+			return -EINVAL;
+		
+		success = cmos_handle ?
+			acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
+			acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
+		if (!success)
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int _sta(acpi_handle handle)
+{
+	int status;
+
+	if (!handle || !acpi_evalf(handle, &status, "_STA", "d"))
+		status = 0;
+
+	return status;
+}
+
+#define dock_docked() (_sta(dock_handle) & 1)
+
+static int dock_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+	int docked = dock_docked();
+
+	if (!dock_handle)
+		len += sprintf(p + len, "status:\t\tnot supported\n");
+	else if (!docked)
+		len += sprintf(p + len, "status:\t\tundocked\n");
+	else {
+		len += sprintf(p + len, "status:\t\tdocked\n");
+		len += sprintf(p + len, "commands:\tdock, undock\n");
+	}
+
+	return len;
+}
+
+static int dock_write(struct ibm_struct *ibm, char *buf)
+{
+	char *cmd;
+
+	if (!dock_docked())
+		return -EINVAL;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (strlencmp(cmd, "undock") == 0) {
+			if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0))
+				return -EIO;
+			if (!acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1))
+				return -EIO;
+		} else if (strlencmp(cmd, "dock") == 0) {
+			if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1))
+				return -EIO;
+		} else
+			return -EINVAL;
+	}
+
+	return 0;
+}	
+
+static void dock_notify(struct ibm_struct *ibm, u32 event)
+{
+	int docked = dock_docked();
+
+	if (event == 3 && docked)
+		acpi_bus_generate_event(ibm->device, event, 1); /* button */
+	else if (event == 3 && !docked)
+		acpi_bus_generate_event(ibm->device, event, 2); /* undock */
+	else if (event == 0 && docked)
+		acpi_bus_generate_event(ibm->device, event, 3); /* dock */
+	else {
+		printk(IBM_ERR "unknown dock event %d, status %d\n",
+		       event, _sta(dock_handle));
+		acpi_bus_generate_event(ibm->device, event, 0); /* unknown */
+	}
+}
+
+#define bay_occupied() (_sta(bay_handle) & 1)
+
+static int bay_init(struct ibm_struct *ibm)
+{
+	/* bay not supported on A21e, A22p, A31, A31p, G40, R32, R40e */
+	ibm->supported = bay_handle && bayej_handle &&
+		acpi_evalf(bay_handle, NULL, "_STA", "qv");
+
+	return 0;
+}
+
+static int bay_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+	int occupied = bay_occupied();
+	
+	if (!ibm->supported)
+		len += sprintf(p + len, "status:\t\tnot supported\n");
+	else if (!occupied)
+		len += sprintf(p + len, "status:\t\tunoccupied\n");
+	else {
+		len += sprintf(p + len, "status:\t\toccupied\n");
+		len += sprintf(p + len, "commands:\teject\n");
+	}
+
+	return len;
+}
+
+static int bay_write(struct ibm_struct *ibm, char *buf)
+{
+	char *cmd;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (strlencmp(cmd, "eject") == 0) {
+			if (!ibm->supported ||
+			    !acpi_evalf(bay_handle, NULL, "_EJ0", "vd", 1))
+				return -EIO;
+		} else
+			return -EINVAL;
+	}
+
+	return 0;
+}	
+
+static void bay_notify(struct ibm_struct *ibm, u32 event)
+{
+	acpi_bus_generate_event(ibm->device, event, 0);
+}
+
+static int cmos_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+
+	/* cmos not supported on A21e, A22p, T20, T21, X20 */
+	if (!cmos_handle)
+		len += sprintf(p + len, "status:\t\tnot supported\n");
+	else {
+		len += sprintf(p + len, "status:\t\tsupported\n");
+		len += sprintf(p + len, "commands:\t<int>\n");
+	}
+
+	return len;
+}
+
+static int cmos_write(struct ibm_struct *ibm, char *buf)
+{
+	char *cmd;
+	int cmos_cmd;
+
+	if (!cmos_handle)
+		return -EINVAL;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (sscanf(cmd, "%u", &cmos_cmd) == 1) {
+			/* cmos_cmd set */
+		} else
+			return -EINVAL;
+
+		if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd))
+			return -EIO;
+	}
+
+	return 0;
+}	
+		
+static int led_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+
+	len += sprintf(p + len, "commands:\t"
+		       "<int> on, <int> off, <int> blink\n");
+
+	return len;
+}
+
+static int led_write(struct ibm_struct *ibm, char *buf)
+{
+	char *cmd;
+	unsigned int led;
+	int led_cmd, sysl_cmd, bled_a, bled_b;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (sscanf(cmd, "%u", &led) != 1)
+			return -EINVAL;
+
+		if (strstr(cmd, "blink")) {
+			led_cmd = 0xc0;
+			sysl_cmd = 2;
+			bled_a = 2;
+			bled_b = 1;
+		} else if (strstr(cmd, "on")) {
+			led_cmd = 0x80;
+			sysl_cmd = 1;
+			bled_a = 2;
+			bled_b = 0;
+		} else if (strstr(cmd, "off")) {
+			led_cmd = sysl_cmd = bled_a = bled_b = 0;
+		} else
+			return -EINVAL;
+		
+		if (led_handle) {
+			if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+					led, led_cmd))
+				return -EIO;
+		} else if (led < 2) {
+			if (acpi_evalf(sysl_handle, NULL, NULL, "vdd",
+				       led, sysl_cmd))
+				return -EIO;
+		} else if (led == 2 && bled_handle) {
+			if (acpi_evalf(bled_handle, NULL, NULL, "vdd",
+				       bled_a, bled_b))
+				return -EIO;
+		} else
+			return -EINVAL;
+	}
+
+	return 0;
+}	
+		
+static int beep_read(struct ibm_struct *ibm, char *p)
+{
+	int len = 0;
+
+	len += sprintf(p + len, "commands:\t<int>\n");
+
+	return len;
+}
+
+static int beep_write(struct ibm_struct *ibm, char *buf)
+{
+	char *cmd;
+	int beep_cmd;
+
+	while ((cmd = next_cmd(&buf))) {
+		if (sscanf(cmd, "%u", &beep_cmd) == 1) {
+			/* beep_cmd set */
+		} else
+			return -EINVAL;
+
+		if (!acpi_evalf(beep_handle, NULL, NULL, "vd", beep_cmd))
+			return -EIO;
+	}
+
+	return 0;
+}	
+		
+static struct ibm_struct ibms[] = {
+	{
+		.name	= "driver",
+		.init	= driver_init,
+		.read	= driver_read,
+	},
+	{
+		.name	= "hotkey",
+		.hid	= "IBM0068",
+		.init	= hotkey_init,
+		.read	= hotkey_read,
+		.write	= hotkey_write,
+		.exit	= hotkey_exit,
+		.notify	= hotkey_notify,
+		.handle	= &hkey_handle,
+		.type	= ACPI_DEVICE_NOTIFY,
+	},
+	{
+		.name	= "bluetooth",
+		.init	= bluetooth_init,
+		.read	= bluetooth_read,
+		.write	= bluetooth_write,
+	},
+	{
+		.name	= "video",
+		.init	= video_init,
+		.read	= video_read,
+		.write	= video_write,
+		.exit	= video_exit,
+	},
+	{
+		.name	= "light",
+		.init	= light_init,
+		.read	= light_read,
+		.write	= light_write,
+	},
+	{
+		.name	= "dock",
+		.read	= dock_read,
+		.write	= dock_write,
+		.notify	= dock_notify,
+		.handle	= &dock_handle,
+		.type	= ACPI_SYSTEM_NOTIFY,
+	},
+	{
+		.name	= "bay",
+		.init	= bay_init,
+		.read	= bay_read,
+		.write	= bay_write,
+		.notify	= bay_notify,
+		.handle	= &bay_handle,
+		.type	= ACPI_SYSTEM_NOTIFY,
+	},
+	{
+		.name	= "cmos",
+		.read	= cmos_read,
+		.write	= cmos_write,
+		.experimental = 1,
+	},
+	{
+		.name	= "led",
+		.read	= led_read,
+		.write	= led_write,
+		.experimental = 1,
+	},
+	{
+		.name	= "beep",
+		.read	= beep_read,
+		.write	= beep_write,
+		.experimental = 1,
+	},
+};
+#define NUM_IBMS (sizeof(ibms)/sizeof(ibms[0]))
+
+static int dispatch_read(char *page, char **start, off_t off, int count,
+			 int *eof, void *data)
+{
+	struct ibm_struct *ibm = (struct ibm_struct *)data;
+	int len;
+	
+	if (!ibm || !ibm->read)
+		return -EINVAL;
+
+	len = ibm->read(ibm, page);
+	if (len < 0)
+		return len;
+
+	if (len <= off + count)
+		*eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+
+static int dispatch_write(struct file *file, const char __user *userbuf,
+			  unsigned long count, void *data)
+{
+	struct ibm_struct *ibm = (struct ibm_struct *)data;
+	char *kernbuf;
+	int ret;
+
+	if (!ibm || !ibm->write)
+		return -EINVAL;
+
+	kernbuf = kmalloc(count + 2, GFP_KERNEL);
+	if (!kernbuf)
+		return -ENOMEM;
+
+        if (copy_from_user(kernbuf, userbuf, count)) {
+		kfree(kernbuf);
+                return -EFAULT;
+	}
+
+	kernbuf[count] = 0;
+	strcat(kernbuf, ",");
+	ret = ibm->write(ibm, kernbuf);
+	if (ret == 0)
+		ret = count;
+
+	kfree(kernbuf);
+
+        return ret;
+}
+
+static void dispatch_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct ibm_struct *ibm = (struct ibm_struct *)data;
+
+	if (!ibm || !ibm->notify)
+		return;
+
+	ibm->notify(ibm, event);
+}
+
+static int setup_notify(struct ibm_struct *ibm)
+{
+	acpi_status status;
+	int ret;
+
+	if (!*ibm->handle)
+		return 0;
+
+	ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
+	if (ret < 0) {
+		printk(IBM_ERR "%s device not present\n", ibm->name);
+		return 0;
+	}
+
+	acpi_driver_data(ibm->device) = ibm;
+	sprintf(acpi_device_class(ibm->device), "%s/%s", IBM_NAME, ibm->name);
+
+	status = acpi_install_notify_handler(*ibm->handle, ibm->type,
+					     dispatch_notify, ibm);
+	if (ACPI_FAILURE(status)) {
+		printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
+		       ibm->name, status);
+		return -ENODEV;
+	}
+
+	ibm->notify_installed = 1;
+
+	return 0;
+}
+
+static int device_add(struct acpi_device *device)
+{
+	return 0;
+}
+
+static int register_driver(struct ibm_struct *ibm)
+{
+	int ret;
+
+	ibm->driver = kmalloc(sizeof(struct acpi_driver), GFP_KERNEL);
+	if (!ibm->driver) {
+		printk(IBM_ERR "kmalloc(ibm->driver) failed\n");
+		return -1;
+	}
+
+	memset(ibm->driver, 0, sizeof(struct acpi_driver));
+	sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
+	ibm->driver->ids = ibm->hid;
+	ibm->driver->ops.add = &device_add;
+
+	ret = acpi_bus_register_driver(ibm->driver);
+	if (ret < 0) {
+		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
+		       ibm->hid, ret);
+		kfree(ibm->driver);
+	}
+
+	return ret;
+}
+
+static int ibm_init(struct ibm_struct *ibm)
+{
+	int ret;
+	struct proc_dir_entry *entry;
+
+	if (ibm->experimental && !experimental)
+		return 0;
+
+	if (ibm->hid) {
+		ret = register_driver(ibm);
+		if (ret < 0)
+			return ret;
+		ibm->driver_registered = 1;
+	}
+
+	if (ibm->init) {
+		ret = ibm->init(ibm);
+		if (ret != 0)
+			return ret;
+		ibm->init_called = 1;
+	}
+
+	entry = create_proc_entry(ibm->name, S_IFREG | S_IRUGO | S_IWUSR,
+				  proc_dir);
+	if (!entry) {
+		printk(IBM_ERR "unable to create proc entry %s\n", ibm->name);
+		return -ENODEV;
+	}
+	entry->owner = THIS_MODULE;
+	ibm->proc_created = 1;
+	
+	entry->data = ibm;
+	if (ibm->read)
+		entry->read_proc = &dispatch_read;
+	if (ibm->write)
+		entry->write_proc = &dispatch_write;
+
+	if (ibm->notify) {
+		ret = setup_notify(ibm);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void ibm_exit(struct ibm_struct *ibm)
+{
+	if (ibm->notify_installed)
+		acpi_remove_notify_handler(*ibm->handle, ibm->type,
+					   dispatch_notify);
+
+	if (ibm->proc_created)
+		remove_proc_entry(ibm->name, proc_dir);
+
+	if (ibm->init_called && ibm->exit)
+		ibm->exit(ibm);
+
+	if (ibm->driver_registered) {
+		acpi_bus_unregister_driver(ibm->driver);
+		kfree(ibm->driver);
+	}
+}
+
+static int ibm_handle_init(char *name,
+			   acpi_handle *handle, acpi_handle parent,
+			   char **paths, int num_paths, int required)
+{
+	int i;
+	acpi_status status;
+
+	for (i=0; i<num_paths; i++) {
+		status = acpi_get_handle(parent, paths[i], handle);
+		if (ACPI_SUCCESS(status))
+			return 0;
+	}
+	
+	*handle = NULL;
+
+	if (required) {
+		printk(IBM_ERR "%s object not found\n", name);
+		return -1;
+	}
+
+	return 0;
+}
+
+#define IBM_HANDLE_INIT(object, required)				\
+	ibm_handle_init(#object, &object##_handle, *object##_parent,	\
+		object##_paths, sizeof(object##_paths)/sizeof(char*), required)
+
+
+static int set_ibm_param(const char *val, struct kernel_param *kp)
+{
+	unsigned int i;
+	char arg_with_comma[32];
+
+	if (strlen(val) > 30)
+		return -ENOSPC;
+
+	strcpy(arg_with_comma, val);
+	strcat(arg_with_comma, ",");
+
+	for (i=0; i<NUM_IBMS; i++)
+		if (strcmp(ibms[i].name, kp->name) == 0)
+			return ibms[i].write(&ibms[i], arg_with_comma);
+	BUG();
+	return -EINVAL;
+}
+
+#define IBM_PARAM(feature) \
+	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
+
+static void acpi_ibm_exit(void)
+{
+	int i;
+
+	for (i=NUM_IBMS-1; i>=0; i--)
+		ibm_exit(&ibms[i]);
+
+	remove_proc_entry(IBM_DIR, acpi_root_dir);
+}
+
+static int __init acpi_ibm_init(void)
+{
+	int ret, i;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	/* these handles are required */
+	if (IBM_HANDLE_INIT(ec,	  1) < 0 ||
+	    IBM_HANDLE_INIT(hkey, 1) < 0 ||
+	    IBM_HANDLE_INIT(vid,  1) < 0 ||
+	    IBM_HANDLE_INIT(beep, 1) < 0)
+		return -ENODEV;
+
+	/* these handles have alternatives */
+	IBM_HANDLE_INIT(lght, 0);
+	if (IBM_HANDLE_INIT(cmos, !lght_handle) < 0)
+		return -ENODEV;
+	IBM_HANDLE_INIT(sysl, 0);
+	if (IBM_HANDLE_INIT(led, !sysl_handle) < 0)
+		return -ENODEV;
+
+	/* these handles are not required */
+	IBM_HANDLE_INIT(dock,  0);
+	IBM_HANDLE_INIT(bay,   0);
+	IBM_HANDLE_INIT(bayej, 0);
+	IBM_HANDLE_INIT(bled,  0);
+
+	proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
+	if (!proc_dir) {
+		printk(IBM_ERR "unable to create proc dir %s", IBM_DIR);
+		return -ENODEV;
+	}
+	proc_dir->owner = THIS_MODULE;
+	
+	for (i=0; i<NUM_IBMS; i++) {
+		ret = ibm_init(&ibms[i]);
+		if (ret < 0) {
+			acpi_ibm_exit();
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+module_init(acpi_ibm_init);
+module_exit(acpi_ibm_exit);
+
+MODULE_AUTHOR("Borislav Deianov");
+MODULE_DESCRIPTION(IBM_DESC);
+MODULE_LICENSE("GPL");
+
+IBM_PARAM(hotkey);
+IBM_PARAM(bluetooth);
+IBM_PARAM(video);
+IBM_PARAM(light);
+IBM_PARAM(dock);
+IBM_PARAM(bay);
+IBM_PARAM(cmos);
+IBM_PARAM(led);
+IBM_PARAM(beep);
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
new file mode 100644
index 0000000..61ea707
--- /dev/null
+++ b/drivers/acpi/motherboard.c
@@ -0,0 +1,177 @@
+/* 
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+/* Purpose: Prevent PCMCIA cards from using motherboard resources. */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("acpi_motherboard")
+
+/* Dell use PNP0C01 instead of PNP0C02 */
+#define ACPI_MB_HID1			"PNP0C01"
+#define ACPI_MB_HID2			"PNP0C02"
+
+/**
+ * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved
+ * Doesn't care about the failure of 'request_region', since other may reserve 
+ * the io ports as well
+ */
+#define IS_RESERVED_ADDR(base, len) \
+	(((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \
+	&& ((base) + (len) > PCIBIOS_MIN_IO))
+
+/*
+ * Clearing the flag (IORESOURCE_BUSY) allows drivers to use
+ * the io ports if they really know they can use it, while
+ * still preventing hotplug PCI devices from using it. 
+ */
+
+static acpi_status
+acpi_reserve_io_ranges (struct acpi_resource *res, void *data)
+{
+	struct resource *requested_res = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges");
+
+	if (res->id == ACPI_RSTYPE_IO) {
+		struct acpi_resource_io *io_res = &res->data.io;
+
+		if (io_res->min_base_address != io_res->max_base_address)
+			return_VALUE(AE_OK);
+		if (IS_RESERVED_ADDR(io_res->min_base_address, io_res->range_length)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
+				io_res->min_base_address, 
+				io_res->min_base_address + io_res->range_length));
+			requested_res = request_region(io_res->min_base_address, 
+				io_res->range_length, "motherboard");
+		}
+	} else if (res->id == ACPI_RSTYPE_FIXED_IO) {
+		struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io;
+
+		if (IS_RESERVED_ADDR(fixed_io_res->base_address, fixed_io_res->range_length)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
+				fixed_io_res->base_address, 
+				fixed_io_res->base_address + fixed_io_res->range_length));
+			requested_res = request_region(fixed_io_res->base_address, 
+				fixed_io_res->range_length, "motherboard");
+		}
+	} else {
+		/* Memory mapped IO? */
+	}
+
+	if (requested_res)
+		requested_res->flags &= ~IORESOURCE_BUSY;
+	return_VALUE(AE_OK);
+}
+
+static int acpi_motherboard_add (struct acpi_device *device)
+{
+	if (!device)
+		return -EINVAL;
+	acpi_walk_resources(device->handle, METHOD_NAME__CRS, 
+		acpi_reserve_io_ranges, NULL);
+
+	return 0;
+}
+
+static struct acpi_driver acpi_motherboard_driver1 = {
+	.name =		"motherboard",
+	.class =	"",
+	.ids =		ACPI_MB_HID1,
+	.ops =	{
+		.add =		acpi_motherboard_add,
+	},
+};
+
+static struct acpi_driver acpi_motherboard_driver2 = {
+	.name =		"motherboard",
+	.class =	"",
+	.ids =		ACPI_MB_HID2,
+	.ops =	{
+		.add =		acpi_motherboard_add,
+	},
+};
+
+static void __init
+acpi_reserve_resources (void)
+{
+	if (acpi_gbl_FADT->xpm1a_evt_blk.address && acpi_gbl_FADT->pm1_evt_len)
+		request_region(acpi_gbl_FADT->xpm1a_evt_blk.address, 
+			acpi_gbl_FADT->pm1_evt_len, "PM1a_EVT_BLK");
+
+	if (acpi_gbl_FADT->xpm1b_evt_blk.address && acpi_gbl_FADT->pm1_evt_len)
+		request_region(acpi_gbl_FADT->xpm1b_evt_blk.address,
+			acpi_gbl_FADT->pm1_evt_len, "PM1b_EVT_BLK");
+
+	if (acpi_gbl_FADT->xpm1a_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len)
+		request_region(acpi_gbl_FADT->xpm1a_cnt_blk.address, 
+			acpi_gbl_FADT->pm1_cnt_len, "PM1a_CNT_BLK");
+
+	if (acpi_gbl_FADT->xpm1b_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len)
+		request_region(acpi_gbl_FADT->xpm1b_cnt_blk.address, 
+			acpi_gbl_FADT->pm1_cnt_len, "PM1b_CNT_BLK");
+
+	if (acpi_gbl_FADT->xpm_tmr_blk.address && acpi_gbl_FADT->pm_tm_len == 4)
+		request_region(acpi_gbl_FADT->xpm_tmr_blk.address,
+			4, "PM_TMR");
+
+	if (acpi_gbl_FADT->xpm2_cnt_blk.address && acpi_gbl_FADT->pm2_cnt_len)
+		request_region(acpi_gbl_FADT->xpm2_cnt_blk.address,
+			acpi_gbl_FADT->pm2_cnt_len, "PM2_CNT_BLK");
+
+	/* Length of GPE blocks must be a non-negative multiple of 2 */
+
+	if (acpi_gbl_FADT->xgpe0_blk.address && acpi_gbl_FADT->gpe0_blk_len &&
+			!(acpi_gbl_FADT->gpe0_blk_len & 0x1))
+		request_region(acpi_gbl_FADT->xgpe0_blk.address,
+			acpi_gbl_FADT->gpe0_blk_len, "GPE0_BLK");
+
+	if (acpi_gbl_FADT->xgpe1_blk.address && acpi_gbl_FADT->gpe1_blk_len &&
+			!(acpi_gbl_FADT->gpe1_blk_len & 0x1))
+		request_region(acpi_gbl_FADT->xgpe1_blk.address,
+			acpi_gbl_FADT->gpe1_blk_len, "GPE1_BLK");
+}
+
+static int __init acpi_motherboard_init(void)
+{
+	acpi_bus_register_driver(&acpi_motherboard_driver1);
+	acpi_bus_register_driver(&acpi_motherboard_driver2);
+	/* 
+	 * Guarantee motherboard IO reservation first
+	 * This module must run after scan.c
+	 */
+	if (!acpi_disabled)
+		acpi_reserve_resources ();
+	return 0;
+}
+
+/**
+ * Reserve motherboard resources after PCI claim BARs,
+ * but before PCI assign resources for uninitialized PCI devices
+ */
+fs_initcall(acpi_motherboard_init);
diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile
new file mode 100644
index 0000000..3f63d36
--- /dev/null
+++ b/drivers/acpi/namespace/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := nsaccess.o  nsload.o    nssearch.o  nsxfeval.o \
+	 nsalloc.o   nseval.o    nsnames.o   nsutils.o   nsxfname.o \
+	 nsdump.o    nsinit.o    nsobject.o  nswalk.o    nsxfobj.o  \
+	 nsparse.o
+
+obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
new file mode 100644
index 0000000..1c0c123
--- /dev/null
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -0,0 +1,637 @@
+/*******************************************************************************
+ *
+ * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdispat.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsaccess")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_root_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Allocate and initialize the default root named objects
+ *
+ * MUTEX:       Locks namespace for entire execution
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_root_initialize (void)
+{
+	acpi_status                         status;
+	const struct acpi_predefined_names *init_val = NULL;
+	struct acpi_namespace_node          *new_node;
+	union acpi_operand_object           *obj_desc;
+	acpi_string                         val = NULL;
+
+
+	ACPI_FUNCTION_TRACE ("ns_root_initialize");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * The global root ptr is initially NULL, so a non-NULL value indicates
+	 * that acpi_ns_root_initialize() has already been called; just return.
+	 */
+	if (acpi_gbl_root_node) {
+		status = AE_OK;
+		goto unlock_and_exit;
+	}
+
+	/*
+	 * Tell the rest of the subsystem that the root is initialized
+	 * (This is OK because the namespace is locked)
+	 */
+	acpi_gbl_root_node = &acpi_gbl_root_node_struct;
+
+	/* Enter the pre-defined names in the name table */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"Entering predefined entries into namespace\n"));
+
+	for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
+		/* _OSI is optional for now, will be permanent later */
+
+		if (!ACPI_STRCMP (init_val->name, "_OSI") && !acpi_gbl_create_osi_method) {
+			continue;
+		}
+
+		status = acpi_ns_lookup (NULL, init_val->name, init_val->type,
+				  ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
+				  NULL, &new_node);
+
+		if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not create predefined name %s, %s\n",
+				init_val->name, acpi_format_exception (status)));
+		}
+
+		/*
+		 * 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);
+			if (ACPI_FAILURE (status)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Could not override predefined %s\n",
+					init_val->name));
+			}
+
+			if (!val) {
+				val = init_val->val;
+			}
+
+			/*
+			 * Entry requests an initial value, allocate a
+			 * descriptor for it.
+			 */
+			obj_desc = acpi_ut_create_internal_object (init_val->type);
+			if (!obj_desc) {
+				status = AE_NO_MEMORY;
+				goto unlock_and_exit;
+			}
+
+			/*
+			 * Convert value string from table entry to
+			 * internal representation. Only types actually
+			 * used for initial values are implemented here.
+			 */
+			switch (init_val->type) {
+			case ACPI_TYPE_METHOD:
+				obj_desc->method.param_count = (u8) ACPI_TO_INTEGER (val);
+				obj_desc->common.flags |= AOPOBJ_DATA_VALID;
+
+#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_App)
+
+				/*
+				 * i_aSL Compiler cheats by putting parameter count
+				 * in the owner_iD
+				 */
+				new_node->owner_id = obj_desc->method.param_count;
+#else
+				/* Mark this as a very SPECIAL method */
+
+				obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY;
+				obj_desc->method.implementation = acpi_ut_osi_implementation;
+#endif
+				break;
+
+			case ACPI_TYPE_INTEGER:
+
+				obj_desc->integer.value = ACPI_TO_INTEGER (val);
+				break;
+
+
+			case ACPI_TYPE_STRING:
+
+				/*
+				 * Build an object around the static string
+				 */
+				obj_desc->string.length = (u32) ACPI_STRLEN (val);
+				obj_desc->string.pointer = val;
+				obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
+				break;
+
+
+			case ACPI_TYPE_MUTEX:
+
+				obj_desc->mutex.node = new_node;
+				obj_desc->mutex.sync_level = (u8) (ACPI_TO_INTEGER (val) - 1);
+
+				if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
+					/*
+					 * Create a counting semaphore for the
+					 * global lock
+					 */
+					status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT,
+							 1, &obj_desc->mutex.semaphore);
+					if (ACPI_FAILURE (status)) {
+						acpi_ut_remove_reference (obj_desc);
+						goto unlock_and_exit;
+					}
+
+					/*
+					 * We just created the mutex for the
+					 * global lock, save it
+					 */
+					acpi_gbl_global_lock_semaphore = obj_desc->mutex.semaphore;
+				}
+				else {
+					/* Create a mutex */
+
+					status = acpi_os_create_semaphore (1, 1,
+							   &obj_desc->mutex.semaphore);
+					if (ACPI_FAILURE (status)) {
+						acpi_ut_remove_reference (obj_desc);
+						goto unlock_and_exit;
+					}
+				}
+				break;
+
+
+			default:
+
+				ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
+					init_val->type));
+				acpi_ut_remove_reference (obj_desc);
+				obj_desc = NULL;
+				continue;
+			}
+
+			/* Store pointer to value descriptor in the Node */
+
+			status = acpi_ns_attach_object (new_node, obj_desc,
+					 ACPI_GET_OBJECT_TYPE (obj_desc));
+
+			/* Remove local reference to the object */
+
+			acpi_ut_remove_reference (obj_desc);
+		}
+	}
+
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+
+	/* Save a handle to "_GPE", it is always present */
+
+	if (ACPI_SUCCESS (status)) {
+		status = acpi_ns_get_node_by_path ("\\_GPE", NULL, ACPI_NS_NO_UPSEARCH,
+				  &acpi_gbl_fadt_gpe_device);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_lookup
+ *
+ * PARAMETERS:  prefix_node     - Search scope if name is not fully qualified
+ *              Pathname        - Search pathname, in internal format
+ *                                (as represented in the AML stream)
+ *              Type            - Type associated with name
+ *              interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
+ *              Flags           - Flags describing the search restrictions
+ *              walk_state      - Current state of the walk
+ *              return_node     - Where the Node is placed (if found
+ *                                or created successfully)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find or enter the passed name in the name space.
+ *              Log an error if name not found in Exec mode.
+ *
+ * MUTEX:       Assumes namespace is locked.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_lookup (
+	union acpi_generic_state        *scope_info,
+	char                            *pathname,
+	acpi_object_type                type,
+	acpi_interpreter_mode           interpreter_mode,
+	u32                             flags,
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      **return_node)
+{
+	acpi_status                     status;
+	char                            *path = pathname;
+	struct acpi_namespace_node      *prefix_node;
+	struct acpi_namespace_node      *current_node = NULL;
+	struct acpi_namespace_node      *this_node = NULL;
+	u32                             num_segments;
+	u32                             num_carats;
+	acpi_name                       simple_name;
+	acpi_object_type                type_to_check_for;
+	acpi_object_type                this_search_type;
+	u32                             search_parent_flag = ACPI_NS_SEARCH_PARENT;
+	u32                             local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND |
+			   ACPI_NS_SEARCH_PARENT);
+
+
+	ACPI_FUNCTION_TRACE ("ns_lookup");
+
+
+	if (!return_node) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	acpi_gbl_ns_lookup_count++;
+	*return_node = ACPI_ENTRY_NOT_FOUND;
+
+	if (!acpi_gbl_root_node) {
+		return_ACPI_STATUS (AE_NO_NAMESPACE);
+	}
+
+	/*
+	 * 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",
+			acpi_gbl_root_node));
+
+		prefix_node = acpi_gbl_root_node;
+	}
+	else {
+		prefix_node = scope_info->scope.node;
+		if (ACPI_GET_DESCRIPTOR_TYPE (prefix_node) != ACPI_DESC_TYPE_NAMED) {
+			ACPI_REPORT_ERROR (("ns_lookup: %p is not a namespace node [%s]\n",
+					prefix_node, acpi_ut_get_descriptor_name (prefix_node)));
+			return_ACPI_STATUS (AE_AML_INTERNAL);
+		}
+
+		/*
+		 * 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.
+		 */
+		while (!acpi_ns_opens_scope (prefix_node->type) &&
+				prefix_node->type != ACPI_TYPE_ANY) {
+			prefix_node = acpi_ns_get_parent_node (prefix_node);
+		}
+	}
+
+	/* Save type   TBD: may be no longer necessary */
+
+	type_to_check_for = type;
+
+	/*
+	 * Begin examination of the actual pathname
+	 */
+	if (!pathname) {
+		/* A Null name_path is allowed and refers to the root */
+
+		num_segments = 0;
+		this_node    = acpi_gbl_root_node;
+		path     = "";
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+			"Null Pathname (Zero segments), Flags=%X\n", flags));
+	}
+	else {
+		/*
+		 * Name pointer is valid (and must be in internal name format)
+		 *
+		 * Check for scope prefixes:
+		 *
+		 * As represented in the AML stream, a namepath consists of an
+		 * optional scope prefix followed by a name segment part.
+		 *
+		 * If present, the scope prefix is either a Root Prefix (in
+		 * which case the name is fully qualified), or one or more
+		 * Parent Prefixes (in which case the name's scope is relative
+		 * to the current scope).
+		 */
+		if (*path == (u8) AML_ROOT_PREFIX) {
+			/* Pathname is fully qualified, start from the root */
+
+			this_node = acpi_gbl_root_node;
+			search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
+			/* Point to name segment part */
+
+			path++;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Path is absolute from root [%p]\n", this_node));
+		}
+		else {
+			/* Pathname is relative to current scope, start there */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Searching relative to prefix scope [%4.4s] (%p)\n",
+				acpi_ut_get_node_name (prefix_node), prefix_node));
+
+			/*
+			 * Handle multiple Parent Prefixes (carat) by just getting
+			 * the parent node for each prefix instance.
+			 */
+			this_node = prefix_node;
+			num_carats = 0;
+			while (*path == (u8) AML_PARENT_PREFIX) {
+				/* 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
+				 */
+				path++;
+
+				/* Backup to the parent node */
+
+				num_carats++;
+				this_node = acpi_ns_get_parent_node (this_node);
+				if (!this_node) {
+					/* Current scope has no parent scope */
+
+					ACPI_REPORT_ERROR (
+						("ACPI path has too many parent prefixes (^) - reached beyond root node\n"));
+					return_ACPI_STATUS (AE_NOT_FOUND);
+				}
+			}
+
+			if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+					"Search scope is [%4.4s], path has %d carat(s)\n",
+					acpi_ut_get_node_name (this_node), num_carats));
+			}
+		}
+
+		/*
+		 * Determine the number of ACPI name segments in this pathname.
+		 *
+		 * The segment part consists of either:
+		 *  - A Null name segment (0)
+		 *  - A dual_name_prefix followed by two 4-byte name segments
+		 *  - A multi_name_prefix followed by a byte indicating the
+		 *      number of segments and the segments themselves.
+		 *  - A single 4-byte name segment
+		 *
+		 * Examine the name prefix opcode, if any, to determine the number of
+		 * segments.
+		 */
+		switch (*path) {
+		case 0:
+			/*
+			 * Null name after a root or parent prefixes. We already
+			 * have the correct target node and there are no name segments.
+			 */
+			num_segments = 0;
+			type = this_node->type;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Prefix-only Pathname (Zero name segments), Flags=%X\n",
+				flags));
+			break;
+
+		case AML_DUAL_NAME_PREFIX:
+
+			/* More than one name_seg, search rules do not apply */
+
+			search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
+			/* Two segments, point to first name segment */
+
+			num_segments = 2;
+			path++;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Dual Pathname (2 segments, Flags=%X)\n", flags));
+			break;
+
+		case AML_MULTI_NAME_PREFIX_OP:
+
+			/* More than one name_seg, search rules do not apply */
+
+			search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
+			/* Extract segment count, point to first name segment */
+
+			path++;
+			num_segments = (u32) (u8) *path;
+			path++;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Multi Pathname (%d Segments, Flags=%X) \n",
+				num_segments, flags));
+			break;
+
+		default:
+			/*
+			 * Not a Null name, no Dual or Multi prefix, hence there is
+			 * only one name segment and Pathname is already pointing to it.
+			 */
+			num_segments = 1;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Simple Pathname (1 segment, Flags=%X)\n", flags));
+			break;
+		}
+
+		ACPI_DEBUG_EXEC (acpi_ns_print_pathname (num_segments, path));
+	}
+
+
+	/*
+	 * Search namespace for each segment of the name.  Loop through and
+	 * verify (or add to the namespace) each name segment.
+	 *
+	 * The object type is significant only at the last name
+	 * segment.  (We don't care about the types along the path, only
+	 * the type of the final target object.)
+	 */
+	this_search_type = ACPI_TYPE_ANY;
+	current_node = this_node;
+	while (num_segments && current_node) {
+		num_segments--;
+		if (!num_segments) {
+			/*
+			 * This is the last segment, enable typechecking
+			 */
+			this_search_type = type;
+
+			/*
+			 * Only allow automatic parent search (search rules) if the caller
+			 * requested it AND we have a single, non-fully-qualified name_seg
+			 */
+			if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
+				(flags & ACPI_NS_SEARCH_PARENT)) {
+				local_flags |= ACPI_NS_SEARCH_PARENT;
+			}
+
+			/* Set error flag according to caller */
+
+			if (flags & ACPI_NS_ERROR_IF_FOUND) {
+				local_flags |= ACPI_NS_ERROR_IF_FOUND;
+			}
+		}
+
+		/* Extract one ACPI name from the front of the pathname */
+
+		ACPI_MOVE_32_TO_32 (&simple_name, path);
+
+		/* Try to find the single (4 character) ACPI name */
+
+		status = acpi_ns_search_and_enter (simple_name, walk_state, current_node,
+				 interpreter_mode, this_search_type, local_flags, &this_node);
+		if (ACPI_FAILURE (status)) {
+			if (status == AE_NOT_FOUND) {
+				/* Name not found in ACPI namespace */
+
+				ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+					"Name [%4.4s] not found in scope [%4.4s] %p\n",
+					(char *) &simple_name, (char *) &current_node->name,
+					current_node));
+			}
+
+			*return_node = this_node;
+			return_ACPI_STATUS (status);
+		}
+
+		/*
+		 * Sanity typecheck of the target object:
+		 *
+		 * If 1) This is the last segment (num_segments == 0)
+		 *    2) And we are looking for a specific type
+		 *       (Not checking for TYPE_ANY)
+		 *    3) Which is not an alias
+		 *    4) Which is not a local type (TYPE_SCOPE)
+		 *    5) And the type of target object is known (not TYPE_ANY)
+		 *    6) And target object does not match what we are looking for
+		 *
+		 * Then we have a type mismatch.  Just warn and ignore it.
+		 */
+		if ((num_segments       == 0)                               &&
+			(type_to_check_for  != ACPI_TYPE_ANY)                   &&
+			(type_to_check_for  != ACPI_TYPE_LOCAL_ALIAS)           &&
+			(type_to_check_for  != ACPI_TYPE_LOCAL_METHOD_ALIAS)    &&
+			(type_to_check_for  != ACPI_TYPE_LOCAL_SCOPE)           &&
+			(this_node->type    != ACPI_TYPE_ANY)                   &&
+			(this_node->type    != type_to_check_for)) {
+			/* Complain about a type mismatch */
+
+			ACPI_REPORT_WARNING (
+				("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n",
+				(char *) &simple_name, acpi_ut_get_type_name (this_node->type),
+				acpi_ut_get_type_name (type_to_check_for)));
+		}
+
+		/*
+		 * 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 see if it opens a scope.
+		 */
+		if ((num_segments == 0) && (type == ACPI_TYPE_ANY)) {
+			type = this_node->type;
+		}
+
+		/* Point to next name segment and make this node current */
+
+		path += ACPI_NAME_SIZE;
+		current_node = this_node;
+	}
+
+	/*
+	 * 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
+		 * scope stack.
+		 */
+		if (acpi_ns_opens_scope (type)) {
+			status = acpi_ds_scope_stack_push (this_node, type, walk_state);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+	}
+
+	*return_node = this_node;
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
new file mode 100644
index 0000000..bfd922c
--- /dev/null
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -0,0 +1,685 @@
+/*******************************************************************************
+ *
+ * Module Name: nsalloc - Namespace allocation and deletion utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsalloc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_create_node
+ *
+ * PARAMETERS:  acpi_name       - Name of the new node
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create a namespace node
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *
+acpi_ns_create_node (
+	u32                             name)
+{
+	struct acpi_namespace_node      *node;
+
+
+	ACPI_FUNCTION_TRACE ("ns_create_node");
+
+
+	node = ACPI_MEM_CALLOCATE (sizeof (struct acpi_namespace_node));
+	if (!node) {
+		return_PTR (NULL);
+	}
+
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_allocated++);
+
+	node->name.integer   = name;
+	node->reference_count = 1;
+	ACPI_SET_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED);
+
+	return_PTR (node);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_delete_node
+ *
+ * PARAMETERS:  Node            - Node to be deleted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete a namespace node
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_delete_node (
+	struct acpi_namespace_node      *node)
+{
+	struct acpi_namespace_node      *parent_node;
+	struct acpi_namespace_node      *prev_node;
+	struct acpi_namespace_node      *next_node;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ns_delete_node", node);
+
+
+	parent_node = acpi_ns_get_parent_node (node);
+
+	prev_node = NULL;
+	next_node = parent_node->child;
+
+	/* Find the node that is the previous peer in the parent's child list */
+
+	while (next_node != node) {
+		prev_node = next_node;
+		next_node = prev_node->peer;
+	}
+
+	if (prev_node) {
+		/* Node is not first child, unlink it */
+
+		prev_node->peer = next_node->peer;
+		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+			prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
+		}
+	}
+	else {
+		/* Node is first child (has no previous peer) */
+
+		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+			/* No peers at all */
+
+			parent_node->child = NULL;
+		}
+		else {   /* Link peer list to parent */
+
+			parent_node->child = next_node->peer;
+		}
+	}
+
+
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++);
+
+	/*
+	 * Detach an object if there is one then delete the node
+	 */
+	acpi_ns_detach_object (node);
+	ACPI_MEM_FREE (node);
+	return_VOID;
+}
+
+
+#ifdef ACPI_ALPHABETIC_NAMESPACE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_compare_names
+ *
+ * PARAMETERS:  Name1           - First name to compare
+ *              Name2           - Second name to compare
+ *
+ * RETURN:      value from strncmp
+ *
+ * DESCRIPTION: Compare two ACPI names.  Names that are prefixed with an
+ *              underscore are forced to be alphabetically first.
+ *
+ ******************************************************************************/
+
+int
+acpi_ns_compare_names (
+	char                            *name1,
+	char                            *name2)
+{
+	char                            reversed_name1[ACPI_NAME_SIZE];
+	char                            reversed_name2[ACPI_NAME_SIZE];
+	u32                             i;
+	u32                             j;
+
+
+	/*
+	 * Replace all instances of "underscore" with a value that is smaller so
+	 * that all names that are prefixed with underscore(s) are alphabetically
+	 * first.
+	 *
+	 * Reverse the name bytewise so we can just do a 32-bit compare instead
+	 * of a strncmp.
+	 */
+	for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) {
+		reversed_name1[j] = name1[i];
+		if (name1[i] == '_') {
+			reversed_name1[j] = '*';
+		}
+
+		reversed_name2[j] = name2[i];
+		if (name2[i] == '_') {
+			reversed_name2[j] = '*';
+		}
+	}
+
+	return (*(int *) reversed_name1 - *(int *) reversed_name2);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_install_node
+ *
+ * PARAMETERS:  walk_state      - Current state of the walk
+ *              parent_node     - The parent of the new Node
+ *              Node            - The new Node to install
+ *              Type            - ACPI object type of the new Node
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize a new namespace node and install it amongst
+ *              its peers.
+ *
+ *              Note: Current namespace lookup is linear search.  However, the
+ *              nodes are linked in alphabetical order to 1) put all reserved
+ *              names (start with underscore) first, and to 2) make a readable
+ *              namespace dump.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_install_node (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      *parent_node,   /* Parent */
+	struct acpi_namespace_node      *node,          /* New Child*/
+	acpi_object_type                type)
+{
+	u16                             owner_id = 0;
+	struct acpi_namespace_node      *child_node;
+#ifdef ACPI_ALPHABETIC_NAMESPACE
+
+	struct acpi_namespace_node      *previous_child_node;
+#endif
+
+
+	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
+	 */
+	if (walk_state) {
+		owner_id = walk_state->owner_id;
+	}
+
+	/* Link the new entry into the parent and existing children */
+
+	child_node = parent_node->child;
+	if (!child_node) {
+		parent_node->child = node;
+		node->flags |= ANOBJ_END_OF_PEER_LIST;
+		node->peer = parent_node;
+	}
+	else {
+#ifdef ACPI_ALPHABETIC_NAMESPACE
+		/*
+		 * Walk the list whilst searching for the correct
+		 * alphabetic placement.
+		 */
+		previous_child_node = NULL;
+		while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node), acpi_ut_get_node_name (node)) < 0) {
+			if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
+				/* Last peer;  Clear end-of-list flag */
+
+				child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
+
+				/* This node is the new peer to the child node */
+
+				child_node->peer = node;
+
+				/* This node is the new end-of-list */
+
+				node->flags |= ANOBJ_END_OF_PEER_LIST;
+				node->peer = parent_node;
+				break;
+			}
+
+			/* Get next peer */
+
+			previous_child_node = child_node;
+			child_node = child_node->peer;
+		}
+
+		/* Did the node get inserted at the end-of-list? */
+
+		if (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
+			/*
+			 * Loop above terminated without reaching the end-of-list.
+			 * Insert the new node at the current location
+			 */
+			if (previous_child_node) {
+				/* Insert node alphabetically */
+
+				node->peer = child_node;
+				previous_child_node->peer = node;
+			}
+			else {
+				/* Insert node alphabetically at start of list */
+
+				node->peer = child_node;
+				parent_node->child = node;
+			}
+		}
+#else
+		while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) {
+			child_node = child_node->peer;
+		}
+
+		child_node->peer = node;
+
+		/* Clear end-of-list flag */
+
+		child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
+		node->flags     |= ANOBJ_END_OF_PEER_LIST;
+		node->peer = parent_node;
+#endif
+	}
+
+	/* Init the new entry */
+
+	node->owner_id = owner_id;
+	node->type = (u8) type;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+		"%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
+		acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), node, owner_id,
+		acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type),
+		parent_node));
+
+	/*
+	 * Increment the reference count(s) of all parents up to
+	 * the root!
+	 */
+	while ((node = acpi_ns_get_parent_node (node)) != NULL) {
+		node->reference_count++;
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_delete_children
+ *
+ * PARAMETERS:  parent_node     - Delete this objects children
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete all children of the parent object. In other words,
+ *              deletes a "scope".
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_delete_children (
+	struct acpi_namespace_node      *parent_node)
+{
+	struct acpi_namespace_node      *child_node;
+	struct acpi_namespace_node      *next_node;
+	struct acpi_namespace_node      *node;
+	u8                              flags;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ns_delete_children", parent_node);
+
+
+	if (!parent_node) {
+		return_VOID;
+	}
+
+	/* If no children, all done! */
+
+	child_node = parent_node->child;
+	if (!child_node) {
+		return_VOID;
+	}
+
+	/*
+	 * Deallocate all children at this level
+	 */
+	do {
+		/* Get the things we need */
+
+		next_node   = child_node->peer;
+		flags       = child_node->flags;
+
+		/* Grandchildren should have all been deleted already */
+
+		if (child_node->child) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n",
+				parent_node, child_node));
+		}
+
+		/* Now we can free this child object */
+
+		ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++);
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n",
+			child_node, acpi_gbl_current_node_count));
+
+		/*
+		 * Detach an object if there is one, then free the child node
+		 */
+		acpi_ns_detach_object (child_node);
+
+		/*
+		 * Decrement the reference count(s) of all parents up to
+		 * the root! (counts were incremented when the node was created)
+		 */
+		node = child_node;
+		while ((node = acpi_ns_get_parent_node (node)) != NULL) {
+			node->reference_count--;
+		}
+
+		/* There should be only one reference remaining on this node */
+
+		if (child_node->reference_count != 1) {
+			ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n",
+				child_node->reference_count, child_node));
+		}
+
+		/* Now we can delete the node */
+
+		ACPI_MEM_FREE (child_node);
+
+		/* And move on to the next child in the list */
+
+		child_node = next_node;
+
+	} while (!(flags & ANOBJ_END_OF_PEER_LIST));
+
+
+	/* Clear the parent's child pointer */
+
+	parent_node->child = NULL;
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_delete_namespace_subtree
+ *
+ * PARAMETERS:  parent_node     - Root of the subtree to be deleted
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects
+ *              stored within the subtree.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_delete_namespace_subtree (
+	struct acpi_namespace_node      *parent_node)
+{
+	struct acpi_namespace_node      *child_node = NULL;
+	u32                             level = 1;
+
+
+	ACPI_FUNCTION_TRACE ("ns_delete_namespace_subtree");
+
+
+	if (!parent_node) {
+		return_VOID;
+	}
+
+	/*
+	 * Traverse the tree of objects until we bubble back up
+	 * to where we started.
+	 */
+	while (level > 0) {
+		/* Get the next node in this scope (NULL if none) */
+
+		child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node,
+				 child_node);
+		if (child_node) {
+			/* Found a child node - detach any attached object */
+
+			acpi_ns_detach_object (child_node);
+
+			/* Check if this node has any children */
+
+			if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) {
+				/*
+				 * There is at least one child of this node,
+				 * visit the node
+				 */
+				level++;
+				parent_node = child_node;
+				child_node = NULL;
+			}
+		}
+		else {
+			/*
+			 * No more children of this parent node.
+			 * Move up to the grandparent.
+			 */
+			level--;
+
+			/*
+			 * Now delete all of the children of this parent
+			 * all at the same time.
+			 */
+			acpi_ns_delete_children (parent_node);
+
+			/* New "last child" is this parent node */
+
+			child_node = parent_node;
+
+			/* Move up the tree to the grandparent */
+
+			parent_node = acpi_ns_get_parent_node (parent_node);
+		}
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_remove_reference
+ *
+ * PARAMETERS:  Node           - Named node whose reference count is to be
+ *                               decremented
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Remove a Node reference.  Decrements the reference count
+ *              of all parent Nodes up to the root.  Any node along
+ *              the way that reaches zero references is freed.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_remove_reference (
+	struct acpi_namespace_node      *node)
+{
+	struct acpi_namespace_node      *parent_node;
+	struct acpi_namespace_node      *this_node;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * Decrement the reference count(s) of this node and all
+	 * nodes up to the root,  Delete anything with zero remaining references.
+	 */
+	this_node = node;
+	while (this_node) {
+		/* Prepare to move up to parent */
+
+		parent_node = acpi_ns_get_parent_node (this_node);
+
+		/* Decrement the reference count on this node */
+
+		this_node->reference_count--;
+
+		/* Delete the node if no more references */
+
+		if (!this_node->reference_count) {
+			/* Delete all children and delete the node */
+
+			acpi_ns_delete_children (this_node);
+			acpi_ns_delete_node (this_node);
+		}
+
+		this_node = parent_node;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_delete_namespace_by_owner
+ *
+ * PARAMETERS:  owner_id    - All nodes with this owner will be deleted
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete entries within the namespace that are owned by a
+ *              specific ID.  Used to delete entire ACPI tables.  All
+ *              reference counts are updated.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_delete_namespace_by_owner (
+	u16                             owner_id)
+{
+	struct acpi_namespace_node      *child_node;
+	struct acpi_namespace_node      *deletion_node;
+	u32                             level;
+	struct acpi_namespace_node      *parent_node;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ns_delete_namespace_by_owner", owner_id);
+
+
+	parent_node   = acpi_gbl_root_node;
+	child_node    = NULL;
+	deletion_node = NULL;
+	level         = 1;
+
+	/*
+	 * Traverse the tree of nodes until we bubble back up
+	 * to where we started.
+	 */
+	while (level > 0) {
+		/*
+		 * Get the next child of this parent node. When child_node is NULL,
+		 * the first child of the parent is returned
+		 */
+		child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node);
+
+		if (deletion_node) {
+			acpi_ns_remove_reference (deletion_node);
+			deletion_node = NULL;
+		}
+
+		if (child_node) {
+			if (child_node->owner_id == owner_id) {
+				/* Found a matching child node - detach any attached object */
+
+				acpi_ns_detach_object (child_node);
+			}
+
+			/* Check if this node has any children */
+
+			if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) {
+				/*
+				 * There is at least one child of this node,
+				 * visit the node
+				 */
+				level++;
+				parent_node = child_node;
+				child_node = NULL;
+			}
+			else if (child_node->owner_id == owner_id) {
+				deletion_node = child_node;
+			}
+		}
+		else {
+			/*
+			 * No more children of this parent node.
+			 * Move up to the grandparent.
+			 */
+			level--;
+			if (level != 0) {
+				if (parent_node->owner_id == owner_id) {
+					deletion_node = parent_node;
+				}
+			}
+
+			/* New "last child" is this parent node */
+
+			child_node = parent_node;
+
+			/* Move up the tree to the grandparent */
+
+			parent_node = acpi_ns_get_parent_node (parent_node);
+		}
+	}
+
+	return_VOID;
+}
+
+
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
new file mode 100644
index 0000000..1f6af3e
--- /dev/null
+++ b/drivers/acpi/namespace/nsdump.c
@@ -0,0 +1,673 @@
+/******************************************************************************
+ *
+ * Module Name: nsdump - table dumping routines for debug
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsdump")
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_print_pathname
+ *
+ * PARAMETERS:  num_segment         - Number of ACPI name segments
+ *              Pathname            - The compressed (internal) path
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_print_pathname (
+	u32                             num_segments,
+	char                            *pathname)
+{
+	ACPI_FUNCTION_NAME ("ns_print_pathname");
+
+
+	if (!(acpi_dbg_level & ACPI_LV_NAMES) || !(acpi_dbg_layer & ACPI_NAMESPACE)) {
+		return;
+	}
+
+	/* Print the entire name */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "["));
+
+	while (num_segments) {
+		acpi_os_printf ("%4.4s", pathname);
+		pathname += ACPI_NAME_SIZE;
+
+		num_segments--;
+		if (num_segments) {
+			acpi_os_printf (".");
+		}
+	}
+
+	acpi_os_printf ("]\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_dump_pathname
+ *
+ * PARAMETERS:  Handle              - Object
+ *              Msg                 - Prefix message
+ *              Level               - Desired debug level
+ *              Component           - Caller's component ID
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ *              Manages allocation/freeing of a pathname buffer
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_dump_pathname (
+	acpi_handle                     handle,
+	char                            *msg,
+	u32                             level,
+	u32                             component)
+{
+
+	ACPI_FUNCTION_TRACE ("ns_dump_pathname");
+
+
+	/* Do this only if the requested debug level and component are enabled */
+
+	if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) {
+		return_VOID;
+	}
+
+	/* Convert handle to a full pathname and print it (with supplied message) */
+
+	acpi_ns_print_node_pathname (handle, msg);
+	acpi_os_printf ("\n");
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_dump_one_object
+ *
+ * PARAMETERS:  Handle              - Node to be dumped
+ *              Level               - Nesting level of the handle
+ *              Context             - Passed into walk_namespace
+ *
+ * DESCRIPTION: Dump a single Node
+ *              This procedure is a user_function called by acpi_ns_walk_namespace.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_dump_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value)
+{
+	struct acpi_walk_info           *info = (struct acpi_walk_info *) context;
+	struct acpi_namespace_node      *this_node;
+	union acpi_operand_object       *obj_desc = NULL;
+	acpi_object_type                obj_type;
+	acpi_object_type                type;
+	u32                             bytes_to_dump;
+	u32                             dbg_level;
+	u32                             i;
+
+
+	ACPI_FUNCTION_NAME ("ns_dump_one_object");
+
+
+	/* Is output enabled? */
+
+	if (!(acpi_dbg_level & info->debug_level)) {
+		return (AE_OK);
+	}
+
+	if (!obj_handle) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
+		return (AE_OK);
+	}
+
+	this_node = acpi_ns_map_handle_to_node (obj_handle);
+	type = this_node->type;
+
+	/* Check if the owner matches */
+
+	if ((info->owner_id != ACPI_UINT32_MAX) &&
+		(info->owner_id != this_node->owner_id)) {
+		return (AE_OK);
+	}
+
+	/* Indent the object according to the level */
+
+	acpi_os_printf ("%2d%*s", (u32) level - 1, (int) level * 2, " ");
+
+	/* Check the node type and name */
+
+	if (type > ACPI_TYPE_LOCAL_MAX) {
+		ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", type));
+	}
+
+	if (!acpi_ut_valid_acpi_name (this_node->name.integer)) {
+		ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n",
+			this_node->name.integer));
+	}
+
+	/*
+	 * Now we can print out the pertinent information
+	 */
+	acpi_os_printf ("%4.4s %-12s %p ",
+			acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node);
+
+	dbg_level = acpi_dbg_level;
+	acpi_dbg_level = 0;
+	obj_desc = acpi_ns_get_attached_object (this_node);
+	acpi_dbg_level = dbg_level;
+
+	switch (info->display_type) {
+	case ACPI_DISPLAY_SUMMARY:
+
+		if (!obj_desc) {
+			/* No attached object, we are done */
+
+			acpi_os_printf ("\n");
+			return (AE_OK);
+		}
+
+		switch (type) {
+		case ACPI_TYPE_PROCESSOR:
+
+			acpi_os_printf ("ID %X Len %.4X Addr %p\n",
+				obj_desc->processor.proc_id, obj_desc->processor.length,
+				(char *) obj_desc->processor.address);
+			break;
+
+
+		case ACPI_TYPE_DEVICE:
+
+			acpi_os_printf ("Notify Object: %p\n", obj_desc);
+			break;
+
+
+		case ACPI_TYPE_METHOD:
+
+			acpi_os_printf ("Args %X Len %.4X Aml %p\n",
+				(u32) obj_desc->method.param_count,
+				obj_desc->method.aml_length, obj_desc->method.aml_start);
+			break;
+
+
+		case ACPI_TYPE_INTEGER:
+
+			acpi_os_printf ("= %8.8X%8.8X\n",
+				ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+			break;
+
+
+		case ACPI_TYPE_PACKAGE:
+
+			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
+				acpi_os_printf ("Elements %.2X\n",
+					obj_desc->package.count);
+			}
+			else {
+				acpi_os_printf ("[Length not yet evaluated]\n");
+			}
+			break;
+
+
+		case ACPI_TYPE_BUFFER:
+
+			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
+				acpi_os_printf ("Len %.2X",
+						 obj_desc->buffer.length);
+
+				/* Dump some of the buffer */
+
+				if (obj_desc->buffer.length > 0) {
+					acpi_os_printf (" =");
+					for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) {
+						acpi_os_printf (" %.2hX", obj_desc->buffer.pointer[i]);
+					}
+				}
+				acpi_os_printf ("\n");
+			}
+			else {
+				acpi_os_printf ("[Length not yet evaluated]\n");
+			}
+			break;
+
+
+		case ACPI_TYPE_STRING:
+
+			acpi_os_printf ("Len %.2X ", obj_desc->string.length);
+			acpi_ut_print_string (obj_desc->string.pointer, 32);
+			acpi_os_printf ("\n");
+			break;
+
+
+		case ACPI_TYPE_REGION:
+
+			acpi_os_printf ("[%s]",
+				acpi_ut_get_region_name (obj_desc->region.space_id));
+			if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
+				acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n",
+					ACPI_FORMAT_UINT64 (obj_desc->region.address),
+					obj_desc->region.length);
+			}
+			else {
+				acpi_os_printf (" [Address/Length not yet evaluated]\n");
+			}
+			break;
+
+
+		case ACPI_TYPE_LOCAL_REFERENCE:
+
+			acpi_os_printf ("[%s]\n",
+				acpi_ps_get_opcode_name (obj_desc->reference.opcode));
+			break;
+
+
+		case ACPI_TYPE_BUFFER_FIELD:
+
+			if (obj_desc->buffer_field.buffer_obj &&
+				obj_desc->buffer_field.buffer_obj->buffer.node) {
+				acpi_os_printf ("Buf [%4.4s]",
+					acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node));
+			}
+			break;
+
+
+		case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+			acpi_os_printf ("Rgn [%4.4s]",
+				acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node));
+			break;
+
+
+		case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+			acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]",
+				acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node),
+				acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node));
+			break;
+
+
+		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+			acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]",
+				acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node),
+				acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node));
+			break;
+
+
+		case ACPI_TYPE_LOCAL_ALIAS:
+		case ACPI_TYPE_LOCAL_METHOD_ALIAS:
+
+			acpi_os_printf ("Target %4.4s (%p)\n",
+				acpi_ut_get_node_name (obj_desc), obj_desc);
+			break;
+
+		default:
+
+			acpi_os_printf ("Object %p\n", obj_desc);
+			break;
+		}
+
+		/* Common field handling */
+
+		switch (type) {
+		case ACPI_TYPE_BUFFER_FIELD:
+		case ACPI_TYPE_LOCAL_REGION_FIELD:
+		case ACPI_TYPE_LOCAL_BANK_FIELD:
+		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+			acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n",
+				(obj_desc->common_field.base_byte_offset * 8)
+					+ obj_desc->common_field.start_field_bit_offset,
+				obj_desc->common_field.bit_length,
+				obj_desc->common_field.access_byte_width);
+			break;
+
+		default:
+			break;
+		}
+		break;
+
+
+	case ACPI_DISPLAY_OBJECTS:
+
+		acpi_os_printf ("O:%p", obj_desc);
+		if (!obj_desc) {
+			/* No attached object, we are done */
+
+			acpi_os_printf ("\n");
+			return (AE_OK);
+		}
+
+		acpi_os_printf ("(R%d)",
+				obj_desc->common.reference_count);
+
+		switch (type) {
+		case ACPI_TYPE_METHOD:
+
+			/* Name is a Method and its AML offset/length are set */
+
+			acpi_os_printf (" M:%p-%X\n", obj_desc->method.aml_start,
+					  obj_desc->method.aml_length);
+			break;
+
+		case ACPI_TYPE_INTEGER:
+
+			acpi_os_printf (" I:%8.8X8.8%X\n",
+					ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+			break;
+
+		case ACPI_TYPE_STRING:
+
+			acpi_os_printf (" S:%p-%X\n", obj_desc->string.pointer,
+					  obj_desc->string.length);
+			break;
+
+		case ACPI_TYPE_BUFFER:
+
+			acpi_os_printf (" B:%p-%X\n", obj_desc->buffer.pointer,
+					  obj_desc->buffer.length);
+			break;
+
+		default:
+
+			acpi_os_printf ("\n");
+			break;
+		}
+		break;
+
+
+	default:
+		acpi_os_printf ("\n");
+		break;
+	}
+
+	/* If debug turned off, done */
+
+	if (!(acpi_dbg_level & ACPI_LV_VALUES)) {
+		return (AE_OK);
+	}
+
+
+	/* If there is an attached object, display it */
+
+	dbg_level    = acpi_dbg_level;
+	acpi_dbg_level = 0;
+	obj_desc     = acpi_ns_get_attached_object (this_node);
+	acpi_dbg_level = dbg_level;
+
+	/* Dump attached objects */
+
+	while (obj_desc) {
+		obj_type = ACPI_TYPE_INVALID;
+		acpi_os_printf ("      Attached Object %p: ", obj_desc);
+
+		/* Decode the type of attached object and dump the contents */
+
+		switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
+		case ACPI_DESC_TYPE_NAMED:
+
+			acpi_os_printf ("(Ptr to Node)\n");
+			bytes_to_dump = sizeof (struct acpi_namespace_node);
+			break;
+
+
+		case ACPI_DESC_TYPE_OPERAND:
+
+			obj_type = ACPI_GET_OBJECT_TYPE (obj_desc);
+
+			if (obj_type > ACPI_TYPE_LOCAL_MAX) {
+				acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n",
+					obj_type);
+				bytes_to_dump = 32;
+			}
+			else {
+				acpi_os_printf ("(Ptr to ACPI Object type %s, %X)\n",
+					acpi_ut_get_type_name (obj_type), obj_type);
+				bytes_to_dump = sizeof (union acpi_operand_object);
+			}
+			break;
+
+
+		default:
+
+			acpi_os_printf (
+				"(String or Buffer ptr - not an object descriptor) [%s]\n",
+				acpi_ut_get_descriptor_name (obj_desc));
+			bytes_to_dump = 16;
+			break;
+		}
+
+		ACPI_DUMP_BUFFER (obj_desc, bytes_to_dump);
+
+		/* If value is NOT an internal object, we are done */
+
+		if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+			goto cleanup;
+		}
+
+		/*
+		 * Valid object, get the pointer to next level, if any
+		 */
+		switch (obj_type) {
+		case ACPI_TYPE_STRING:
+			obj_desc = (void *) obj_desc->string.pointer;
+			break;
+
+		case ACPI_TYPE_BUFFER:
+			obj_desc = (void *) obj_desc->buffer.pointer;
+			break;
+
+		case ACPI_TYPE_BUFFER_FIELD:
+			obj_desc = (union acpi_operand_object *) obj_desc->buffer_field.buffer_obj;
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+			obj_desc = (void *) obj_desc->package.elements;
+			break;
+
+		case ACPI_TYPE_METHOD:
+			obj_desc = (void *) obj_desc->method.aml_start;
+			break;
+
+		case ACPI_TYPE_LOCAL_REGION_FIELD:
+			obj_desc = (void *) obj_desc->field.region_obj;
+			break;
+
+		case ACPI_TYPE_LOCAL_BANK_FIELD:
+			obj_desc = (void *) obj_desc->bank_field.region_obj;
+			break;
+
+		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+			obj_desc = (void *) obj_desc->index_field.index_obj;
+			break;
+
+		default:
+			goto cleanup;
+		}
+
+		obj_type = ACPI_TYPE_INVALID;  /* Terminate loop after next pass */
+	}
+
+cleanup:
+	acpi_os_printf ("\n");
+	return (AE_OK);
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_dump_objects
+ *
+ * PARAMETERS:  Type                - Object type to be dumped
+ *              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
+ *                                    ACPI_UINT32_MAX to match all owners.
+ *              start_handle        - Where in namespace to start/end search
+ *
+ * DESCRIPTION: Dump typed objects within the loaded namespace.
+ *              Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_dump_objects (
+	acpi_object_type                type,
+	u8                              display_type,
+	u32                             max_depth,
+	u32                             owner_id,
+	acpi_handle                     start_handle)
+{
+	struct acpi_walk_info           info;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	info.debug_level = ACPI_LV_TABLES;
+	info.owner_id = owner_id;
+	info.display_type = display_type;
+
+	(void) acpi_ns_walk_namespace (type, start_handle, max_depth,
+			 ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
+			 (void *) &info, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_dump_tables
+ *
+ * PARAMETERS:  search_base         - Root of subtree to be dumped, or
+ *                                    NS_ALL to dump the entire namespace
+ *              max_depth           - Maximum depth of dump.  Use INT_MAX
+ *                                    for an effectively unlimited depth.
+ *
+ * DESCRIPTION: Dump the name space, or a portion of it.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_dump_tables (
+	acpi_handle                     search_base,
+	u32                             max_depth)
+{
+	acpi_handle                     search_handle = search_base;
+
+
+	ACPI_FUNCTION_TRACE ("ns_dump_tables");
+
+
+	if (!acpi_gbl_root_node) {
+		/*
+		 * If the name space has not been initialized,
+		 * there is nothing to dump.
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "namespace not initialized!\n"));
+		return_VOID;
+	}
+
+	if (ACPI_NS_ALL == search_base) {
+		/*  entire namespace    */
+
+		search_handle = acpi_gbl_root_node;
+		ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
+	}
+
+	acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
+			ACPI_UINT32_MAX, search_handle);
+	return_VOID;
+}
+
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_dump_entry
+ *
+ * PARAMETERS:  Handle              - Node to be dumped
+ *              debug_level         - Output level
+ *
+ * DESCRIPTION: Dump a single Node
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_dump_entry (
+	acpi_handle                     handle,
+	u32                             debug_level)
+{
+	struct acpi_walk_info           info;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	info.debug_level = debug_level;
+	info.owner_id = ACPI_UINT32_MAX;
+	info.display_type = ACPI_DISPLAY_SUMMARY;
+
+	(void) acpi_ns_dump_one_object (handle, 1, &info, NULL);
+}
+
+#endif
+
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
new file mode 100644
index 0000000..d30a59e
--- /dev/null
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -0,0 +1,146 @@
+/******************************************************************************
+ *
+ * Module Name: nsdump - table dumping routines for debug
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsdumpdv")
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_dump_one_device
+ *
+ * PARAMETERS:  Handle              - Node to be dumped
+ *              Level               - Nesting level of the handle
+ *              Context             - Passed into walk_namespace
+ *
+ * DESCRIPTION: Dump a single Node that represents a device
+ *              This procedure is a user_function called by acpi_ns_walk_namespace.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_dump_one_device (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value)
+{
+	struct acpi_buffer              buffer;
+	struct acpi_device_info         *info;
+	acpi_status                     status;
+	u32                             i;
+
+
+	ACPI_FUNCTION_NAME ("ns_dump_one_device");
+
+
+	status = acpi_ns_dump_one_object (obj_handle, level, context, return_value);
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_get_object_info (obj_handle, &buffer);
+	if (ACPI_SUCCESS (status)) {
+		info = buffer.pointer;
+		for (i = 0; i < level; i++) {
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
+		}
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES,
+			"    HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
+			info->hardware_id.value, ACPI_FORMAT_UINT64 (info->address),
+			info->current_status));
+		ACPI_MEM_FREE (info);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_dump_root_devices
+ *
+ * PARAMETERS:  None
+ *
+ * DESCRIPTION: Dump all objects of type "device"
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_dump_root_devices (void)
+{
+	acpi_handle                     sys_bus_handle;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_NAME ("ns_dump_root_devices");
+
+
+	/* Only dump the table if tracing is enabled */
+
+	if (!(ACPI_LV_TABLES & acpi_dbg_level)) {
+		return;
+	}
+
+	status = acpi_get_handle(NULL, ACPI_NS_SYSTEM_BUS, &sys_bus_handle);
+	if (ACPI_FAILURE (status)) {
+		return;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
+		"Display of all devices in the namespace:\n"));
+
+	status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle,
+			 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
+			 acpi_ns_dump_one_device, NULL, NULL);
+}
+
+#endif
+
+
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
new file mode 100644
index 0000000..0d008d5
--- /dev/null
+++ b/drivers/acpi/namespace/nseval.c
@@ -0,0 +1,487 @@
+/*******************************************************************************
+ *
+ * Module Name: nseval - Object evaluation interfaces -- includes control
+ *                       method lookup and execution.
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nseval")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_evaluate_relative
+ *
+ * PARAMETERS:  Pathname            - Name of method to execute, If NULL, the
+ *                                    handle is the object to execute
+ *              Info                - Method info block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find and execute the requested method using the handle as a
+ *              scope
+ *
+ * MUTEX:       Locks Namespace
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_evaluate_relative (
+	char                            *pathname,
+	struct acpi_parameter_info      *info)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node = NULL;
+	union acpi_generic_state        *scope_info;
+	char                            *internal_path = NULL;
+
+
+	ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
+
+
+	/*
+	 * Must have a valid object handle
+	 */
+	if (!info || !info->node) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Build an internal name string for the method */
+
+	status = acpi_ns_internalize_name (pathname, &internal_path);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	scope_info = acpi_ut_create_generic_state ();
+	if (!scope_info) {
+		goto cleanup1;
+	}
+
+	/* Get the prefix handle and Node */
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	info->node = acpi_ns_map_handle_to_node (info->node);
+	if (!info->node) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		status = AE_BAD_PARAMETER;
+		goto cleanup;
+	}
+
+	/* Lookup the name in the namespace */
+
+	scope_info->scope.node = info->node;
+	status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
+			 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
+			 &node);
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
+			pathname, acpi_format_exception (status)));
+		goto cleanup;
+	}
+
+	/*
+	 * Now that we have a handle to the object, we can attempt to evaluate it.
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
+		pathname, node, acpi_ns_get_attached_object (node)));
+
+	info->node = node;
+	status = acpi_ns_evaluate_by_handle (info);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
+		pathname));
+
+cleanup:
+	acpi_ut_delete_generic_state (scope_info);
+
+cleanup1:
+	ACPI_MEM_FREE (internal_path);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_evaluate_by_name
+ *
+ * PARAMETERS:  Pathname            - Fully qualified pathname to the object
+ *              Info                - Contains:
+ *                  return_object   - Where to put method's return value (if
+ *                                    any).  If NULL, no value is returned.
+ *                  Params          - List of parameters to pass to the method,
+ *                                    terminated by NULL.  Params itself may be
+ *                                    NULL if no parameters are being passed.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find and execute the requested method passing the given
+ *              parameters
+ *
+ * MUTEX:       Locks Namespace
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_evaluate_by_name (
+	char                            *pathname,
+	struct acpi_parameter_info      *info)
+{
+	acpi_status                     status;
+	char                            *internal_path = NULL;
+
+
+	ACPI_FUNCTION_TRACE ("ns_evaluate_by_name");
+
+
+	/* Build an internal name string for the method */
+
+	status = acpi_ns_internalize_name (pathname, &internal_path);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Lookup the name in the namespace */
+
+	status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
+			 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
+			 &info->node);
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+			"Object at [%s] was not found, status=%.4X\n",
+			pathname, status));
+		goto cleanup;
+	}
+
+	/*
+	 * Now that we have a handle to the object, we can attempt to evaluate it.
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
+		pathname, info->node, acpi_ns_get_attached_object (info->node)));
+
+	status = acpi_ns_evaluate_by_handle (info);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
+		pathname));
+
+
+cleanup:
+
+	/* Cleanup */
+
+	if (internal_path) {
+		ACPI_MEM_FREE (internal_path);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_evaluate_by_handle
+ *
+ * PARAMETERS:  Handle              - Method Node to execute
+ *              Params              - List of parameters to pass to the method,
+ *                                    terminated by NULL.  Params itself may be
+ *                                    NULL if no parameters are being passed.
+ *              param_type          - Type of Parameter list
+ *              return_object       - Where to put method's return value (if
+ *                                    any).  If NULL, no value is returned.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute the requested method passing the given parameters
+ *
+ * MUTEX:       Locks Namespace
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_evaluate_by_handle (
+	struct acpi_parameter_info      *info)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle");
+
+
+	/* Check if namespace has been initialized */
+
+	if (!acpi_gbl_root_node) {
+		return_ACPI_STATUS (AE_NO_NAMESPACE);
+	}
+
+	/* Parameter Validation */
+
+	if (!info) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Initialize the return value to an invalid object */
+
+	info->return_object = NULL;
+
+	/* Get the prefix handle and Node */
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	info->node = acpi_ns_map_handle_to_node (info->node);
+	if (!info->node) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * For a method alias, we must grab the actual method node so that proper
+	 * scoping context will be established before execution.
+	 */
+	if (acpi_ns_get_type (info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+		info->node = ACPI_CAST_PTR (struct acpi_namespace_node, info->node->object);
+	}
+
+	/*
+	 * Two major cases here:
+	 * 1) The object is an actual control method -- execute it.
+	 * 2) The object is not a method -- just return it's current value
+	 *
+	 * In both cases, the namespace is unlocked by the acpi_ns* procedure
+	 */
+	if (acpi_ns_get_type (info->node) == ACPI_TYPE_METHOD) {
+		/*
+		 * Case 1) We have an actual control method to execute
+		 */
+		status = acpi_ns_execute_control_method (info);
+	}
+	else {
+		/*
+		 * Case 2) Object is NOT a method, just return its current value
+		 */
+		status = acpi_ns_get_object_value (info);
+	}
+
+	/*
+	 * Check if there is a return value on the stack that must be dealt with
+	 */
+	if (status == AE_CTRL_RETURN_VALUE) {
+		/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
+
+		status = AE_OK;
+	}
+
+	/*
+	 * Namespace was unlocked by the handling acpi_ns* function, so we
+	 * just return
+	 */
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_execute_control_method
+ *
+ * PARAMETERS:  Info            - Method info block (w/params)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute the requested method passing the given parameters
+ *
+ * MUTEX:       Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_execute_control_method (
+	struct acpi_parameter_info      *info)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE ("ns_execute_control_method");
+
+
+	/* Verify that there is a method associated with this object */
+
+	obj_desc = acpi_ns_get_attached_object (info->node);
+	if (!obj_desc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
+
+		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		return_ACPI_STATUS (AE_NULL_OBJECT);
+	}
+
+	ACPI_DUMP_PATHNAME (info->node, "Execute Method:",
+		ACPI_LV_INFO, _COMPONENT);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
+		obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1));
+
+	/*
+	 * Unlock the namespace before execution.  This allows namespace access
+	 * via the external Acpi* interfaces while a method is being executed.
+	 * However, any namespace deletion must acquire both the namespace and
+	 * interpreter locks to ensure that no thread is using the portion of the
+	 * namespace that is being deleted.
+	 */
+	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Execute the method via the interpreter.  The interpreter is locked
+	 * here before calling into the AML parser
+	 */
+	status = acpi_ex_enter_interpreter ();
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_psx_execute (info);
+	acpi_ex_exit_interpreter ();
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_object_value
+ *
+ * PARAMETERS:  Info            - Method info block (w/params)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return the current value of the object
+ *
+ * MUTEX:       Assumes namespace is locked, leaves namespace unlocked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_get_object_value (
+	struct acpi_parameter_info      *info)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_namespace_node      *resolved_node = info->node;
+
+
+	ACPI_FUNCTION_TRACE ("ns_get_object_value");
+
+
+	/*
+	 * Objects require additional resolution steps (e.g., the Node may be a
+	 * field that must be read, etc.) -- we can't just grab the object out of
+	 * the node.
+	 */
+
+	/*
+	 * Use resolve_node_to_value() to get the associated value. This call always
+	 * deletes obj_desc (allocated above).
+	 *
+	 * NOTE: we can get away with passing in NULL for a walk state because
+	 * obj_desc is guaranteed to not be a reference to either a method local or
+	 * a method argument (because this interface can only be called from the
+	 * acpi_evaluate external interface, never called from a running method.)
+	 *
+	 * Even though we do not directly invoke the interpreter for this, we must
+	 * enter it because we could access an opregion. The opregion access code
+	 * assumes that the interpreter is locked.
+	 *
+	 * We must release the namespace lock before entering the intepreter.
+	 */
+	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ex_enter_interpreter ();
+	if (ACPI_SUCCESS (status)) {
+		status = acpi_ex_resolve_node_to_value (&resolved_node, NULL);
+		/*
+		 * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
+		 * in resolved_node.
+		 */
+		acpi_ex_exit_interpreter ();
+
+		if (ACPI_SUCCESS (status)) {
+			status = AE_CTRL_RETURN_VALUE;
+			info->return_object = ACPI_CAST_PTR
+					 (union acpi_operand_object, resolved_node);
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
+				info->return_object,
+				acpi_ut_get_object_type_name (info->return_object)));
+		}
+	}
+
+	/* Namespace is unlocked */
+
+	return_ACPI_STATUS (status);
+}
+
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
new file mode 100644
index 0000000..4a46b38
--- /dev/null
+++ b/drivers/acpi/namespace/nsinit.c
@@ -0,0 +1,441 @@
+/******************************************************************************
+ *
+ * Module Name: nsinit - namespace initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsinit")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_initialize_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk the entire namespace and perform any necessary
+ *              initialization on the objects found therein
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_initialize_objects (
+	void)
+{
+	acpi_status                     status;
+	struct acpi_init_walk_info      info;
+
+
+	ACPI_FUNCTION_TRACE ("ns_initialize_objects");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"**** Starting initialization of namespace objects ****\n"));
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+		"Completing Region/Field/Buffer/Package initialization:"));
+
+	/* Set all init info to zero */
+
+	ACPI_MEMSET (&info, 0, sizeof (struct acpi_init_walk_info));
+
+	/* Walk entire namespace from the supplied root */
+
+	status = acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+			  ACPI_UINT32_MAX, acpi_ns_init_one_object,
+			  &info, NULL);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
+			acpi_format_exception (status)));
+	}
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+		"\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,
+		info.package_init,  info.package_count, info.object_count));
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"%hd Control Methods found\n", info.method_count));
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"%hd Op Regions found\n", info.op_region_count));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_initialize_devices
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      acpi_status
+ *
+ * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
+ *              This means running _INI on all present devices.
+ *
+ *              Note: We install PCI config space handler on region access,
+ *              not here.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_initialize_devices (
+	void)
+{
+	acpi_status                     status;
+	struct acpi_device_walk_info    info;
+
+
+	ACPI_FUNCTION_TRACE ("ns_initialize_devices");
+
+
+	/* Init counters */
+
+	info.device_count = 0;
+	info.num_STA = 0;
+	info.num_INI = 0;
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+		"Executing all Device _STA and_INI methods:"));
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Walk namespace for all objects */
+
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+			  ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL);
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
+			acpi_format_exception (status)));
+	}
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+		"\n%hd Devices found containing: %hd _STA, %hd _INI methods\n",
+		info.device_count, info.num_STA, info.num_INI));
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_init_one_object
+ *
+ * PARAMETERS:  obj_handle      - Node
+ *              Level           - Current nesting level
+ *              Context         - Points to a init info struct
+ *              return_value    - Not used
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
+ *              within the  namespace.
+ *
+ *              Currently, the only objects that require initialization are:
+ *              1) Methods
+ *              2) Op Regions
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_init_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value)
+{
+	acpi_object_type                type;
+	acpi_status                     status;
+	struct acpi_init_walk_info      *info = (struct acpi_init_walk_info *) context;
+	struct acpi_namespace_node      *node = (struct acpi_namespace_node *) obj_handle;
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_NAME ("ns_init_one_object");
+
+
+	info->object_count++;
+
+	/* And even then, we are only interested in a few object types */
+
+	type = acpi_ns_get_type (obj_handle);
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		return (AE_OK);
+	}
+
+	/* Increment counters for object types we are looking for */
+
+	switch (type) {
+	case ACPI_TYPE_REGION:
+		info->op_region_count++;
+		break;
+
+	case ACPI_TYPE_BUFFER_FIELD:
+		info->field_count++;
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		info->buffer_count++;
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+		info->package_count++;
+		break;
+
+	default:
+
+		/* No init required, just exit now */
+		return (AE_OK);
+	}
+
+	/*
+	 * 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
+	 */
+	status = acpi_ex_enter_interpreter ();
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/*
+	 * Each of these types can contain executable AML code within the
+	 * declaration.
+	 */
+	switch (type) {
+	case ACPI_TYPE_REGION:
+
+		info->op_region_init++;
+		status = acpi_ds_get_region_arguments (obj_desc);
+		break;
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		info->field_init++;
+		status = acpi_ds_get_buffer_field_arguments (obj_desc);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		info->buffer_init++;
+		status = acpi_ds_get_buffer_arguments (obj_desc);
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+
+		info->package_init++;
+		status = acpi_ds_get_package_arguments (obj_desc);
+		break;
+
+	default:
+		/* No other types can get here */
+		break;
+	}
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not execute arguments for [%4.4s] (%s), %s\n",
+				acpi_ut_get_node_name (node), acpi_ut_get_type_name (type),
+				acpi_format_exception (status)));
+	}
+
+	/*
+	 * Print a dot for each object unless we are going to print the entire
+	 * pathname
+	 */
+	if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+	}
+
+	/*
+	 * We ignore errors from above, and always return OK, since we don't want
+	 * to abort the walk on any single error.
+	 */
+	acpi_ex_exit_interpreter ();
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_init_one_device
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      acpi_status
+ *
+ * DESCRIPTION: This is called once per device soon after ACPI is enabled
+ *              to initialize each device. It determines if the device is
+ *              present, and if so, calls _INI.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_init_one_device (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value)
+{
+	struct acpi_device_walk_info   *info = (struct acpi_device_walk_info *) context;
+	struct acpi_parameter_info      pinfo;
+	u32                             flags;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ns_init_one_device");
+
+
+	pinfo.parameters = NULL;
+	pinfo.parameter_type = ACPI_PARAM_ARGS;
+
+	pinfo.node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!pinfo.node) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * We will run _STA/_INI on Devices, Processors and thermal_zones only
+	 */
+	if ((pinfo.node->type != ACPI_TYPE_DEVICE)      &&
+		(pinfo.node->type != ACPI_TYPE_PROCESSOR)   &&
+		(pinfo.node->type != ACPI_TYPE_THERMAL)) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
+		(!(acpi_dbg_level & ACPI_LV_INFO))) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+	}
+
+	info->device_count++;
+
+	/*
+	 * Run _STA to determine if we can run _INI on the device.
+	 */
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_STA"));
+	status = acpi_ut_execute_STA (pinfo.node, &flags);
+
+	if (ACPI_FAILURE (status)) {
+		if (pinfo.node->type == ACPI_TYPE_DEVICE) {
+			/* Ignore error and move on to next device */
+
+			return_ACPI_STATUS (AE_OK);
+		}
+
+		/* _STA is not required for Processor or thermal_zone objects */
+	}
+	else {
+		info->num_STA++;
+
+		if (!(flags & 0x01)) {
+			/* Don't look at children of a not present device */
+
+			return_ACPI_STATUS(AE_CTRL_DEPTH);
+		}
+	}
+
+	/*
+	 * The device is present. Run _INI.
+	 */
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_INI"));
+	status = acpi_ns_evaluate_relative ("_INI", &pinfo);
+	if (ACPI_FAILURE (status)) {
+		/* No _INI (AE_NOT_FOUND) means device requires no initialization */
+
+		if (status != AE_NOT_FOUND) {
+			/* Ignore error and move on to next device */
+
+#ifdef ACPI_DEBUG_OUTPUT
+			char                *scope_name = acpi_ns_get_external_pathname (pinfo.node);
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n",
+					scope_name, acpi_format_exception (status)));
+
+			ACPI_MEM_FREE (scope_name);
+#endif
+		}
+
+		status = AE_OK;
+	}
+	else {
+		/* Delete any return object (especially if implicit_return is enabled) */
+
+		if (pinfo.return_object) {
+			acpi_ut_remove_reference (pinfo.return_object);
+		}
+
+		/* Count of successful INIs */
+
+		info->num_INI++;
+	}
+
+	if (acpi_gbl_init_handler) {
+		/* External initialization handler is present, call it */
+
+		status = acpi_gbl_init_handler (pinfo.node, ACPI_INIT_DEVICE_INI);
+	}
+
+	return_ACPI_STATUS (status);
+}
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
new file mode 100644
index 0000000..1d7aedf
--- /dev/null
+++ b/drivers/acpi/namespace/nsload.c
@@ -0,0 +1,460 @@
+/******************************************************************************
+ *
+ * Module Name: nsload - namespace loading/expanding/contracting procedures
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdispat.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsload")
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_load_table
+ *
+ * PARAMETERS:  table_desc      - Descriptor for table to be loaded
+ *              Node            - Owning NS node
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load one ACPI table into the namespace
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_load_table (
+	struct acpi_table_desc          *table_desc,
+	struct acpi_namespace_node      *node)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ns_load_table");
+
+
+	/* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
+
+	if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
+		/* Just ignore this table */
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Check validity of the AML start and length */
+
+	if (!table_desc->aml_start) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null AML pointer\n"));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n",
+		table_desc->aml_start));
+
+	/* Ignore table if there is no AML contained within */
+
+	if (!table_desc->aml_length) {
+		ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n",
+			table_desc->pointer->signature));
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * Parse the table and load the namespace with all named
+	 * objects found within.  Control methods are NOT parsed
+	 * at this time.  In fact, the control methods cannot be
+	 * parsed until the entire namespace is loaded, because
+	 * if a control method makes a forward reference (call)
+	 * to another control method, we can't continue parsing
+	 * because we don't know how many arguments to parse next!
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"**** Loading table into namespace ****\n"));
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ns_parse_table (table_desc, node->child);
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Now we can parse the control methods.  We always parse
+	 * them here for a sanity check, and if configured for
+	 * just-in-time parsing, we delete the control method
+	 * parse trees.
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"**** Begin Table Method Parsing and Object Initialization ****\n"));
+
+	status = acpi_ds_initialize_objects (table_desc, node);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"**** Completed Table Method Parsing and Object Initialization ****\n"));
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_load_table_by_type
+ *
+ * PARAMETERS:  table_type          - Id of the table type to load
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load an ACPI table or tables into the namespace.  All tables
+ *              of the given type are loaded.  The mechanism allows this
+ *              routine to be called repeatedly.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_load_table_by_type (
+	acpi_table_type                 table_type)
+{
+	u32                             i;
+	acpi_status                     status;
+	struct acpi_table_desc          *table_desc;
+
+
+	ACPI_FUNCTION_TRACE ("ns_load_table_by_type");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Table types supported are:
+	 * DSDT (one), SSDT/PSDT (multiple)
+	 */
+	switch (table_type) {
+	case ACPI_TABLE_DSDT:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n"));
+
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next;
+
+		/* If table already loaded into namespace, just return */
+
+		if (table_desc->loaded_into_namespace) {
+			goto unlock_and_exit;
+		}
+
+		/* Now load the single DSDT */
+
+		status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
+		if (ACPI_SUCCESS (status)) {
+			table_desc->loaded_into_namespace = TRUE;
+		}
+		break;
+
+
+	case ACPI_TABLE_SSDT:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n",
+			acpi_gbl_table_lists[ACPI_TABLE_SSDT].count));
+
+		/*
+		 * Traverse list of SSDT tables
+		 */
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next;
+		for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) {
+			/*
+			 * Only attempt to load table if it is not
+			 * already loaded!
+			 */
+			if (!table_desc->loaded_into_namespace) {
+				status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
+				if (ACPI_FAILURE (status)) {
+					break;
+				}
+
+				table_desc->loaded_into_namespace = TRUE;
+			}
+
+			table_desc = table_desc->next;
+		}
+		break;
+
+
+	case ACPI_TABLE_PSDT:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n",
+			acpi_gbl_table_lists[ACPI_TABLE_PSDT].count));
+
+		/*
+		 * Traverse list of PSDT tables
+		 */
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next;
+
+		for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) {
+			/* Only attempt to load table if it is not already loaded! */
+
+			if (!table_desc->loaded_into_namespace) {
+				status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
+				if (ACPI_FAILURE (status)) {
+					break;
+				}
+
+				table_desc->loaded_into_namespace = TRUE;
+			}
+
+			table_desc = table_desc->next;
+		}
+		break;
+
+
+	default:
+		status = AE_SUPPORT;
+		break;
+	}
+
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_load_namespace
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
+ *              (DSDT points to either the BIOS or a buffer.)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_load_namespace (
+	void)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_load_name_space");
+
+
+	/* There must be at least a DSDT installed */
+
+	if (acpi_gbl_DSDT == NULL) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "DSDT is not in memory\n"));
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	/*
+	 * Load the namespace.  The DSDT is required,
+	 * but the SSDT and PSDT tables are optional.
+	 */
+	status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Ignore exceptions from these */
+
+	(void) acpi_ns_load_table_by_type (ACPI_TABLE_SSDT);
+	(void) acpi_ns_load_table_by_type (ACPI_TABLE_PSDT);
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+		"ACPI Namespace successfully loaded at root %p\n",
+		acpi_gbl_root_node));
+
+	return_ACPI_STATUS (status);
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_delete_subtree
+ *
+ * PARAMETERS:  start_handle        - Handle in namespace where search begins
+ *
+ * RETURNS      Status
+ *
+ * DESCRIPTION: Walks the namespace starting at the given handle and deletes
+ *              all objects, entries, and scopes in the entire subtree.
+ *
+ *              Namespace/Interpreter should be locked or the subsystem should
+ *              be in shutdown before this routine is called.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_delete_subtree (
+	acpi_handle                     start_handle)
+{
+	acpi_status                     status;
+	acpi_handle                     child_handle;
+	acpi_handle                     parent_handle;
+	acpi_handle                     next_child_handle;
+	acpi_handle                     dummy;
+	u32                             level;
+
+
+	ACPI_FUNCTION_TRACE ("ns_delete_subtree");
+
+
+	parent_handle = start_handle;
+	child_handle = NULL;
+	level        = 1;
+
+	/*
+	 * Traverse the tree of objects until we bubble back up
+	 * to where we started.
+	 */
+	while (level > 0) {
+		/* Attempt to get the next object in this scope */
+
+		status = acpi_get_next_object (ACPI_TYPE_ANY, parent_handle,
+				  child_handle, &next_child_handle);
+
+		child_handle = next_child_handle;
+
+		/* Did we get a new object? */
+
+		if (ACPI_SUCCESS (status)) {
+			/* Check if this object has any children */
+
+			if (ACPI_SUCCESS (acpi_get_next_object (ACPI_TYPE_ANY, child_handle,
+					 NULL, &dummy))) {
+				/*
+				 * There is at least one child of this object,
+				 * visit the object
+				 */
+				level++;
+				parent_handle = child_handle;
+				child_handle = NULL;
+			}
+		}
+		else {
+			/*
+			 * No more children in this object, go back up to
+			 * the object's parent
+			 */
+			level--;
+
+			/* Delete all children now */
+
+			acpi_ns_delete_children (child_handle);
+
+			child_handle = parent_handle;
+			status = acpi_get_parent (parent_handle, &parent_handle);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+	}
+
+	/* Now delete the starting object, and we are done */
+
+	acpi_ns_delete_node (child_handle);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ *  FUNCTION:       acpi_ns_unload_name_space
+ *
+ *  PARAMETERS:     Handle          - Root of namespace subtree to be deleted
+ *
+ *  RETURN:         Status
+ *
+ *  DESCRIPTION:    Shrinks the namespace, typically in response to an undocking
+ *                  event.  Deletes an entire subtree starting from (and
+ *                  including) the given handle.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_unload_namespace (
+	acpi_handle                     handle)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ns_unload_name_space");
+
+
+	/* Parameter validation */
+
+	if (!acpi_gbl_root_node) {
+		return_ACPI_STATUS (AE_NO_NAMESPACE);
+	}
+
+	if (!handle) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* This function does the real work */
+
+	status = acpi_ns_delete_subtree (handle);
+
+	return_ACPI_STATUS (status);
+}
+
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+#endif
+
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
new file mode 100644
index 0000000..b6f8f91
--- /dev/null
+++ b/drivers/acpi/namespace/nsnames.c
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ *
+ * Module Name: nsnames - Name manipulation and search
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsnames")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_build_external_path
+ *
+ * PARAMETERS:  Node            - NS node whose pathname is needed
+ *              Size            - Size of the pathname
+ *              *name_buffer    - Where to return the pathname
+ *
+ * RETURN:      Places the pathname into the name_buffer, in external format
+ *              (name segments separated by path separators)
+ *
+ * DESCRIPTION: Generate a full pathaname
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_build_external_path (
+	struct acpi_namespace_node      *node,
+	acpi_size                       size,
+	char                            *name_buffer)
+{
+	acpi_size                       index;
+	struct acpi_namespace_node      *parent_node;
+
+
+	ACPI_FUNCTION_NAME ("ns_build_external_path");
+
+
+	/* Special case for root */
+
+	index = size - 1;
+	if (index < ACPI_NAME_SIZE) {
+		name_buffer[0] = AML_ROOT_PREFIX;
+		name_buffer[1] = 0;
+		return;
+	}
+
+	/* Store terminator byte, then build name backwards */
+
+	parent_node = node;
+	name_buffer[index] = 0;
+
+	while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) {
+		index -= ACPI_NAME_SIZE;
+
+		/* Put the name into the buffer */
+
+		ACPI_MOVE_32_TO_32 ((name_buffer + index), &parent_node->name);
+		parent_node = acpi_ns_get_parent_node (parent_node);
+
+		/* Prefix name with the path separator */
+
+		index--;
+		name_buffer[index] = ACPI_PATH_SEPARATOR;
+	}
+
+	/* Overwrite final separator with the root prefix character */
+
+	name_buffer[index] = AML_ROOT_PREFIX;
+
+	if (index != 0) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not construct pathname; index=%X, size=%X, Path=%s\n",
+			(u32) index, (u32) size, &name_buffer[size]));
+	}
+
+	return;
+}
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_external_pathname
+ *
+ * PARAMETERS:  Node            - NS node whose pathname is needed
+ *
+ * RETURN:      Pointer to storage containing the fully qualified name of
+ *              the node, In external format (name segments separated by path
+ *              separators.)
+ *
+ * DESCRIPTION: Used for debug printing in acpi_ns_search_table().
+ *
+ ******************************************************************************/
+
+char *
+acpi_ns_get_external_pathname (
+	struct acpi_namespace_node      *node)
+{
+	char                            *name_buffer;
+	acpi_size                       size;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ns_get_external_pathname", node);
+
+
+	/* Calculate required buffer size based on depth below root */
+
+	size = acpi_ns_get_pathname_length (node);
+
+	/* Allocate a buffer to be returned to caller */
+
+	name_buffer = ACPI_MEM_CALLOCATE (size);
+	if (!name_buffer) {
+		ACPI_REPORT_ERROR (("ns_get_table_pathname: allocation failure\n"));
+		return_PTR (NULL);
+	}
+
+	/* Build the path in the allocated buffer */
+
+	acpi_ns_build_external_path (node, size, name_buffer);
+	return_PTR (name_buffer);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_pathname_length
+ *
+ * PARAMETERS:  Node        - Namespace node
+ *
+ * RETURN:      Length of path, including prefix
+ *
+ * DESCRIPTION: Get the length of the pathname string for this node
+ *
+ ******************************************************************************/
+
+acpi_size
+acpi_ns_get_pathname_length (
+	struct acpi_namespace_node      *node)
+{
+	acpi_size                       size;
+	struct acpi_namespace_node      *next_node;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * Compute length of pathname as 5 * number of name segments.
+	 * Go back up the parent tree to the root
+	 */
+	size = 0;
+	next_node = node;
+
+	while (next_node && (next_node != acpi_gbl_root_node)) {
+		size += ACPI_PATH_SEGMENT_LENGTH;
+		next_node = acpi_ns_get_parent_node (next_node);
+	}
+
+	if (!size) {
+		size = 1;       /* Root node case */
+	}
+
+	return (size + 1);  /* +1 for null string terminator */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_handle_to_pathname
+ *
+ * PARAMETERS:  target_handle           - Handle of named object whose name is
+ *                                        to be found
+ *              Buffer                  - Where the pathname is returned
+ *
+ * RETURN:      Status, Buffer is filled with pathname if status is AE_OK
+ *
+ * DESCRIPTION: Build and return a full namespace pathname
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_handle_to_pathname (
+	acpi_handle                     target_handle,
+	struct acpi_buffer              *buffer)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	acpi_size                       required_size;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ns_handle_to_pathname", target_handle);
+
+
+	node = acpi_ns_map_handle_to_node (target_handle);
+	if (!node) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Determine size required for the caller buffer */
+
+	required_size = acpi_ns_get_pathname_length (node);
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (buffer, required_size);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Build the path in the caller buffer */
+
+	acpi_ns_build_external_path (node, required_size, buffer->pointer);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X] \n",
+		(char *) buffer->pointer, (u32) required_size));
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
new file mode 100644
index 0000000..4e41e66
--- /dev/null
+++ b/drivers/acpi/namespace/nsobject.c
@@ -0,0 +1,461 @@
+/*******************************************************************************
+ *
+ * Module Name: nsobject - Utilities for objects attached to namespace
+ *                         table entries
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsobject")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_attach_object
+ *
+ * PARAMETERS:  Node                - Parent Node
+ *              Object              - Object to be attached
+ *              Type                - Type of object, or ACPI_TYPE_ANY if not
+ *                                    known
+ *
+ * DESCRIPTION: Record the given object as the value associated with the
+ *              name whose acpi_handle is passed.  If Object is NULL
+ *              and Type is ACPI_TYPE_ANY, set the name as having no value.
+ *              Note: Future may require that the Node->Flags field be passed
+ *              as a parameter.
+ *
+ * MUTEX:       Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_attach_object (
+	struct acpi_namespace_node      *node,
+	union acpi_operand_object       *object,
+	acpi_object_type                type)
+{
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *last_obj_desc;
+	acpi_object_type                object_type = ACPI_TYPE_ANY;
+
+
+	ACPI_FUNCTION_TRACE ("ns_attach_object");
+
+
+	/*
+	 * Parameter validation
+	 */
+	if (!node) {
+		/* Invalid handle */
+
+		ACPI_REPORT_ERROR (("ns_attach_object: Null named_obj handle\n"));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (!object && (ACPI_TYPE_ANY != type)) {
+		/* Null object */
+
+		ACPI_REPORT_ERROR (("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
+		/* Not a name handle */
+
+		ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle %p [%s]\n",
+				node, acpi_ut_get_descriptor_name (node)));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Check if this object is already attached */
+
+	if (node->object == object) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj %p already installed in name_obj %p\n",
+			object, node));
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* If null object, we will just install it */
+
+	if (!object) {
+		obj_desc   = NULL;
+		object_type = ACPI_TYPE_ANY;
+	}
+
+	/*
+	 * If the source object is a namespace Node with an attached object,
+	 * we will use that (attached) object
+	 */
+	else if ((ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) &&
+			((struct acpi_namespace_node *) object)->object) {
+		/*
+		 * Value passed is a name handle and that name has a
+		 * non-null value.  Use that name's value and type.
+		 */
+		obj_desc   = ((struct acpi_namespace_node *) object)->object;
+		object_type = ((struct acpi_namespace_node *) object)->type;
+	}
+
+	/*
+	 * Otherwise, we will use the parameter object, but we must type
+	 * it first
+	 */
+	else {
+		obj_desc = (union acpi_operand_object   *) object;
+
+		/* Use the given type */
+
+		object_type = type;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
+		obj_desc, node, acpi_ut_get_node_name (node)));
+
+	/* Detach an existing attached object if present */
+
+	if (node->object) {
+		acpi_ns_detach_object (node);
+	}
+
+	if (obj_desc) {
+		/*
+		 * Must increment the new value's reference count
+		 * (if it is an internal object)
+		 */
+		acpi_ut_add_reference (obj_desc);
+
+		/*
+		 * Handle objects with multiple descriptors - walk
+		 * to the end of the descriptor list
+		 */
+		last_obj_desc = obj_desc;
+		while (last_obj_desc->common.next_object) {
+			last_obj_desc = last_obj_desc->common.next_object;
+		}
+
+		/* Install the object at the front of the object list */
+
+		last_obj_desc->common.next_object = node->object;
+	}
+
+	node->type     = (u8) object_type;
+	node->object   = obj_desc;
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_detach_object
+ *
+ * PARAMETERS:  Node           - An node whose object will be detached
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Detach/delete an object associated with a namespace node.
+ *              if the object is an allocated object, it is freed.
+ *              Otherwise, the field is simply cleared.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_detach_object (
+	struct acpi_namespace_node      *node)
+{
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE ("ns_detach_object");
+
+
+	obj_desc = node->object;
+
+	if (!obj_desc ||
+		(ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+		return_VOID;
+	}
+
+	/* Clear the entry in all cases */
+
+	node->object = NULL;
+	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 = node->object->common.next_object;
+		}
+	}
+
+	/* Reset the node type to untyped */
+
+	node->type = ACPI_TYPE_ANY;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
+		node, acpi_ut_get_node_name (node), obj_desc));
+
+	/* Remove one reference on the object (and all subobjects) */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_attached_object
+ *
+ * PARAMETERS:  Node             - Parent Node to be examined
+ *
+ * RETURN:      Current value of the object field from the Node whose
+ *              handle is passed
+ *
+ * DESCRIPTION: Obtain the object attached to a namespace node.
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ns_get_attached_object (
+	struct acpi_namespace_node      *node)
+{
+	ACPI_FUNCTION_TRACE_PTR ("ns_get_attached_object", node);
+
+
+	if (!node) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Null Node ptr\n"));
+		return_PTR (NULL);
+	}
+
+	if (!node->object ||
+			((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)) {
+		return_PTR (NULL);
+	}
+
+	return_PTR (node->object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_secondary_object
+ *
+ * PARAMETERS:  Node             - Parent Node to be examined
+ *
+ * RETURN:      Current value of the object field from the Node whose
+ *              handle is passed.
+ *
+ * DESCRIPTION: Obtain a secondary object associated with a namespace node.
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ns_get_secondary_object (
+	union acpi_operand_object       *obj_desc)
+{
+	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.next_object)                           ||
+		(ACPI_GET_OBJECT_TYPE (obj_desc->common.next_object) == ACPI_TYPE_LOCAL_DATA)) {
+		return_PTR (NULL);
+	}
+
+	return_PTR (obj_desc->common.next_object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_attach_data
+ *
+ * PARAMETERS:  Node            - Namespace node
+ *              Handler         - Handler to be associated with the data
+ *              Data            - Data to be attached
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Low-level attach data.  Create and attach a Data object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_attach_data (
+	struct acpi_namespace_node      *node,
+	acpi_object_handler             handler,
+	void                            *data)
+{
+	union acpi_operand_object       *prev_obj_desc;
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *data_desc;
+
+
+	/* We only allow one attachment per handler */
+
+	prev_obj_desc = NULL;
+	obj_desc = node->object;
+	while (obj_desc) {
+		if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+			(obj_desc->data.handler == handler)) {
+			return (AE_ALREADY_EXISTS);
+		}
+
+		prev_obj_desc = obj_desc;
+		obj_desc = obj_desc->common.next_object;
+	}
+
+	/* Create an internal object for the data */
+
+	data_desc = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_DATA);
+	if (!data_desc) {
+		return (AE_NO_MEMORY);
+	}
+
+	data_desc->data.handler = handler;
+	data_desc->data.pointer = data;
+
+	/* Install the data object */
+
+	if (prev_obj_desc) {
+		prev_obj_desc->common.next_object = data_desc;
+	}
+	else {
+		node->object = data_desc;
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_detach_data
+ *
+ * PARAMETERS:  Node            - Namespace node
+ *              Handler         - Handler associated with the data
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Low-level detach data.  Delete the data node, but the caller
+ *              is responsible for the actual data.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_detach_data (
+	struct acpi_namespace_node      *node,
+	acpi_object_handler             handler)
+{
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *prev_obj_desc;
+
+
+	prev_obj_desc = NULL;
+	obj_desc = node->object;
+	while (obj_desc) {
+		if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+			(obj_desc->data.handler == handler)) {
+			if (prev_obj_desc) {
+				prev_obj_desc->common.next_object = obj_desc->common.next_object;
+			}
+			else {
+				node->object = obj_desc->common.next_object;
+			}
+
+			acpi_ut_remove_reference (obj_desc);
+			return (AE_OK);
+		}
+
+		prev_obj_desc = obj_desc;
+		obj_desc = obj_desc->common.next_object;
+	}
+
+	return (AE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_attached_data
+ *
+ * PARAMETERS:  Node            - Namespace node
+ *              Handler         - Handler associated with the data
+ *              Data            - Where the data is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Low level interface to obtain data previously associated with
+ *              a namespace node.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_get_attached_data (
+	struct acpi_namespace_node      *node,
+	acpi_object_handler             handler,
+	void                            **data)
+{
+	union acpi_operand_object       *obj_desc;
+
+
+	obj_desc = node->object;
+	while (obj_desc) {
+		if ((ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+			(obj_desc->data.handler == handler)) {
+			*data = obj_desc->data.pointer;
+			return (AE_OK);
+		}
+
+		obj_desc = obj_desc->common.next_object;
+	}
+
+	return (AE_NOT_FOUND);
+}
+
+
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
new file mode 100644
index 0000000..a0e13e8
--- /dev/null
+++ b/drivers/acpi/namespace/nsparse.c
@@ -0,0 +1,171 @@
+/******************************************************************************
+ *
+ * Module Name: nsparse - namespace interface to AML parser
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsparse")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    ns_one_complete_parse
+ *
+ * PARAMETERS:  pass_number             - 1 or 2
+ *              table_desc              - The table to be parsed.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_one_complete_parse (
+	u32                             pass_number,
+	struct acpi_table_desc          *table_desc)
+{
+	union acpi_parse_object         *parse_root;
+	acpi_status                     status;
+	struct acpi_walk_state          *walk_state;
+
+
+	ACPI_FUNCTION_TRACE ("ns_one_complete_parse");
+
+
+	/* Create and init a Root Node */
+
+	parse_root = acpi_ps_create_scope_op ();
+	if (!parse_root) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Create and initialize a new walk state */
+
+	walk_state = acpi_ds_create_walk_state (table_desc->table_id,
+			   NULL, NULL, NULL);
+	if (!walk_state) {
+		acpi_ps_free_op (parse_root);
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL,
+			  table_desc->aml_start, table_desc->aml_length,
+			  NULL, pass_number);
+	if (ACPI_FAILURE (status)) {
+		acpi_ds_delete_walk_state (walk_state);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Parse the AML */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", pass_number));
+	status = acpi_ps_parse_aml (walk_state);
+
+	acpi_ps_delete_parse_tree (parse_root);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_parse_table
+ *
+ * PARAMETERS:  table_desc      - An ACPI table descriptor for table to parse
+ *              start_node      - Where to enter the table into the namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_parse_table (
+	struct acpi_table_desc          *table_desc,
+	struct acpi_namespace_node      *start_node)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ns_parse_table");
+
+
+	/*
+	 * AML Parse, pass 1
+	 *
+	 * In this pass, we load most of the namespace.  Control methods
+	 * are not parsed until later.  A parse tree is not created.  Instead,
+	 * each Parser Op subtree is deleted when it is finished.  This saves
+	 * a great deal of memory, and allows a small cache of parse objects
+	 * to service the entire parse.  The second pass of the parse then
+	 * performs another complete parse of the AML..
+	 */
+	status = acpi_ns_one_complete_parse (1, table_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * AML Parse, pass 2
+	 *
+	 * In this pass, we resolve forward references and other things
+	 * that could not be completed during the first pass.
+	 * Another complete parse of the AML is performed, but the
+	 * overhead of this is compensated for by the fact that the
+	 * parse objects are all cached.
+	 */
+	status = acpi_ns_one_complete_parse (2, table_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
new file mode 100644
index 0000000..0e6dea2
--- /dev/null
+++ b/drivers/acpi/namespace/nssearch.c
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ *
+ * Module Name: nssearch - Namespace search
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nssearch")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_search_node
+ *
+ * PARAMETERS:  *target_name        - Ascii ACPI name to search for
+ *              *Node               - Starting node where search will begin
+ *              Type                - Object type to match
+ *              **return_node       - Where the matched Named obj is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Search a single level of the namespace.  Performs a
+ *              simple search of the specified level, and does not add
+ *              entries or search parents.
+ *
+ *
+ *      Named object lists are built (and subsequently dumped) in the
+ *      order in which the names are encountered during the namespace load;
+ *
+ *      All namespace searching is linear in this implementation, but
+ *      could be easily modified to support any improved search
+ *      algorithm.  However, the linear search was chosen for simplicity
+ *      and because the trees are small and the other interpreter
+ *      execution overhead is relatively high.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_search_node (
+	u32                             target_name,
+	struct acpi_namespace_node      *node,
+	acpi_object_type                type,
+	struct acpi_namespace_node      **return_node)
+{
+	struct acpi_namespace_node      *next_node;
+
+
+	ACPI_FUNCTION_TRACE ("ns_search_node");
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+	if (ACPI_LV_NAMES & acpi_dbg_level) {
+		char                        *scope_name;
+
+		scope_name = acpi_ns_get_external_pathname (node);
+		if (scope_name) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Searching %s (%p) For [%4.4s] (%s)\n",
+				scope_name, node, (char *) &target_name,
+				acpi_ut_get_type_name (type)));
+
+			ACPI_MEM_FREE (scope_name);
+		}
+	}
+#endif
+
+	/*
+	 * Search for name at this namespace level, which is to say that we
+	 * must search for the name among the children of this object
+	 */
+	next_node = node->child;
+	while (next_node) {
+		/* Check for match against the name */
+
+		if (next_node->name.integer == target_name) {
+			/* Resolve a control method alias if any */
+
+			if (acpi_ns_get_type (next_node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+				next_node = ACPI_CAST_PTR (struct acpi_namespace_node, next_node->object);
+			}
+
+			/*
+			 * Found matching entry.
+			 */
+			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+				"Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
+				(char *) &target_name, acpi_ut_get_type_name (next_node->type),
+				next_node, acpi_ut_get_node_name (node), node));
+
+			*return_node = next_node;
+			return_ACPI_STATUS (AE_OK);
+		}
+
+		/*
+		 * The last entry in the list points back to the parent,
+		 * so a flag is used to indicate the end-of-list
+		 */
+		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+			/* Searched entire list, we are done */
+
+			break;
+		}
+
+		/* Didn't match name, move on to the next peer object */
+
+		next_node = next_node->peer;
+	}
+
+	/* 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",
+		(char *) &target_name, acpi_ut_get_type_name (type),
+		acpi_ut_get_node_name (node), node, node->child));
+
+	return_ACPI_STATUS (AE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_search_parent_tree
+ *
+ * PARAMETERS:  *target_name        - Ascii ACPI name to search for
+ *              *Node               - Starting node where search will begin
+ *              Type                - Object type to match
+ *              **return_node       - Where the matched Node is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called when a name has not been found in the current namespace
+ *              level.  Before adding it or giving up, ACPI scope rules require
+ *              searching enclosing scopes in cases identified by acpi_ns_local().
+ *
+ *              "A name is located by finding the matching name in the current
+ *              name space, and then in the parent name space. If the parent
+ *              name space does not contain the name, the search continues
+ *              recursively until either the name is found or the name space
+ *              does not have a parent (the root of the name space).  This
+ *              indicates that the name is not found" (From ACPI Specification,
+ *              section 5.3)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_search_parent_tree (
+	u32                             target_name,
+	struct acpi_namespace_node      *node,
+	acpi_object_type                type,
+	struct acpi_namespace_node      **return_node)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *parent_node;
+
+
+	ACPI_FUNCTION_TRACE ("ns_search_parent_tree");
+
+
+	parent_node = acpi_ns_get_parent_node (node);
+
+	/*
+	 * If there is no parent (i.e., we are at the root) or type is "local",
+	 * we won't be searching the parent tree.
+	 */
+	if (!parent_node) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
+			(char *) &target_name));
+		return_ACPI_STATUS (AE_NOT_FOUND);
+	}
+
+	if (acpi_ns_local (type)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+			"[%4.4s] type [%s] must be local to this scope (no parent search)\n",
+			(char *) &target_name, acpi_ut_get_type_name (type)));
+		return_ACPI_STATUS (AE_NOT_FOUND);
+	}
+
+	/* Search the parent tree */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+		"Searching parent [%4.4s] for [%4.4s]\n",
+		acpi_ut_get_node_name (parent_node), (char *) &target_name));
+
+	/*
+	 * 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
+		 * object type at this point, we only care about the existence of
+		 * the actual name we are searching for.  Typechecking comes later.
+		 */
+		status = acpi_ns_search_node (target_name, parent_node,
+				  ACPI_TYPE_ANY, return_node);
+		if (ACPI_SUCCESS (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/*
+		 * Not found here, go up another level
+		 * (until we reach the root)
+		 */
+		parent_node = acpi_ns_get_parent_node (parent_node);
+	}
+
+	/* Not found in parent tree */
+
+	return_ACPI_STATUS (AE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_search_and_enter
+ *
+ * PARAMETERS:  target_name         - Ascii ACPI name to search for (4 chars)
+ *              walk_state          - Current state of the walk
+ *              *Node               - Starting node where search will begin
+ *              interpreter_mode    - Add names only in ACPI_MODE_LOAD_PASS_x.
+ *                                    Otherwise,search only.
+ *              Type                - Object type to match
+ *              Flags               - Flags describing the search restrictions
+ *              **return_node       - Where the Node is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Search for a name segment in a single namespace level,
+ *              optionally adding it if it is not found.  If the passed
+ *              Type is not Any and the type previously stored in the
+ *              entry was Any (i.e. unknown), update the stored type.
+ *
+ *              In ACPI_IMODE_EXECUTE, search only.
+ *              In other modes, search and add if not found.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_search_and_enter (
+	u32                             target_name,
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      *node,
+	acpi_interpreter_mode           interpreter_mode,
+	acpi_object_type                type,
+	u32                             flags,
+	struct acpi_namespace_node      **return_node)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *new_node;
+
+
+	ACPI_FUNCTION_TRACE ("ns_search_and_enter");
+
+
+	/* Parameter validation */
+
+	if (!node || !target_name || !return_node) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null param: Node %p Name %X return_node %p\n",
+			node, target_name, return_node));
+
+		ACPI_REPORT_ERROR (("ns_search_and_enter: Null parameter\n"));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Name must consist of printable characters */
+
+	if (!acpi_ut_valid_acpi_name (target_name)) {
+		ACPI_REPORT_ERROR (("ns_search_and_enter: Bad character in ACPI Name: %X\n",
+			target_name));
+		return_ACPI_STATUS (AE_BAD_CHARACTER);
+	}
+
+	/* Try to find the name in the namespace level specified by the caller */
+
+	*return_node = ACPI_ENTRY_NOT_FOUND;
+	status = acpi_ns_search_node (target_name, node, type, return_node);
+	if (status != AE_NOT_FOUND) {
+		/*
+		 * If we found it AND the request specifies that a find is an error,
+		 * return the error
+		 */
+		if ((status == AE_OK) &&
+			(flags & ACPI_NS_ERROR_IF_FOUND)) {
+			status = AE_ALREADY_EXISTS;
+		}
+
+		/*
+		 * Either found it or there was an error
+		 * -- finished either way
+		 */
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * The name was not found.  If we are NOT performing the first pass
+	 * (name entry) of loading the namespace, search the parent tree (all the
+	 * way to the root if necessary.) We don't want to perform the parent
+	 * search when the namespace is actually being loaded.  We want to perform
+	 * the search when namespace references are being resolved (load pass 2)
+	 * and during the execution phase.
+	 */
+	if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) &&
+		(flags & ACPI_NS_SEARCH_PARENT)) {
+		/*
+		 * Not found at this level - search parent tree according to the
+		 * ACPI specification
+		 */
+		status = acpi_ns_search_parent_tree (target_name, node, type, return_node);
+		if (ACPI_SUCCESS (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * In execute mode, just search, never add names.  Exit now.
+	 */
+	if (interpreter_mode == ACPI_IMODE_EXECUTE) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+			"%4.4s Not found in %p [Not adding]\n",
+			(char *) &target_name, node));
+
+		return_ACPI_STATUS (AE_NOT_FOUND);
+	}
+
+	/* Create the new named object */
+
+	new_node = acpi_ns_create_node (target_name);
+	if (!new_node) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Install the new object into the parent's list of children */
+
+	acpi_ns_install_node (walk_state, node, new_node, type);
+	*return_node = new_node;
+
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
new file mode 100644
index 0000000..75da76c
--- /dev/null
+++ b/drivers/acpi/namespace/nsutils.c
@@ -0,0 +1,1069 @@
+/******************************************************************************
+ *
+ * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
+ *                        parents and siblings and Scope manipulation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/amlcode.h>
+#include <acpi/actables.h>
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_report_error
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print warning message with full pathname
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_report_error (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id,
+	char                            *internal_name,
+	acpi_status                     lookup_status)
+{
+	acpi_status                     status;
+	char                            *name = NULL;
+
+
+	acpi_os_printf ("%8s-%04d: *** Error: Looking up ",
+		module_name, line_number);
+
+	if (lookup_status == AE_BAD_CHARACTER) {
+		/* There is a non-ascii character in the name */
+
+		acpi_os_printf ("[0x%4.4X] (NON-ASCII)\n",
+			*(ACPI_CAST_PTR (u32, internal_name)));
+	}
+	else {
+		/* Convert path to external format */
+
+		status = acpi_ns_externalize_name (ACPI_UINT32_MAX,
+				 internal_name, NULL, &name);
+
+		/* Print target name */
+
+		if (ACPI_SUCCESS (status)) {
+			acpi_os_printf ("[%s]", name);
+		}
+		else {
+			acpi_os_printf ("[COULD NOT EXTERNALIZE NAME]");
+		}
+
+		if (name) {
+			ACPI_MEM_FREE (name);
+		}
+	}
+
+	acpi_os_printf (" in namespace, %s\n",
+		acpi_format_exception (lookup_status));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_report_method_error
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print warning message with full pathname
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_report_method_error (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id,
+	char                            *message,
+	struct acpi_namespace_node      *prefix_node,
+	char                            *path,
+	acpi_status                     method_status)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node = prefix_node;
+
+
+	if (path) {
+		status = acpi_ns_get_node_by_path (path, prefix_node,
+				 ACPI_NS_NO_UPSEARCH, &node);
+		if (ACPI_FAILURE (status)) {
+			acpi_os_printf ("report_method_error: Could not get node\n");
+			return;
+		}
+	}
+
+	acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
+	acpi_ns_print_node_pathname (node, message);
+	acpi_os_printf (", %s\n", acpi_format_exception (method_status));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_print_node_pathname
+ *
+ * PARAMETERS:  Node                - Object
+ *              Msg                 - Prefix message
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ *              Manages allocation/freeing of a pathname buffer
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_print_node_pathname (
+	struct acpi_namespace_node      *node,
+	char                            *msg)
+{
+	struct acpi_buffer              buffer;
+	acpi_status                     status;
+
+
+	if (!node) {
+		acpi_os_printf ("[NULL NAME]");
+		return;
+	}
+
+	/* Convert handle to full pathname and print it (with supplied message) */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+	status = acpi_ns_handle_to_pathname (node, &buffer);
+	if (ACPI_SUCCESS (status)) {
+		if (msg) {
+			acpi_os_printf ("%s ", msg);
+		}
+
+		acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node);
+		ACPI_MEM_FREE (buffer.pointer);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_valid_root_prefix
+ *
+ * PARAMETERS:  Prefix          - Character to be checked
+ *
+ * RETURN:      TRUE if a valid prefix
+ *
+ * DESCRIPTION: Check if a character is a valid ACPI Root prefix
+ *
+ ******************************************************************************/
+
+u8
+acpi_ns_valid_root_prefix (
+	char                            prefix)
+{
+
+	return ((u8) (prefix == '\\'));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_valid_path_separator
+ *
+ * PARAMETERS:  Sep              - Character to be checked
+ *
+ * RETURN:      TRUE if a valid path separator
+ *
+ * DESCRIPTION: Check if a character is a valid ACPI path separator
+ *
+ ******************************************************************************/
+
+u8
+acpi_ns_valid_path_separator (
+	char                            sep)
+{
+
+	return ((u8) (sep == '.'));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_type
+ *
+ * PARAMETERS:  Handle              - Parent Node to be examined
+ *
+ * RETURN:      Type field from Node whose handle is passed
+ *
+ ******************************************************************************/
+
+acpi_object_type
+acpi_ns_get_type (
+	struct acpi_namespace_node      *node)
+{
+	ACPI_FUNCTION_TRACE ("ns_get_type");
+
+
+	if (!node) {
+		ACPI_REPORT_WARNING (("ns_get_type: Null Node input pointer\n"));
+		return_VALUE (ACPI_TYPE_ANY);
+	}
+
+	return_VALUE ((acpi_object_type) node->type);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_local
+ *
+ * PARAMETERS:  Type            - A namespace object type
+ *
+ * RETURN:      LOCAL if names must be found locally in objects of the
+ *              passed type, 0 if enclosing scopes should be searched
+ *
+ ******************************************************************************/
+
+u32
+acpi_ns_local (
+	acpi_object_type                type)
+{
+	ACPI_FUNCTION_TRACE ("ns_local");
+
+
+	if (!acpi_ut_valid_object_type (type)) {
+		/* Type code out of range  */
+
+		ACPI_REPORT_WARNING (("ns_local: Invalid Object Type\n"));
+		return_VALUE (ACPI_NS_NORMAL);
+	}
+
+	return_VALUE ((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_internal_name_length
+ *
+ * PARAMETERS:  Info            - Info struct initialized with the
+ *                                external name pointer.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Calculate the length of the internal (AML) namestring
+ *              corresponding to the external (ASL) namestring.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_get_internal_name_length (
+	struct acpi_namestring_info     *info)
+{
+	char                            *next_external_char;
+	u32                             i;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	next_external_char = info->external_name;
+	info->num_carats = 0;
+	info->num_segments = 0;
+	info->fully_qualified = FALSE;
+
+	/*
+	 * For the internal name, the required length is 4 bytes per segment, plus
+	 * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null
+	 * (which is not really needed, but no there's harm in putting it there)
+	 *
+	 * strlen() + 1 covers the first name_seg, which has no path separator
+	 */
+	if (acpi_ns_valid_root_prefix (next_external_char[0])) {
+		info->fully_qualified = TRUE;
+		next_external_char++;
+	}
+	else {
+		/*
+		 * Handle Carat prefixes
+		 */
+		while (*next_external_char == '^') {
+			info->num_carats++;
+			next_external_char++;
+		}
+	}
+
+	/*
+	 * Determine the number of ACPI name "segments" by counting the number of
+	 * path separators within the string. Start with one segment since the
+	 * segment count is [(# separators) + 1], and zero separators is ok.
+	 */
+	if (*next_external_char) {
+		info->num_segments = 1;
+		for (i = 0; next_external_char[i]; i++) {
+			if (acpi_ns_valid_path_separator (next_external_char[i])) {
+				info->num_segments++;
+			}
+		}
+	}
+
+	info->length = (ACPI_NAME_SIZE * info->num_segments) +
+			  4 + info->num_carats;
+
+	info->next_external_char = next_external_char;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_build_internal_name
+ *
+ * PARAMETERS:  Info            - Info struct fully initialized
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Construct the internal (AML) namestring
+ *              corresponding to the external (ASL) namestring.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_build_internal_name (
+	struct acpi_namestring_info     *info)
+{
+	u32                             num_segments = info->num_segments;
+	char                            *internal_name = info->internal_name;
+	char                            *external_name = info->next_external_char;
+	char                            *result = NULL;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("ns_build_internal_name");
+
+
+	/* Setup the correct prefixes, counts, and pointers */
+
+	if (info->fully_qualified) {
+		internal_name[0] = '\\';
+
+		if (num_segments <= 1) {
+			result = &internal_name[1];
+		}
+		else if (num_segments == 2) {
+			internal_name[1] = AML_DUAL_NAME_PREFIX;
+			result = &internal_name[2];
+		}
+		else {
+			internal_name[1] = AML_MULTI_NAME_PREFIX_OP;
+			internal_name[2] = (char) num_segments;
+			result = &internal_name[3];
+		}
+	}
+	else {
+		/*
+		 * Not fully qualified.
+		 * Handle Carats first, then append the name segments
+		 */
+		i = 0;
+		if (info->num_carats) {
+			for (i = 0; i < info->num_carats; i++) {
+				internal_name[i] = '^';
+			}
+		}
+
+		if (num_segments <= 1) {
+			result = &internal_name[i];
+		}
+		else if (num_segments == 2) {
+			internal_name[i] = AML_DUAL_NAME_PREFIX;
+			result = &internal_name[(acpi_native_uint) (i+1)];
+		}
+		else {
+			internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
+			internal_name[(acpi_native_uint) (i+1)] = (char) num_segments;
+			result = &internal_name[(acpi_native_uint) (i+2)];
+		}
+	}
+
+	/* Build the name (minus path separators) */
+
+	for (; num_segments; num_segments--) {
+		for (i = 0; i < ACPI_NAME_SIZE; i++) {
+			if (acpi_ns_valid_path_separator (*external_name) ||
+			   (*external_name == 0)) {
+				/* Pad the segment with underscore(s) if segment is short */
+
+				result[i] = '_';
+			}
+			else {
+				/* Convert the character to uppercase and save it */
+
+				result[i] = (char) ACPI_TOUPPER ((int) *external_name);
+				external_name++;
+			}
+		}
+
+		/* Now we must have a path separator, or the pathname is bad */
+
+		if (!acpi_ns_valid_path_separator (*external_name) &&
+			(*external_name != 0)) {
+			return_ACPI_STATUS (AE_BAD_PARAMETER);
+		}
+
+		/* Move on the next segment */
+
+		external_name++;
+		result += ACPI_NAME_SIZE;
+	}
+
+	/* Terminate the string */
+
+	*result = 0;
+
+	if (info->fully_qualified) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
+			internal_name, internal_name));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
+			internal_name, internal_name));
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_internalize_name
+ *
+ * PARAMETERS:  *external_name          - External representation of name
+ *              **Converted Name        - Where to return the resulting
+ *                                        internal represention of the name
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
+ *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
+ *
+ *******************************************************************************/
+
+acpi_status
+acpi_ns_internalize_name (
+	char                            *external_name,
+	char                            **converted_name)
+{
+	char                            *internal_name;
+	struct acpi_namestring_info     info;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ns_internalize_name");
+
+
+	if ((!external_name)     ||
+		(*external_name == 0) ||
+		(!converted_name)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Get the length of the new internal name */
+
+	info.external_name = external_name;
+	acpi_ns_get_internal_name_length (&info);
+
+	/* We need a segment to store the internal  name */
+
+	internal_name = ACPI_MEM_CALLOCATE (info.length);
+	if (!internal_name) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Build the name */
+
+	info.internal_name = internal_name;
+	status = acpi_ns_build_internal_name (&info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (internal_name);
+		return_ACPI_STATUS (status);
+	}
+
+	*converted_name = internal_name;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_externalize_name
+ *
+ * PARAMETERS:  *internal_name         - Internal representation of name
+ *              **converted_name       - Where to return the resulting
+ *                                       external representation of name
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
+ *              to its external form (e.g. "\_PR_.CPU0")
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_externalize_name (
+	u32                             internal_name_length,
+	char                            *internal_name,
+	u32                             *converted_name_length,
+	char                            **converted_name)
+{
+	acpi_native_uint                names_index = 0;
+	acpi_native_uint                num_segments = 0;
+	acpi_native_uint                required_length;
+	acpi_native_uint                prefix_length = 0;
+	acpi_native_uint                i = 0;
+	acpi_native_uint                j = 0;
+
+
+	ACPI_FUNCTION_TRACE ("ns_externalize_name");
+
+
+	if (!internal_name_length   ||
+		!internal_name          ||
+		!converted_name) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Check for a prefix (one '\' | one or more '^').
+	 */
+	switch (internal_name[0]) {
+	case '\\':
+		prefix_length = 1;
+		break;
+
+	case '^':
+		for (i = 0; i < internal_name_length; i++) {
+			if (internal_name[i] == '^') {
+				prefix_length = i + 1;
+			}
+			else {
+				break;
+			}
+		}
+
+		if (i == internal_name_length) {
+			prefix_length = i;
+		}
+
+		break;
+
+	default:
+		break;
+	}
+
+	/*
+	 * Check for object names.  Note that there could be 0-255 of these
+	 * 4-byte elements.
+	 */
+	if (prefix_length < internal_name_length) {
+		switch (internal_name[prefix_length]) {
+		case AML_MULTI_NAME_PREFIX_OP:
+
+			/* <count> 4-byte names */
+
+			names_index = prefix_length + 2;
+			num_segments = (acpi_native_uint) (u8)
+					   internal_name[(acpi_native_uint) (prefix_length + 1)];
+			break;
+
+		case AML_DUAL_NAME_PREFIX:
+
+			/* Two 4-byte names */
+
+			names_index = prefix_length + 1;
+			num_segments = 2;
+			break;
+
+		case 0:
+
+			/* null_name */
+
+			names_index = 0;
+			num_segments = 0;
+			break;
+
+		default:
+
+			/* one 4-byte name */
+
+			names_index = prefix_length;
+			num_segments = 1;
+			break;
+		}
+	}
+
+	/*
+	 * Calculate the length of converted_name, which equals the length
+	 * of the prefix, length of all object names, length of any required
+	 * punctuation ('.') between object names, plus the NULL terminator.
+	 */
+	required_length = prefix_length + (4 * num_segments) +
+			   ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
+
+	/*
+	 * Check to see if we're still in bounds.  If not, there's a problem
+	 * with internal_name (invalid format).
+	 */
+	if (required_length > internal_name_length) {
+		ACPI_REPORT_ERROR (("ns_externalize_name: Invalid internal name\n"));
+		return_ACPI_STATUS (AE_BAD_PATHNAME);
+	}
+
+	/*
+	 * Build converted_name
+	 */
+	*converted_name = ACPI_MEM_CALLOCATE (required_length);
+	if (!(*converted_name)) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	j = 0;
+
+	for (i = 0; i < prefix_length; i++) {
+		(*converted_name)[j++] = internal_name[i];
+	}
+
+	if (num_segments > 0) {
+		for (i = 0; i < num_segments; i++) {
+			if (i > 0) {
+				(*converted_name)[j++] = '.';
+			}
+
+			(*converted_name)[j++] = internal_name[names_index++];
+			(*converted_name)[j++] = internal_name[names_index++];
+			(*converted_name)[j++] = internal_name[names_index++];
+			(*converted_name)[j++] = internal_name[names_index++];
+		}
+	}
+
+	if (converted_name_length) {
+		*converted_name_length = (u32) required_length;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_map_handle_to_node
+ *
+ * PARAMETERS:  Handle          - Handle to be converted to an Node
+ *
+ * RETURN:      A Name table entry pointer
+ *
+ * DESCRIPTION: Convert a namespace handle to a real Node
+ *
+ * Note: Real integer handles allow for more verification
+ *       and keep all pointers within this subsystem.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *
+acpi_ns_map_handle_to_node (
+	acpi_handle                     handle)
+{
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * Simple implementation.
+	 */
+	if (!handle) {
+		return (NULL);
+	}
+
+	if (handle == ACPI_ROOT_OBJECT) {
+		return (acpi_gbl_root_node);
+	}
+
+	/* We can at least attempt to verify the handle */
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (handle) != ACPI_DESC_TYPE_NAMED) {
+		return (NULL);
+	}
+
+	return ((struct acpi_namespace_node *) handle);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_convert_entry_to_handle
+ *
+ * PARAMETERS:  Node          - Node to be converted to a Handle
+ *
+ * RETURN:      A user handle
+ *
+ * DESCRIPTION: Convert a real Node to a namespace handle
+ *
+ ******************************************************************************/
+
+acpi_handle
+acpi_ns_convert_entry_to_handle (
+	struct acpi_namespace_node          *node)
+{
+
+
+	/*
+	 * Simple implementation for now;
+	 */
+	return ((acpi_handle) node);
+
+
+/* ---------------------------------------------------
+
+	if (!Node)
+	{
+		return (NULL);
+	}
+
+	if (Node == acpi_gbl_root_node)
+	{
+		return (ACPI_ROOT_OBJECT);
+	}
+
+
+	return ((acpi_handle) Node);
+------------------------------------------------------*/
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_terminate
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: free memory allocated for table storage.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_terminate (void)
+{
+	union acpi_operand_object       *obj_desc;
+
+
+	ACPI_FUNCTION_TRACE ("ns_terminate");
+
+
+	/*
+	 * 1) Free the entire namespace -- all nodes and objects
+	 *
+	 * Delete all object descriptors attached to namepsace nodes
+	 */
+	acpi_ns_delete_namespace_subtree (acpi_gbl_root_node);
+
+	/* Detach any objects attached to the root */
+
+	obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node);
+	if (obj_desc) {
+		acpi_ns_detach_object (acpi_gbl_root_node);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
+
+	/*
+	 * 2) Now we can delete the ACPI tables
+	 */
+	acpi_tb_delete_all_tables ();
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_opens_scope
+ *
+ * PARAMETERS:  Type        - A valid namespace type
+ *
+ * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
+ *              to the ACPI specification, else 0
+ *
+ ******************************************************************************/
+
+u32
+acpi_ns_opens_scope (
+	acpi_object_type                type)
+{
+	ACPI_FUNCTION_TRACE_STR ("ns_opens_scope", acpi_ut_get_type_name (type));
+
+
+	if (!acpi_ut_valid_object_type (type)) {
+		/* type code out of range  */
+
+		ACPI_REPORT_WARNING (("ns_opens_scope: Invalid Object Type %X\n", type));
+		return_VALUE (ACPI_NS_NORMAL);
+	}
+
+	return_VALUE (((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_node_by_path
+ *
+ * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
+ *                            \ (backslash) and ^ (carat) prefixes, and the
+ *                            . (period) to separate segments are supported.
+ *              start_node  - Root of subtree to be searched, or NS_ALL for the
+ *                            root of the name space.  If Name is fully
+ *                            qualified (first s8 is '\'), the passed value
+ *                            of Scope will not be accessed.
+ *              Flags       - Used to indicate whether to perform upsearch or
+ *                            not.
+ *              return_node - Where the Node is returned
+ *
+ * DESCRIPTION: Look up a name relative to a given scope and return the
+ *              corresponding Node.  NOTE: Scope can be null.
+ *
+ * MUTEX:       Locks namespace
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_get_node_by_path (
+	char                            *pathname,
+	struct acpi_namespace_node      *start_node,
+	u32                             flags,
+	struct acpi_namespace_node      **return_node)
+{
+	union acpi_generic_state        scope_info;
+	acpi_status                     status;
+	char                            *internal_path = NULL;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ns_get_node_by_path", pathname);
+
+
+	if (pathname) {
+		/* Convert path to internal representation */
+
+		status = acpi_ns_internalize_name (pathname, &internal_path);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Must lock namespace during lookup */
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Setup lookup scope (search starting point) */
+
+	scope_info.scope.node = start_node;
+
+	/* Lookup the name in the namespace */
+
+	status = acpi_ns_lookup (&scope_info, internal_path,
+			 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+			 (flags | ACPI_NS_DONT_OPEN_SCOPE),
+			 NULL, return_node);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n",
+				internal_path, acpi_format_exception (status)));
+	}
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+
+cleanup:
+	/* Cleanup */
+	if (internal_path) {
+		ACPI_MEM_FREE (internal_path);
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_find_parent_name
+ *
+ * PARAMETERS:  *child_node            - Named Obj whose name is to be found
+ *
+ * RETURN:      The ACPI name
+ *
+ * DESCRIPTION: Search for the given obj in its parent scope and return the
+ *              name segment, or "????" if the parent name can't be found
+ *              (which "should not happen").
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_name
+acpi_ns_find_parent_name (
+	struct acpi_namespace_node      *child_node)
+{
+	struct acpi_namespace_node      *parent_node;
+
+
+	ACPI_FUNCTION_TRACE ("ns_find_parent_name");
+
+
+	if (child_node) {
+		/* Valid entry.  Get the parent Node */
+
+		parent_node = acpi_ns_get_parent_node (child_node);
+		if (parent_node) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"Parent of %p [%4.4s] is %p [%4.4s]\n",
+				child_node, acpi_ut_get_node_name (child_node),
+				parent_node, acpi_ut_get_node_name (parent_node)));
+
+			if (parent_node->name.integer) {
+				return_VALUE ((acpi_name) parent_node->name.integer);
+			}
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Unable to find parent of %p (%4.4s)\n",
+			child_node, acpi_ut_get_node_name (child_node)));
+	}
+
+	return_VALUE (ACPI_UNKNOWN_NAME);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_parent_node
+ *
+ * PARAMETERS:  Node       - Current table entry
+ *
+ * RETURN:      Parent entry of the given entry
+ *
+ * DESCRIPTION: Obtain the parent entry for a given entry in the namespace.
+ *
+ ******************************************************************************/
+
+
+struct acpi_namespace_node *
+acpi_ns_get_parent_node (
+	struct acpi_namespace_node      *node)
+{
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (!node) {
+		return (NULL);
+	}
+
+	/*
+	 * Walk to the end of this peer list. The last entry is marked with a flag
+	 * and the peer pointer is really a pointer back to the parent. This saves
+	 * putting a parent back pointer in each and every named object!
+	 */
+	while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
+		node = node->peer;
+	}
+
+
+	return (node->peer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_next_valid_node
+ *
+ * PARAMETERS:  Node       - Current table entry
+ *
+ * RETURN:      Next valid Node in the linked node list. NULL if no more valid
+ *              nodes.
+ *
+ * DESCRIPTION: Find the next valid node within a name table.
+ *              Useful for implementing NULL-end-of-list loops.
+ *
+ ******************************************************************************/
+
+
+struct acpi_namespace_node *
+acpi_ns_get_next_valid_node (
+	struct acpi_namespace_node      *node)
+{
+
+	/* If we are at the end of this peer list, return NULL */
+
+	if (node->flags & ANOBJ_END_OF_PEER_LIST) {
+		return NULL;
+	}
+
+	/* Otherwise just return the next peer */
+
+	return (node->peer);
+}
+
+
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
new file mode 100644
index 0000000..4de2444
--- /dev/null
+++ b/drivers/acpi/namespace/nswalk.c
@@ -0,0 +1,289 @@
+/******************************************************************************
+ *
+ * Module Name: nswalk - Functions for walking the ACPI namespace
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nswalk")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_next_node
+ *
+ * PARAMETERS:  Type                - Type of node to be searched for
+ *              parent_node         - Parent node whose children we are
+ *                                     getting
+ *              child_node          - Previous child that was found.
+ *                                    The NEXT child will be returned
+ *
+ * RETURN:      struct acpi_namespace_node - Pointer to the NEXT child or NULL if
+ *                                    none is found.
+ *
+ * DESCRIPTION: Return the next peer node within the namespace.  If Handle
+ *              is valid, Scope is ignored.  Otherwise, the first node
+ *              within Scope is returned.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *
+acpi_ns_get_next_node (
+	acpi_object_type                type,
+	struct acpi_namespace_node      *parent_node,
+	struct acpi_namespace_node      *child_node)
+{
+	struct acpi_namespace_node      *next_node = NULL;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (!child_node) {
+		/* It's really the parent's _scope_ that we want */
+
+		if (parent_node->child) {
+			next_node = parent_node->child;
+		}
+	}
+
+	else {
+		/* Start search at the NEXT node */
+
+		next_node = acpi_ns_get_next_valid_node (child_node);
+	}
+
+	/* If any type is OK, we are done */
+
+	if (type == ACPI_TYPE_ANY) {
+		/* next_node is NULL if we are at the end-of-list */
+
+		return (next_node);
+	}
+
+	/* Must search for the node -- but within this scope only */
+
+	while (next_node) {
+		/* If type matches, we are done */
+
+		if (next_node->type == type) {
+			return (next_node);
+		}
+
+		/* Otherwise, move on to the next node */
+
+		next_node = acpi_ns_get_next_valid_node (next_node);
+	}
+
+	/* Not found */
+
+	return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_walk_namespace
+ *
+ * PARAMETERS:  Type                - acpi_object_type to search for
+ *              start_node          - Handle in namespace where search begins
+ *              max_depth           - Depth to which search is to reach
+ *              unlock_before_callback- Whether to unlock the NS before invoking
+ *                                    the callback routine
+ *              user_function       - Called when an object of "Type" is found
+ *              Context             - Passed to user function
+ *              return_value        - from the user_function if terminated early.
+ *                                    Otherwise, returns NULL.
+ * RETURNS:     Status
+ *
+ * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
+ *              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.
+ *
+ *              The point of this procedure is to provide a generic namespace
+ *              walk routine that can be called from multiple places to
+ *              provide multiple services;  the User Function can be tailored
+ *              to each task, whether it is a print function, a compare
+ *              function, etc.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_walk_namespace (
+	acpi_object_type                type,
+	acpi_handle                     start_node,
+	u32                             max_depth,
+	u8                              unlock_before_callback,
+	acpi_walk_callback              user_function,
+	void                            *context,
+	void                            **return_value)
+{
+	acpi_status                     status;
+	acpi_status                     mutex_status;
+	struct acpi_namespace_node      *child_node;
+	struct acpi_namespace_node      *parent_node;
+	acpi_object_type                child_type;
+	u32                             level;
+
+
+	ACPI_FUNCTION_TRACE ("ns_walk_namespace");
+
+
+	/* Special case for the namespace Root Node */
+
+	if (start_node == ACPI_ROOT_OBJECT) {
+		start_node = acpi_gbl_root_node;
+	}
+
+	/* Null child means "get first node" */
+
+	parent_node = start_node;
+	child_node  = NULL;
+	child_type  = ACPI_TYPE_ANY;
+	level       = 1;
+
+	/*
+	 * Traverse the tree of nodes until we bubble back up to where we
+	 * started. When Level is zero, the loop is done because we have
+	 * bubbled up to (and passed) the original parent handle (start_entry)
+	 */
+	while (level > 0) {
+		/* Get the next node in this scope.  Null if not found */
+
+		status = AE_OK;
+		child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node);
+		if (child_node) {
+			/*
+			 * Found node, Get the type if we are not
+			 * searching for ANY
+			 */
+			if (type != ACPI_TYPE_ANY) {
+				child_type = child_node->type;
+			}
+
+			if (child_type == type) {
+				/*
+				 * Found a matching node, invoke the user
+				 * callback function
+				 */
+				if (unlock_before_callback) {
+					mutex_status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+					if (ACPI_FAILURE (mutex_status)) {
+						return_ACPI_STATUS (mutex_status);
+					}
+				}
+
+				status = user_function (child_node, level,
+						 context, return_value);
+
+				if (unlock_before_callback) {
+					mutex_status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+					if (ACPI_FAILURE (mutex_status)) {
+						return_ACPI_STATUS (mutex_status);
+					}
+				}
+
+				switch (status) {
+				case AE_OK:
+				case AE_CTRL_DEPTH:
+
+					/* Just keep going */
+					break;
+
+				case AE_CTRL_TERMINATE:
+
+					/* Exit now, with OK status */
+
+					return_ACPI_STATUS (AE_OK);
+
+				default:
+
+					/* All others are valid exceptions */
+
+					return_ACPI_STATUS (status);
+				}
+			}
+
+			/*
+			 * Depth first search:
+			 * Attempt to go down another level in the namespace
+			 * if we are allowed to.  Don't go any further if we
+			 * have reached the caller specified maximum depth
+			 * or if the user function has specified that the
+			 * maximum depth has been reached.
+			 */
+			if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
+				if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) {
+					/*
+					 * There is at least one child of this
+					 * node, visit the onde
+					 */
+					level++;
+					parent_node = child_node;
+					child_node = NULL;
+				}
+			}
+		}
+		else {
+			/*
+			 * No more children of this node (acpi_ns_get_next_node
+			 * failed), go back upwards in the namespace tree to
+			 * the node's parent.
+			 */
+			level--;
+			child_node = parent_node;
+			parent_node = acpi_ns_get_parent_node (parent_node);
+		}
+	}
+
+	/* Complete walk, not terminated by user function */
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
new file mode 100644
index 0000000..1dc9955
--- /dev/null
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -0,0 +1,764 @@
+/*******************************************************************************
+ *
+ * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
+ *                         ACPI Object evaluation interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsxfeval")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_evaluate_object_typed
+ *
+ * PARAMETERS:  Handle              - Object handle (optional)
+ *              *Pathname           - Object pathname (optional)
+ *              **external_params   - List of parameters to pass to method,
+ *                                    terminated by NULL.  May be NULL
+ *                                    if no parameters are being passed.
+ *              *return_buffer      - Where to put method's return value (if
+ *                                    any).  If NULL, no value is returned.
+ *              return_type         - Expected type of return object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find and evaluate the given object, passing the given
+ *              parameters if necessary.  One of "Handle" or "Pathname" must
+ *              be valid (non-null)
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_evaluate_object_typed (
+	acpi_handle                     handle,
+	acpi_string                     pathname,
+	struct acpi_object_list         *external_params,
+	struct acpi_buffer              *return_buffer,
+	acpi_object_type                return_type)
+{
+	acpi_status                     status;
+	u8                              must_free = FALSE;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_evaluate_object_typed");
+
+
+	/* Return buffer must be valid */
+
+	if (!return_buffer) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
+		must_free = TRUE;
+	}
+
+	/* Evaluate the object */
+
+	status = acpi_evaluate_object (handle, pathname, external_params, return_buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Type ANY means "don't care" */
+
+	if (return_type == ACPI_TYPE_ANY) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	if (return_buffer->length == 0) {
+		/* Error because caller specifically asked for a return value */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"No return value\n"));
+
+		return_ACPI_STATUS (AE_NULL_OBJECT);
+	}
+
+	/* Examine the object type returned from evaluate_object */
+
+	if (((union acpi_object *) return_buffer->pointer)->type == return_type) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Return object type does not match requested type */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+		"Incorrect return type [%s] requested [%s]\n",
+		acpi_ut_get_type_name (((union acpi_object *) return_buffer->pointer)->type),
+		acpi_ut_get_type_name (return_type)));
+
+	if (must_free) {
+		/* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
+
+		acpi_os_free (return_buffer->pointer);
+		return_buffer->pointer = NULL;
+	}
+
+	return_buffer->length = 0;
+	return_ACPI_STATUS (AE_TYPE);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_evaluate_object
+ *
+ * PARAMETERS:  Handle              - Object handle (optional)
+ *              Pathname            - Object pathname (optional)
+ *              external_params     - List of parameters to pass to method,
+ *                                    terminated by NULL.  May be NULL
+ *                                    if no parameters are being passed.
+ *              return_buffer       - Where to put method's return value (if
+ *                                    any).  If NULL, no value is returned.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find and evaluate the given object, passing the given
+ *              parameters if necessary.  One of "Handle" or "Pathname" must
+ *              be valid (non-null)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_evaluate_object (
+	acpi_handle                     handle,
+	acpi_string                     pathname,
+	struct acpi_object_list         *external_params,
+	struct acpi_buffer              *return_buffer)
+{
+	acpi_status                     status;
+	acpi_status                     status2;
+	struct acpi_parameter_info      info;
+	acpi_size                       buffer_space_needed;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_evaluate_object");
+
+
+	info.node = handle;
+	info.parameters = NULL;
+	info.return_object = NULL;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
+	/*
+	 * If there are parameters to be passed to the object
+	 * (which must be a control method), the external objects
+	 * must be converted to internal objects
+	 */
+	if (external_params && external_params->count) {
+		/*
+		 * Allocate a new parameter block for the internal objects
+		 * Add 1 to count to allow for null terminated internal list
+		 */
+		info.parameters = ACPI_MEM_CALLOCATE (
+				 ((acpi_size) external_params->count + 1) *
+				 sizeof (void *));
+		if (!info.parameters) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/*
+		 * Convert each external object in the list to an
+		 * internal object
+		 */
+		for (i = 0; i < external_params->count; i++) {
+			status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
+					  &info.parameters[i]);
+			if (ACPI_FAILURE (status)) {
+				acpi_ut_delete_internal_object_list (info.parameters);
+				return_ACPI_STATUS (status);
+			}
+		}
+		info.parameters[external_params->count] = NULL;
+	}
+
+
+	/*
+	 * Three major cases:
+	 * 1) Fully qualified pathname
+	 * 2) No handle, not fully qualified pathname (error)
+	 * 3) Valid handle
+	 */
+	if ((pathname) &&
+		(acpi_ns_valid_root_prefix (pathname[0]))) {
+		/*
+		 *  The path is fully qualified, just evaluate by name
+		 */
+		status = acpi_ns_evaluate_by_name (pathname, &info);
+	}
+	else if (!handle) {
+		/*
+		 * A handle is optional iff a fully qualified pathname
+		 * is specified.  Since we've already handled fully
+		 * qualified names above, this is an error
+		 */
+		if (!pathname) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Both Handle and Pathname are NULL\n"));
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Handle is NULL and Pathname is relative\n"));
+		}
+
+		status = AE_BAD_PARAMETER;
+	}
+	else {
+		/*
+		 * We get here if we have a handle -- and if we have a
+		 * pathname it is relative.  The handle will be validated
+		 * in the lower procedures
+		 */
+		if (!pathname) {
+			/*
+			 * The null pathname case means the handle is for
+			 * the actual object to be evaluated
+			 */
+			status = acpi_ns_evaluate_by_handle (&info);
+		}
+		else {
+		   /*
+			* Both a Handle and a relative Pathname
+			*/
+			status = acpi_ns_evaluate_relative (pathname, &info);
+		}
+	}
+
+
+	/*
+	 * If we are expecting a return value, and all went well above,
+	 * copy the return value to an external object.
+	 */
+	if (return_buffer) {
+		if (!info.return_object) {
+			return_buffer->length = 0;
+		}
+		else {
+			if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) {
+				/*
+				 * If we received a NS Node as a return object, this means that
+				 * the object we are evaluating has nothing interesting to
+				 * return (such as a mutex, etc.)  We return an error because
+				 * these types are essentially unsupported by this interface.
+				 * We don't check up front because this makes it easier to add
+				 * support for various types at a later date if necessary.
+				 */
+				status = AE_TYPE;
+				info.return_object = NULL;  /* No need to delete a NS Node */
+				return_buffer->length = 0;
+			}
+
+			if (ACPI_SUCCESS (status)) {
+				/*
+				 * Find out how large a buffer is needed
+				 * to contain the returned object
+				 */
+				status = acpi_ut_get_object_size (info.return_object,
+						   &buffer_space_needed);
+				if (ACPI_SUCCESS (status)) {
+					/* Validate/Allocate/Clear caller buffer */
+
+					status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed);
+					if (ACPI_FAILURE (status)) {
+						/*
+						 * Caller's buffer is too small or a new one can't be allocated
+						 */
+						ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+							"Needed buffer size %X, %s\n",
+							(u32) buffer_space_needed,
+							acpi_format_exception (status)));
+					}
+					else {
+						/*
+						 *  We have enough space for the object, build it
+						 */
+						status = acpi_ut_copy_iobject_to_eobject (info.return_object,
+								  return_buffer);
+					}
+				}
+			}
+		}
+	}
+
+	if (info.return_object) {
+		/*
+		 * Delete the internal return object.  NOTE: Interpreter
+		 * must be locked to avoid race condition.
+		 */
+		status2 = acpi_ex_enter_interpreter ();
+		if (ACPI_SUCCESS (status2)) {
+			/*
+			 * Delete the internal return object. (Or at least
+			 * decrement the reference count by one)
+			 */
+			acpi_ut_remove_reference (info.return_object);
+			acpi_ex_exit_interpreter ();
+		}
+	}
+
+	/*
+	 * Free the input parameter list (if we created one),
+	 */
+	if (info.parameters) {
+		/* Free the allocated parameter block */
+
+		acpi_ut_delete_internal_object_list (info.parameters);
+	}
+
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_evaluate_object);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_walk_namespace
+ *
+ * PARAMETERS:  Type                - acpi_object_type to search for
+ *              start_object        - Handle in namespace where search begins
+ *              max_depth           - Depth to which search is to reach
+ *              user_function       - Called when an object of "Type" is found
+ *              Context             - Passed to user function
+ *              return_value        - Location where return value of
+ *                                    user_function is put if terminated early
+ *
+ * RETURNS      Return value from the user_function if terminated early.
+ *              Otherwise, returns NULL.
+ *
+ * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
+ *              starting (and ending) at the object specified by start_handle.
+ *              The user_function is called whenever an object 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.
+ *
+ *              The point of this procedure is to provide a generic namespace
+ *              walk routine that can be called from multiple places to
+ *              provide multiple services;  the User Function can be tailored
+ *              to each task, whether it is a print function, a compare
+ *              function, etc.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_walk_namespace (
+	acpi_object_type                type,
+	acpi_handle                     start_object,
+	u32                             max_depth,
+	acpi_walk_callback              user_function,
+	void                            *context,
+	void                            **return_value)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_walk_namespace");
+
+
+	/* Parameter validation */
+
+	if ((type > ACPI_TYPE_EXTERNAL_MAX) ||
+		(!max_depth)                    ||
+		(!user_function)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * 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.
+	 */
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ns_walk_namespace (type, start_object, max_depth, ACPI_NS_WALK_UNLOCK,
+			  user_function, context, return_value);
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_walk_namespace);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_device_callback
+ *
+ * PARAMETERS:  Callback from acpi_get_device
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non-
+ *              present devices, or if they specified a HID, it filters based
+ *              on that.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ns_get_device_callback (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value)
+{
+	struct acpi_get_devices_info    *info = context;
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	u32                             flags;
+	struct acpi_device_id           hid;
+	struct acpi_compatible_id_list *cid;
+	acpi_native_uint                i;
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	node = acpi_ns_map_handle_to_node (obj_handle);
+	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	if (!node) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Run _STA to determine if device is present */
+
+	status = acpi_ut_execute_STA (node, &flags);
+	if (ACPI_FAILURE (status)) {
+		return (AE_CTRL_DEPTH);
+	}
+
+	if (!(flags & 0x01)) {
+		/* Don't return at the device or children of the device if not there */
+
+		return (AE_CTRL_DEPTH);
+	}
+
+	/* Filter based on device HID & CID */
+
+	if (info->hid != NULL) {
+		status = acpi_ut_execute_HID (node, &hid);
+		if (status == AE_NOT_FOUND) {
+			return (AE_OK);
+		}
+		else if (ACPI_FAILURE (status)) {
+			return (AE_CTRL_DEPTH);
+		}
+
+		if (ACPI_STRNCMP (hid.value, info->hid, sizeof (hid.value)) != 0) {
+			/* Get the list of Compatible IDs */
+
+			status = acpi_ut_execute_CID (node, &cid);
+			if (status == AE_NOT_FOUND) {
+				return (AE_OK);
+			}
+			else if (ACPI_FAILURE (status)) {
+				return (AE_CTRL_DEPTH);
+			}
+
+			/* Walk the CID list */
+
+			for (i = 0; i < cid->count; i++) {
+				if (ACPI_STRNCMP (cid->id[i].value, info->hid,
+						 sizeof (struct acpi_compatible_id)) != 0) {
+					ACPI_MEM_FREE (cid);
+					return (AE_OK);
+				}
+			}
+			ACPI_MEM_FREE (cid);
+		}
+	}
+
+	status = info->user_function (obj_handle, nesting_level, info->context, return_value);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_devices
+ *
+ * PARAMETERS:  HID                 - HID to search for. Can be NULL.
+ *              user_function       - Called when a matching object is found
+ *              Context             - Passed to user function
+ *              return_value        - Location where return value of
+ *                                    user_function is put if terminated early
+ *
+ * RETURNS      Return value from the user_function if terminated early.
+ *              Otherwise, returns NULL.
+ *
+ * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
+ *              starting (and ending) at the object specified by start_handle.
+ *              The user_function is called whenever an object of type
+ *              Device is found.  If the user function returns
+ *              a non-zero value, the search is terminated immediately and this
+ *              value is returned to the caller.
+ *
+ *              This is a wrapper for walk_namespace, but the callback performs
+ *              additional filtering. Please see acpi_get_device_callback.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_devices (
+	char                            *HID,
+	acpi_walk_callback              user_function,
+	void                            *context,
+	void                            **return_value)
+{
+	acpi_status                     status;
+	struct acpi_get_devices_info    info;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_devices");
+
+
+	/* Parameter validation */
+
+	if (!user_function) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * We're going to call their callback from OUR callback, so we need
+	 * to know what it is, and their context parameter.
+	 */
+	info.context      = context;
+	info.user_function = user_function;
+	info.hid          = HID;
+
+	/*
+	 * 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.
+	 */
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE,
+			   ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+			   ACPI_NS_WALK_UNLOCK,
+			   acpi_ns_get_device_callback, &info,
+			   return_value);
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_get_devices);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_attach_data
+ *
+ * PARAMETERS:  obj_handle          - Namespace node
+ *              Handler             - Handler for this attachment
+ *              Data                - Pointer to data to be attached
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_attach_data (
+	acpi_handle                     obj_handle,
+	acpi_object_handler             handler,
+	void                            *data)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	/* Parameter validation */
+
+	if (!obj_handle ||
+		!handler    ||
+		!data) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Convert and validate the handle */
+
+	node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	status = acpi_ns_attach_data (node, handler, data);
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_detach_data
+ *
+ * PARAMETERS:  obj_handle          - Namespace node handle
+ *              Handler             - Handler used in call to acpi_attach_data
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove data that was previously attached to a node.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_detach_data (
+	acpi_handle                     obj_handle,
+	acpi_object_handler             handler)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	/* Parameter validation */
+
+	if (!obj_handle ||
+		!handler) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Convert and validate the handle */
+
+	node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	status = acpi_ns_detach_data (node, handler);
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_data
+ *
+ * PARAMETERS:  obj_handle          - Namespace node
+ *              Handler             - Handler used in call to attach_data
+ *              Data                - Where the data is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_data (
+	acpi_handle                     obj_handle,
+	acpi_object_handler             handler,
+	void                            **data)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	/* Parameter validation */
+
+	if (!obj_handle ||
+		!handler    ||
+		!data) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Convert and validate the handle */
+
+	node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	status = acpi_ns_get_attached_data (node, handler, data);
+
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return (status);
+}
+
+
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
new file mode 100644
index 0000000..f2405ef
--- /dev/null
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -0,0 +1,369 @@
+/******************************************************************************
+ *
+ * Module Name: nsxfname - Public interfaces to the ACPI subsystem
+ *                         ACPI Namespace oriented interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsxfname")
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_handle
+ *
+ * PARAMETERS:  Parent          - Object to search under (search scope).
+ *              path_name       - Pointer to an asciiz string containing the
+ *                                  name
+ *              ret_handle      - Where the return handle is placed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This routine will search for a caller specified name in the
+ *              name space.  The caller can restrict the search region by
+ *              specifying a non NULL parent.  The parent value is itself a
+ *              namespace handle.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_handle (
+	acpi_handle                     parent,
+	acpi_string                     pathname,
+	acpi_handle                     *ret_handle)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node = NULL;
+	struct acpi_namespace_node      *prefix_node = NULL;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Parameter Validation */
+
+	if (!ret_handle || !pathname) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Convert a parent handle to a prefix node */
+
+	if (parent) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		prefix_node = acpi_ns_map_handle_to_node (parent);
+		if (!prefix_node) {
+			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+			return (AE_BAD_PARAMETER);
+		}
+
+		status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	/* Special case for root, since we can't search for it */
+
+	if (ACPI_STRCMP (pathname, ACPI_NS_ROOT_PATH) == 0) {
+		*ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node);
+		return (AE_OK);
+	}
+
+	/*
+	 *  Find the Node and convert to a handle
+	 */
+	status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
+			  &node);
+
+	*ret_handle = NULL;
+	if (ACPI_SUCCESS (status)) {
+		*ret_handle = acpi_ns_convert_entry_to_handle (node);
+	}
+
+	return (status);
+}
+EXPORT_SYMBOL(acpi_get_handle);
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_name
+ *
+ * PARAMETERS:  Handle          - Handle to be converted to a pathname
+ *              name_type       - Full pathname or single segment
+ *              Buffer          - Buffer for returned path
+ *
+ * RETURN:      Pointer to a string containing the fully qualified Name.
+ *
+ * DESCRIPTION: This routine returns the fully qualified name associated with
+ *              the Handle parameter.  This and the acpi_pathname_to_handle are
+ *              complementary functions.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_name (
+	acpi_handle                     handle,
+	u32                             name_type,
+	struct acpi_buffer              *buffer)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+
+
+	/* Parameter validation */
+
+	if (name_type > ACPI_NAME_TYPE_MAX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_validate_buffer (buffer);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	if (name_type == ACPI_FULL_PATHNAME) {
+		/* Get the full pathname (From the namespace root) */
+
+		status = acpi_ns_handle_to_pathname (handle, buffer);
+		return (status);
+	}
+
+	/*
+	 * Wants the single segment ACPI name.
+	 * Validate handle and convert to a namespace Node
+	 */
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	node = acpi_ns_map_handle_to_node (handle);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (buffer, ACPI_PATH_SEGMENT_LENGTH);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
+	/* Just copy the ACPI name from the Node and zero terminate it */
+
+	ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node),
+			 ACPI_NAME_SIZE);
+	((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0;
+	status = AE_OK;
+
+
+unlock_and_exit:
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return (status);
+}
+EXPORT_SYMBOL(acpi_get_name);
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_object_info
+ *
+ * PARAMETERS:  Handle          - Object Handle
+ *              Info            - Where the info is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Returns information about an object as gleaned from the
+ *              namespace node and possibly by running several standard
+ *              control methods (Such as in the case of a device.)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_object_info (
+	acpi_handle                     handle,
+	struct acpi_buffer              *buffer)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	struct acpi_device_info         *info;
+	struct acpi_device_info         *return_info;
+	struct acpi_compatible_id_list *cid_list = NULL;
+	acpi_size                       size;
+
+
+	/* Parameter validation */
+
+	if (!handle || !buffer) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_validate_buffer (buffer);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_device_info));
+	if (!info) {
+		return (AE_NO_MEMORY);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	node = acpi_ns_map_handle_to_node (handle);
+	if (!node) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		goto cleanup;
+	}
+
+	/* Init return structure */
+
+	size = sizeof (struct acpi_device_info);
+
+	info->type  = node->type;
+	info->name  = node->name.integer;
+	info->valid = 0;
+
+	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* If not a device, we are all done */
+
+	if (info->type == ACPI_TYPE_DEVICE) {
+		/*
+		 * Get extra info for ACPI Devices objects only:
+		 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
+		 *
+		 * Note: none of these methods are required, so they may or may
+		 * not be present for this device.  The Info->Valid bitfield is used
+		 * to indicate which methods were found and ran successfully.
+		 */
+
+		/* Execute the Device._HID method */
+
+		status = acpi_ut_execute_HID (node, &info->hardware_id);
+		if (ACPI_SUCCESS (status)) {
+			info->valid |= ACPI_VALID_HID;
+		}
+
+		/* Execute the Device._UID method */
+
+		status = acpi_ut_execute_UID (node, &info->unique_id);
+		if (ACPI_SUCCESS (status)) {
+			info->valid |= ACPI_VALID_UID;
+		}
+
+		/* Execute the Device._CID method */
+
+		status = acpi_ut_execute_CID (node, &cid_list);
+		if (ACPI_SUCCESS (status)) {
+			size += ((acpi_size) cid_list->count - 1) *
+					 sizeof (struct acpi_compatible_id);
+			info->valid |= ACPI_VALID_CID;
+		}
+
+		/* Execute the Device._STA method */
+
+		status = acpi_ut_execute_STA (node, &info->current_status);
+		if (ACPI_SUCCESS (status)) {
+			info->valid |= ACPI_VALID_STA;
+		}
+
+		/* Execute the Device._ADR method */
+
+		status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
+				  &info->address);
+		if (ACPI_SUCCESS (status)) {
+			info->valid |= ACPI_VALID_ADR;
+		}
+
+		/* Execute the Device._sx_d methods */
+
+		status = acpi_ut_execute_sxds (node, info->highest_dstates);
+		if (ACPI_SUCCESS (status)) {
+			info->valid |= ACPI_VALID_SXDS;
+		}
+	}
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (buffer, size);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Populate the return buffer */
+
+	return_info = buffer->pointer;
+	ACPI_MEMCPY (return_info, info, sizeof (struct acpi_device_info));
+
+	if (cid_list) {
+		ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
+	}
+
+
+cleanup:
+	ACPI_MEM_FREE (info);
+	if (cid_list) {
+		ACPI_MEM_FREE (cid_list);
+	}
+	return (status);
+}
+EXPORT_SYMBOL(acpi_get_object_info);
+
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
new file mode 100644
index 0000000..19acf32
--- /dev/null
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ *
+ * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
+ *                         ACPI Object oriented interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsxfobj")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_type
+ *
+ * PARAMETERS:  Handle          - Handle of object whose type is desired
+ *              *ret_type       - Where the type will be placed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This routine returns the type associatd with a particular handle
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_type (
+	acpi_handle                     handle,
+	acpi_object_type                *ret_type)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	/* Parameter Validation */
+
+	if (!ret_type) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Special case for the predefined Root Node
+	 * (return type ANY)
+	 */
+	if (handle == ACPI_ROOT_OBJECT) {
+		*ret_type = ACPI_TYPE_ANY;
+		return (AE_OK);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Convert and validate the handle */
+
+	node = acpi_ns_map_handle_to_node (handle);
+	if (!node) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+		return (AE_BAD_PARAMETER);
+	}
+
+	*ret_type = node->type;
+
+
+	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return (status);
+}
+EXPORT_SYMBOL(acpi_get_type);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_parent
+ *
+ * PARAMETERS:  Handle          - Handle of object whose parent is desired
+ *              ret_handle      - Where the parent handle will be placed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Returns a handle to the parent of the object represented by
+ *              Handle.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_parent (
+	acpi_handle                     handle,
+	acpi_handle                     *ret_handle)
+{
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	if (!ret_handle) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Special case for the predefined Root Node (no parent) */
+
+	if (handle == ACPI_ROOT_OBJECT) {
+		return (AE_NULL_ENTRY);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Convert and validate the handle */
+
+	node = acpi_ns_map_handle_to_node (handle);
+	if (!node) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	/* Get the parent entry */
+
+	*ret_handle =
+		acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_node (node));
+
+	/* Return exception if parent is null */
+
+	if (!acpi_ns_get_parent_node (node)) {
+		status = AE_NULL_ENTRY;
+	}
+
+
+unlock_and_exit:
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return (status);
+}
+EXPORT_SYMBOL(acpi_get_parent);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_next_object
+ *
+ * PARAMETERS:  Type            - Type of object to be searched for
+ *              Parent          - Parent object whose children we are getting
+ *              last_child      - Previous child that was found.
+ *                                The NEXT child will be returned
+ *              ret_handle      - Where handle to the next object is placed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return the next peer object within the namespace.  If Handle is
+ *              valid, Scope is ignored.  Otherwise, the first object within
+ *              Scope is returned.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_next_object (
+	acpi_object_type                type,
+	acpi_handle                     parent,
+	acpi_handle                     child,
+	acpi_handle                     *ret_handle)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	struct acpi_namespace_node      *parent_node = NULL;
+	struct acpi_namespace_node      *child_node = NULL;
+
+
+	/* Parameter validation */
+
+	if (type > ACPI_TYPE_EXTERNAL_MAX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* If null handle, use the parent */
+
+	if (!child) {
+		/* Start search at the beginning of the specified scope */
+
+		parent_node = acpi_ns_map_handle_to_node (parent);
+		if (!parent_node) {
+			status = AE_BAD_PARAMETER;
+			goto unlock_and_exit;
+		}
+	}
+	else {
+		/* Non-null handle, ignore the parent */
+		/* Convert and validate the handle */
+
+		child_node = acpi_ns_map_handle_to_node (child);
+		if (!child_node) {
+			status = AE_BAD_PARAMETER;
+			goto unlock_and_exit;
+		}
+	}
+
+	/* Internal function does the real work */
+
+	node = acpi_ns_get_next_node (type, parent_node, child_node);
+	if (!node) {
+		status = AE_NOT_FOUND;
+		goto unlock_and_exit;
+	}
+
+	if (ret_handle) {
+		*ret_handle = acpi_ns_convert_entry_to_handle (node);
+	}
+
+
+unlock_and_exit:
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return (status);
+}
+EXPORT_SYMBOL(acpi_get_next_object);
+
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
new file mode 100644
index 0000000..a82834b
--- /dev/null
+++ b/drivers/acpi/numa.c
@@ -0,0 +1,213 @@
+/*
+ *  acpi_numa.c - ACPI NUMA support
+ *
+ *  Copyright (C) 2002 Takayoshi Kochi <t-kochi@bq.jp.nec.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acmacros.h>
+
+#define ACPI_NUMA	0x80000000
+#define _COMPONENT	ACPI_NUMA
+	ACPI_MODULE_NAME ("numa")
+
+extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries);
+
+void __init
+acpi_table_print_srat_entry (
+	acpi_table_entry_header	*header)
+{
+
+	ACPI_FUNCTION_NAME ("acpi_table_print_srat_entry");
+
+	if (!header)
+		return;
+
+	switch (header->type) {
+
+	case ACPI_SRAT_PROCESSOR_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+	{
+		struct acpi_table_processor_affinity *p =
+			(struct acpi_table_processor_affinity*) header;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
+		       p->apic_id, p->lsapic_eid, p->proximity_domain,
+		       p->flags.enabled?"enabled":"disabled"));
+	}
+#endif /* ACPI_DEBUG_OUTPUT */
+		break;
+
+	case ACPI_SRAT_MEMORY_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+	{
+		struct acpi_table_memory_affinity *p =
+			(struct acpi_table_memory_affinity*) header;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
+		       p->base_addr_hi, p->base_addr_lo, p->length_hi, p->length_lo,
+		       p->memory_type, p->proximity_domain,
+		       p->flags.enabled ? "enabled" : "disabled",
+		       p->flags.hot_pluggable ? " hot-pluggable" : ""));
+	}
+#endif /* ACPI_DEBUG_OUTPUT */
+		break;
+
+	default:
+		printk(KERN_WARNING PREFIX "Found unsupported SRAT entry (type = 0x%x)\n",
+			header->type);
+		break;
+	}
+}
+
+
+static int __init
+acpi_parse_slit (unsigned long phys_addr, unsigned long size)
+{
+	struct acpi_table_slit	*slit;
+	u32			localities;
+
+	if (!phys_addr || !size)
+		return -EINVAL;
+
+	slit = (struct acpi_table_slit *) __va(phys_addr);
+
+	/* downcast just for %llu vs %lu for i386/ia64  */
+	localities = (u32) slit->localities;
+
+	acpi_numa_slit_init(slit);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_processor_affinity (
+	acpi_table_entry_header *header,
+	const unsigned long end)
+{
+	struct acpi_table_processor_affinity *processor_affinity;
+
+	processor_affinity = (struct acpi_table_processor_affinity*) header;
+	if (!processor_affinity)
+		return -EINVAL;
+
+	acpi_table_print_srat_entry(header);
+
+	/* let architecture-dependent part to do it */
+	acpi_numa_processor_affinity_init(processor_affinity);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_memory_affinity (
+	acpi_table_entry_header *header,
+	const unsigned long end)
+{
+	struct acpi_table_memory_affinity *memory_affinity;
+
+	memory_affinity = (struct acpi_table_memory_affinity*) header;
+	if (!memory_affinity)
+		return -EINVAL;
+
+	acpi_table_print_srat_entry(header);
+
+	/* let architecture-dependent part to do it */
+	acpi_numa_memory_affinity_init(memory_affinity);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_srat (unsigned long phys_addr, unsigned long size)
+{
+	struct acpi_table_srat	*srat;
+
+	if (!phys_addr || !size)
+		return -EINVAL;
+
+	srat = (struct acpi_table_srat *) __va(phys_addr);
+
+	return 0;
+}
+
+
+int __init
+acpi_table_parse_srat (
+	enum acpi_srat_entry_id	id,
+	acpi_madt_entry_handler	handler,
+	unsigned int max_entries)
+{
+	return acpi_table_parse_madt_family(ACPI_SRAT, sizeof(struct acpi_table_srat),
+					    id, handler, max_entries);
+}
+
+
+int __init
+acpi_numa_init(void)
+{
+	int			result;
+
+	/* SRAT: Static Resource Affinity Table */
+	result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat);
+
+	if (result > 0) {
+		result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY,
+					       acpi_parse_processor_affinity,
+					       NR_CPUS);
+		result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY,
+					       acpi_parse_memory_affinity,
+					       NR_NODE_MEMBLKS);	// IA64 specific
+	}
+
+	/* SLIT: System Locality Information Table */
+	result = acpi_table_parse(ACPI_SLIT, acpi_parse_slit);
+
+	acpi_numa_arch_fixup();
+	return 0;
+}
+
+int
+acpi_get_pxm(acpi_handle h)
+{
+	unsigned long pxm;
+	acpi_status status;
+	acpi_handle handle;
+	acpi_handle phandle = h;
+
+	do {
+		handle = phandle;
+		status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
+		if (ACPI_SUCCESS(status))
+			return (int)pxm;
+		status = acpi_get_parent(handle, &phandle);
+	} while(ACPI_SUCCESS(status));
+	return -1;
+}
+EXPORT_SYMBOL(acpi_get_pxm);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
new file mode 100644
index 0000000..5a9128d
--- /dev/null
+++ b/drivers/acpi/osl.c
@@ -0,0 +1,1162 @@
+/*
+ *  acpi_osl.c - OS-dependent functions ($Revision: 83 $)
+ *
+ *  Copyright (C) 2000       Andrew Henroid
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kmod.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/nmi.h>
+#include <acpi/acpi.h>
+#include <asm/io.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+#include <asm/uaccess.h>
+
+#include <linux/efi.h>
+
+
+#define _COMPONENT		ACPI_OS_SERVICES
+ACPI_MODULE_NAME	("osl")
+
+#define PREFIX		"ACPI: "
+
+struct acpi_os_dpc
+{
+    acpi_osd_exec_callback  function;
+    void		    *context;
+};
+
+#ifdef CONFIG_ACPI_CUSTOM_DSDT
+#include CONFIG_ACPI_CUSTOM_DSDT_FILE
+#endif
+
+#ifdef ENABLE_DEBUGGER
+#include <linux/kdb.h>
+
+/* stuff for debugger support */
+int acpi_in_debugger;
+EXPORT_SYMBOL(acpi_in_debugger);
+
+extern char line_buf[80];
+#endif /*ENABLE_DEBUGGER*/
+
+static unsigned int acpi_irq_irq;
+static acpi_osd_handler acpi_irq_handler;
+static void *acpi_irq_context;
+static struct workqueue_struct *kacpid_wq;
+
+acpi_status
+acpi_os_initialize(void)
+{
+	return AE_OK;
+}
+
+acpi_status
+acpi_os_initialize1(void)
+{
+	/*
+	 * Initialize PCI configuration space access, as we'll need to access
+	 * it while walking the namespace (bus 0 and root bridges w/ _BBNs).
+	 */
+#ifdef CONFIG_ACPI_PCI
+	if (!raw_pci_ops) {
+		printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n");
+		return AE_NULL_ENTRY;
+	}
+#endif
+	kacpid_wq = create_singlethread_workqueue("kacpid");
+	BUG_ON(!kacpid_wq);
+
+	return AE_OK;
+}
+
+acpi_status
+acpi_os_terminate(void)
+{
+	if (acpi_irq_handler) {
+		acpi_os_remove_interrupt_handler(acpi_irq_irq,
+						 acpi_irq_handler);
+	}
+
+	destroy_workqueue(kacpid_wq);
+
+	return AE_OK;
+}
+
+void
+acpi_os_printf(const char *fmt,...)
+{
+	va_list args;
+	va_start(args, fmt);
+	acpi_os_vprintf(fmt, args);
+	va_end(args);
+}
+EXPORT_SYMBOL(acpi_os_printf);
+
+void
+acpi_os_vprintf(const char *fmt, va_list args)
+{
+	static char buffer[512];
+	
+	vsprintf(buffer, fmt, args);
+
+#ifdef ENABLE_DEBUGGER
+	if (acpi_in_debugger) {
+		kdb_printf("%s", buffer);
+	} else {
+		printk("%s", buffer);
+	}
+#else
+	printk("%s", buffer);
+#endif
+}
+
+void *
+acpi_os_allocate(acpi_size size)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+void
+acpi_os_free(void *ptr)
+{
+	kfree(ptr);
+}
+EXPORT_SYMBOL(acpi_os_free);
+
+acpi_status
+acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
+{
+	if (efi_enabled) {
+		addr->pointer_type = ACPI_PHYSICAL_POINTER;
+		if (efi.acpi20)
+			addr->pointer.physical =
+				(acpi_physical_address) virt_to_phys(efi.acpi20);
+		else if (efi.acpi)
+			addr->pointer.physical =
+				(acpi_physical_address) virt_to_phys(efi.acpi);
+		else {
+			printk(KERN_ERR PREFIX "System description tables not found\n");
+			return AE_NOT_FOUND;
+		}
+	} else {
+		if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) {
+			printk(KERN_ERR PREFIX "System description tables not found\n");
+			return AE_NOT_FOUND;
+		}
+	}
+
+	return AE_OK;
+}
+
+acpi_status
+acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void __iomem **virt)
+{
+	if (efi_enabled) {
+		if (EFI_MEMORY_WB & efi_mem_attributes(phys)) {
+			*virt = (void __iomem *) phys_to_virt(phys);
+		} else {
+			*virt = ioremap(phys, size);
+		}
+	} else {
+		if (phys > ULONG_MAX) {
+			printk(KERN_ERR PREFIX "Cannot map memory that high\n");
+			return AE_BAD_PARAMETER;
+		}
+		/*
+	 	 * ioremap checks to ensure this is in reserved space
+	 	 */
+		*virt = ioremap((unsigned long) phys, size);
+	}
+
+	if (!*virt)
+		return AE_NO_MEMORY;
+
+	return AE_OK;
+}
+
+void
+acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+{
+	iounmap(virt);
+}
+
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_os_get_physical_address(void *virt, acpi_physical_address *phys)
+{
+	if(!phys || !virt)
+		return AE_BAD_PARAMETER;
+
+	*phys = virt_to_phys(virt);
+
+	return AE_OK;
+}
+#endif
+
+#define ACPI_MAX_OVERRIDE_LEN 100
+
+static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
+
+acpi_status
+acpi_os_predefined_override (const struct acpi_predefined_names *init_val,
+		             acpi_string *new_val)
+{
+	if (!init_val || !new_val)
+		return AE_BAD_PARAMETER;
+
+	*new_val = NULL;
+	if (!memcmp (init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
+		printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
+			acpi_os_name);
+		*new_val = acpi_os_name;
+	}
+
+	return AE_OK;
+}
+
+acpi_status
+acpi_os_table_override (struct acpi_table_header *existing_table,
+			struct acpi_table_header **new_table)
+{
+	if (!existing_table || !new_table)
+		return AE_BAD_PARAMETER;
+
+#ifdef CONFIG_ACPI_CUSTOM_DSDT
+	if (strncmp(existing_table->signature, "DSDT", 4) == 0)
+		*new_table = (struct acpi_table_header*)AmlCode;
+	else
+		*new_table = NULL;
+#else
+	*new_table = NULL;
+#endif
+	return AE_OK;
+}
+
+static irqreturn_t
+acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	return (*acpi_irq_handler)(acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
+}
+
+acpi_status
+acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, void *context)
+{
+	unsigned int irq;
+
+	/*
+	 * Ignore the GSI from the core, and use the value in our copy of the
+	 * FADT. It may not be the same if an interrupt source override exists
+	 * for the SCI.
+	 */
+	gsi = acpi_fadt.sci_int;
+	if (acpi_gsi_to_irq(gsi, &irq) < 0) {
+		printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
+		       gsi);
+		return AE_OK;
+	}
+
+	acpi_irq_handler = handler;
+	acpi_irq_context = context;
+	if (request_irq(irq, acpi_irq, SA_SHIRQ, "acpi", acpi_irq)) {
+		printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
+		return AE_NOT_ACQUIRED;
+	}
+	acpi_irq_irq = irq;
+
+	return AE_OK;
+}
+
+acpi_status
+acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
+{
+	if (irq) {
+		free_irq(irq, acpi_irq);
+		acpi_irq_handler = NULL;
+		acpi_irq_irq = 0;
+	}
+
+	return AE_OK;
+}
+
+/*
+ * Running in interpreter thread context, safe to sleep
+ */
+
+void
+acpi_os_sleep(acpi_integer ms)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(((signed long) ms * HZ) / 1000);
+}
+EXPORT_SYMBOL(acpi_os_sleep);
+
+void
+acpi_os_stall(u32 us)
+{
+	while (us) {
+		u32 delay = 1000;
+
+		if (delay > us)
+			delay = us;
+		udelay(delay);
+		touch_nmi_watchdog();
+		us -= delay;
+	}
+}
+EXPORT_SYMBOL(acpi_os_stall);
+
+/*
+ * Support ACPI 3.0 AML Timer operand
+ * Returns 64-bit free-running, monotonically increasing timer
+ * with 100ns granularity
+ */
+u64
+acpi_os_get_timer (void)
+{
+	static u64 t;
+
+#ifdef	CONFIG_HPET
+	/* TBD: use HPET if available */
+#endif
+
+#ifdef	CONFIG_X86_PM_TIMER
+	/* TBD: default to PM timer if HPET was not available */
+#endif
+	if (!t)
+		printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
+
+	return ++t;
+}
+
+acpi_status
+acpi_os_read_port(
+	acpi_io_address	port,
+	u32		*value,
+	u32		width)
+{
+	u32 dummy;
+
+	if (!value)
+		value = &dummy;
+
+	switch (width)
+	{
+	case 8:
+		*(u8*)  value = inb(port);
+		break;
+	case 16:
+		*(u16*) value = inw(port);
+		break;
+	case 32:
+		*(u32*) value = inl(port);
+		break;
+	default:
+		BUG();
+	}
+
+	return AE_OK;
+}
+EXPORT_SYMBOL(acpi_os_read_port);
+
+acpi_status
+acpi_os_write_port(
+	acpi_io_address	port,
+	u32		value,
+	u32		width)
+{
+	switch (width)
+	{
+	case 8:
+		outb(value, port);
+		break;
+	case 16:
+		outw(value, port);
+		break;
+	case 32:
+		outl(value, port);
+		break;
+	default:
+		BUG();
+	}
+
+	return AE_OK;
+}
+EXPORT_SYMBOL(acpi_os_write_port);
+
+acpi_status
+acpi_os_read_memory(
+	acpi_physical_address	phys_addr,
+	u32			*value,
+	u32			width)
+{
+	u32			dummy;
+	void __iomem		*virt_addr;
+	int			iomem = 0;
+
+	if (efi_enabled) {
+		if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
+			/* HACK ALERT! We can use readb/w/l on real memory too.. */
+			virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+		} else {
+			iomem = 1;
+			virt_addr = ioremap(phys_addr, width);
+		}
+	} else
+		virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+	if (!value)
+		value = &dummy;
+
+	switch (width) {
+	case 8:
+		*(u8*) value = readb(virt_addr);
+		break;
+	case 16:
+		*(u16*) value = readw(virt_addr);
+		break;
+	case 32:
+		*(u32*) value = readl(virt_addr);
+		break;
+	default:
+		BUG();
+	}
+
+	if (efi_enabled) {
+		if (iomem)
+			iounmap(virt_addr);
+	}
+
+	return AE_OK;
+}
+
+acpi_status
+acpi_os_write_memory(
+	acpi_physical_address	phys_addr,
+	u32			value,
+	u32			width)
+{
+	void __iomem		*virt_addr;
+	int			iomem = 0;
+
+	if (efi_enabled) {
+		if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
+			/* HACK ALERT! We can use writeb/w/l on real memory too */
+			virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+		} else {
+			iomem = 1;
+			virt_addr = ioremap(phys_addr, width);
+		}
+	} else
+		virt_addr = (void __iomem *) phys_to_virt(phys_addr);
+
+	switch (width) {
+	case 8:
+		writeb(value, virt_addr);
+		break;
+	case 16:
+		writew(value, virt_addr);
+		break;
+	case 32:
+		writel(value, virt_addr);
+		break;
+	default:
+		BUG();
+	}
+
+	if (iomem)
+		iounmap(virt_addr);
+
+	return AE_OK;
+}
+
+#ifdef CONFIG_ACPI_PCI
+
+acpi_status
+acpi_os_read_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, void *value, u32 width)
+{
+	int result, size;
+
+	if (!value)
+		return AE_BAD_PARAMETER;
+
+	switch (width) {
+	case 8:
+		size = 1;
+		break;
+	case 16:
+		size = 2;
+		break;
+	case 32:
+		size = 4;
+		break;
+	default:
+		return AE_ERROR;
+	}
+
+	BUG_ON(!raw_pci_ops);
+
+	result = raw_pci_ops->read(pci_id->segment, pci_id->bus,
+				PCI_DEVFN(pci_id->device, pci_id->function),
+				reg, size, value);
+
+	return (result ? AE_ERROR : AE_OK);
+}
+EXPORT_SYMBOL(acpi_os_read_pci_configuration);
+
+acpi_status
+acpi_os_write_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, acpi_integer value, u32 width)
+{
+	int result, size;
+
+	switch (width) {
+	case 8:
+		size = 1;
+		break;
+	case 16:
+		size = 2;
+		break;
+	case 32:
+		size = 4;
+		break;
+	default:
+		return AE_ERROR;
+	}
+
+	BUG_ON(!raw_pci_ops);
+
+	result = raw_pci_ops->write(pci_id->segment, pci_id->bus,
+				PCI_DEVFN(pci_id->device, pci_id->function),
+				reg, size, value);
+
+	return (result ? AE_ERROR : AE_OK);
+}
+
+/* TODO: Change code to take advantage of driver model more */
+static void
+acpi_os_derive_pci_id_2 (
+	acpi_handle		rhandle,        /* upper bound  */
+	acpi_handle		chandle,        /* current node */
+	struct acpi_pci_id	**id,
+	int			*is_bridge,
+	u8			*bus_number)
+{
+	acpi_handle		handle;
+	struct acpi_pci_id	*pci_id = *id;
+	acpi_status		status;
+	unsigned long		temp;
+	acpi_object_type	type;
+	u8			tu8;
+
+	acpi_get_parent(chandle, &handle);
+	if (handle != rhandle) {
+		acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, bus_number);
+
+		status = acpi_get_type(handle, &type);
+		if ( (ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE) )
+			return;
+
+		status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &temp);
+		if (ACPI_SUCCESS(status)) {
+			pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (temp));
+			pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));
+
+			if (*is_bridge)
+				pci_id->bus = *bus_number;
+
+			/* any nicer way to get bus number of bridge ? */
+			status = acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, 8);
+			if (ACPI_SUCCESS(status) &&
+			    ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
+				status = acpi_os_read_pci_configuration(pci_id, 0x18, &tu8, 8);
+				if (!ACPI_SUCCESS(status)) {
+					/* Certainly broken...  FIX ME */
+					return;
+				}
+				*is_bridge = 1;
+				pci_id->bus = tu8;
+				status = acpi_os_read_pci_configuration(pci_id, 0x19, &tu8, 8);
+				if (ACPI_SUCCESS(status)) {
+					*bus_number = tu8;
+				}
+			} else
+				*is_bridge = 0;
+		}
+	}
+}
+
+void
+acpi_os_derive_pci_id (
+	acpi_handle		rhandle,        /* upper bound  */
+	acpi_handle		chandle,        /* current node */
+	struct acpi_pci_id	**id)
+{
+	int is_bridge = 1;
+	u8 bus_number = (*id)->bus;
+
+	acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
+}
+
+#else /*!CONFIG_ACPI_PCI*/
+
+acpi_status
+acpi_os_write_pci_configuration (
+	struct acpi_pci_id	*pci_id,
+	u32			reg,
+	acpi_integer		value,
+	u32			width)
+{
+	return AE_SUPPORT;
+}
+
+acpi_status
+acpi_os_read_pci_configuration (
+	struct acpi_pci_id	*pci_id,
+	u32			reg,
+	void			*value,
+	u32			width)
+{
+	return AE_SUPPORT;
+}
+
+void
+acpi_os_derive_pci_id (
+	acpi_handle		rhandle,        /* upper bound  */
+	acpi_handle		chandle,        /* current node */
+	struct acpi_pci_id	**id)
+{
+}
+
+#endif /*CONFIG_ACPI_PCI*/
+
+static void
+acpi_os_execute_deferred (
+	void *context)
+{
+	struct acpi_os_dpc	*dpc = NULL;
+
+	ACPI_FUNCTION_TRACE ("os_execute_deferred");
+
+	dpc = (struct acpi_os_dpc *) context;
+	if (!dpc) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
+		return_VOID;
+	}
+
+	dpc->function(dpc->context);
+
+	kfree(dpc);
+
+	return_VOID;
+}
+
+acpi_status
+acpi_os_queue_for_execution(
+	u32			priority,
+	acpi_osd_exec_callback	function,
+	void			*context)
+{
+	acpi_status 		status = AE_OK;
+	struct acpi_os_dpc	*dpc;
+	struct work_struct	*task;
+
+	ACPI_FUNCTION_TRACE ("os_queue_for_execution");
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", function, context));
+
+	if (!function)
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+
+	/*
+	 * Allocate/initialize DPC structure.  Note that this memory will be
+	 * freed by the callee.  The kernel handles the tq_struct list  in a
+	 * way that allows us to also free its memory inside the callee.
+	 * Because we may want to schedule several tasks with different
+	 * parameters we can't use the approach some kernel code uses of
+	 * having a static tq_struct.
+	 * We can save time and code by allocating the DPC and tq_structs
+	 * from the same memory.
+	 */
+
+	dpc = kmalloc(sizeof(struct acpi_os_dpc)+sizeof(struct work_struct), GFP_ATOMIC);
+	if (!dpc)
+		return_ACPI_STATUS (AE_NO_MEMORY);
+
+	dpc->function = function;
+	dpc->context = context;
+
+	task = (void *)(dpc+1);
+	INIT_WORK(task, acpi_os_execute_deferred, (void*)dpc);
+
+	if (!queue_work(kacpid_wq, task)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to queue_work() failed.\n"));
+		kfree(dpc);
+		status = AE_ERROR;
+	}
+
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_os_queue_for_execution);
+
+void
+acpi_os_wait_events_complete(
+	void *context)
+{
+	flush_workqueue(kacpid_wq);
+}
+EXPORT_SYMBOL(acpi_os_wait_events_complete);
+
+/*
+ * Allocate the memory for a spinlock and initialize it.
+ */
+acpi_status
+acpi_os_create_lock (
+	acpi_handle	*out_handle)
+{
+	spinlock_t *lock_ptr;
+
+	ACPI_FUNCTION_TRACE ("os_create_lock");
+
+	lock_ptr = acpi_os_allocate(sizeof(spinlock_t));
+
+	spin_lock_init(lock_ptr);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating spinlock[%p].\n", lock_ptr));
+
+	*out_handle = lock_ptr;
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*
+ * Deallocate the memory for a spinlock.
+ */
+void
+acpi_os_delete_lock (
+	acpi_handle	handle)
+{
+	ACPI_FUNCTION_TRACE ("os_create_lock");
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting spinlock[%p].\n", handle));
+
+	acpi_os_free(handle);
+
+	return_VOID;
+}
+
+/*
+ * Acquire a spinlock.
+ *
+ * handle is a pointer to the spinlock_t.
+ * flags is *not* the result of save_flags - it is an ACPI-specific flag variable
+ *   that indicates whether we are at interrupt level.
+ */
+void
+acpi_os_acquire_lock (
+	acpi_handle	handle,
+	u32		flags)
+{
+	ACPI_FUNCTION_TRACE ("os_acquire_lock");
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquiring spinlock[%p] from %s level\n", handle,
+		((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));
+
+	if (flags & ACPI_NOT_ISR)
+		ACPI_DISABLE_IRQS();
+
+	spin_lock((spinlock_t *)handle);
+
+	return_VOID;
+}
+
+
+/*
+ * Release a spinlock. See above.
+ */
+void
+acpi_os_release_lock (
+	acpi_handle	handle,
+	u32		flags)
+{
+	ACPI_FUNCTION_TRACE ("os_release_lock");
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Releasing spinlock[%p] from %s level\n", handle,
+		((flags & ACPI_NOT_ISR) ? "non-interrupt" : "interrupt")));
+
+	spin_unlock((spinlock_t *)handle);
+
+	if (flags & ACPI_NOT_ISR)
+		ACPI_ENABLE_IRQS();
+
+	return_VOID;
+}
+
+
+acpi_status
+acpi_os_create_semaphore(
+	u32		max_units,
+	u32		initial_units,
+	acpi_handle	*handle)
+{
+	struct semaphore	*sem = NULL;
+
+	ACPI_FUNCTION_TRACE ("os_create_semaphore");
+
+	sem = acpi_os_allocate(sizeof(struct semaphore));
+	if (!sem)
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	memset(sem, 0, sizeof(struct semaphore));
+
+	sema_init(sem, initial_units);
+
+	*handle = (acpi_handle*)sem;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n", *handle, initial_units));
+
+	return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_os_create_semaphore);
+
+
+/*
+ * TODO: A better way to delete semaphores?  Linux doesn't have a
+ * 'delete_semaphore()' function -- may result in an invalid
+ * pointer dereference for non-synchronized consumers.	Should
+ * we at least check for blocked threads and signal/cancel them?
+ */
+
+acpi_status
+acpi_os_delete_semaphore(
+	acpi_handle	handle)
+{
+	struct semaphore *sem = (struct semaphore*) handle;
+
+	ACPI_FUNCTION_TRACE ("os_delete_semaphore");
+
+	if (!sem)
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
+
+	acpi_os_free(sem); sem =  NULL;
+
+	return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_os_delete_semaphore);
+
+
+/*
+ * TODO: The kernel doesn't have a 'down_timeout' function -- had to
+ * improvise.  The process is to sleep for one scheduler quantum
+ * until the semaphore becomes available.  Downside is that this
+ * may result in starvation for timeout-based waits when there's
+ * lots of semaphore activity.
+ *
+ * TODO: Support for units > 1?
+ */
+acpi_status
+acpi_os_wait_semaphore(
+	acpi_handle		handle,
+	u32			units,
+	u16			timeout)
+{
+	acpi_status		status = AE_OK;
+	struct semaphore	*sem = (struct semaphore*)handle;
+	int			ret = 0;
+
+	ACPI_FUNCTION_TRACE ("os_wait_semaphore");
+
+	if (!sem || (units < 1))
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+
+	if (units > 1)
+		return_ACPI_STATUS (AE_SUPPORT);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout));
+
+	if (in_atomic())
+		timeout = 0;
+
+	switch (timeout)
+	{
+		/*
+		 * No Wait:
+		 * --------
+		 * A zero timeout value indicates that we shouldn't wait - just
+		 * acquire the semaphore if available otherwise return AE_TIME
+		 * (a.k.a. 'would block').
+		 */
+		case 0:
+		if(down_trylock(sem))
+			status = AE_TIME;
+		break;
+
+		/*
+		 * Wait Indefinitely:
+		 * ------------------
+		 */
+		case ACPI_WAIT_FOREVER:
+		down(sem);
+		break;
+
+		/*
+		 * Wait w/ Timeout:
+		 * ----------------
+		 */
+		default:
+		// TODO: A better timeout algorithm?
+		{
+			int i = 0;
+			static const int quantum_ms = 1000/HZ;
+
+			ret = down_trylock(sem);
+			for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
+				current->state = TASK_INTERRUPTIBLE;
+				schedule_timeout(1);
+				ret = down_trylock(sem);
+			}
+	
+			if (ret != 0)
+				status = AE_TIME;
+		}
+		break;
+	}
+
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Failed to acquire semaphore[%p|%d|%d], %s\n", 
+			handle, units, timeout, acpi_format_exception(status)));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout));
+	}
+
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_os_wait_semaphore);
+
+
+/*
+ * TODO: Support for units > 1?
+ */
+acpi_status
+acpi_os_signal_semaphore(
+    acpi_handle 	    handle,
+    u32 		    units)
+{
+	struct semaphore *sem = (struct semaphore *) handle;
+
+	ACPI_FUNCTION_TRACE ("os_signal_semaphore");
+
+	if (!sem || (units < 1))
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+
+	if (units > 1)
+		return_ACPI_STATUS (AE_SUPPORT);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle, units));
+
+	up(sem);
+
+	return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_os_signal_semaphore);
+
+#ifdef ACPI_FUTURE_USAGE
+u32
+acpi_os_get_line(char *buffer)
+{
+
+#ifdef ENABLE_DEBUGGER
+	if (acpi_in_debugger) {
+		u32 chars;
+
+		kdb_read(buffer, sizeof(line_buf));
+
+		/* remove the CR kdb includes */
+		chars = strlen(buffer) - 1;
+		buffer[chars] = '\0';
+	}
+#endif
+
+	return 0;
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+/* Assumes no unreadable holes inbetween */
+u8
+acpi_os_readable(void *ptr, acpi_size len)
+{
+#if defined(__i386__) || defined(__x86_64__) 
+	char tmp;
+	return !__get_user(tmp, (char __user *)ptr) && !__get_user(tmp, (char __user *)ptr + len - 1);
+#endif
+	return 1;
+}
+
+#ifdef ACPI_FUTURE_USAGE
+u8
+acpi_os_writable(void *ptr, acpi_size len)
+{
+	/* could do dummy write (racy) or a kernel page table lookup.
+	   The later may be difficult at early boot when kmap doesn't work yet. */
+	return 1;
+}
+#endif
+
+u32
+acpi_os_get_thread_id (void)
+{
+	if (!in_atomic())
+		return current->pid;
+
+	return 0;
+}
+
+acpi_status
+acpi_os_signal (
+    u32		function,
+    void	*info)
+{
+	switch (function)
+	{
+	case ACPI_SIGNAL_FATAL:
+		printk(KERN_ERR PREFIX "Fatal opcode executed\n");
+		break;
+	case ACPI_SIGNAL_BREAKPOINT:
+		/*
+		 * AML Breakpoint
+		 * ACPI spec. says to treat it as a NOP unless
+		 * you are debugging.  So if/when we integrate
+		 * AML debugger into the kernel debugger its
+		 * hook will go here.  But until then it is
+		 * not useful to print anything on breakpoints.
+		 */
+		break;
+	default:
+		break;
+	}
+
+	return AE_OK;
+}
+EXPORT_SYMBOL(acpi_os_signal);
+
+static int __init
+acpi_os_name_setup(char *str)
+{
+	char *p = acpi_os_name;
+	int count = ACPI_MAX_OVERRIDE_LEN-1;
+
+	if (!str || !*str)
+		return 0;
+
+	for (; count-- && str && *str; str++) {
+		if (isalnum(*str) || *str == ' ' || *str == ':')
+			*p++ = *str;
+		else if (*str == '\'' || *str == '"')
+			continue;
+		else
+			break;
+	}
+	*p = 0;
+
+	return 1;
+		
+}
+
+__setup("acpi_os_name=", acpi_os_name_setup);
+
+/*
+ * _OSI control
+ * empty string disables _OSI
+ * TBD additional string adds to _OSI
+ */
+static int __init
+acpi_osi_setup(char *str)
+{
+	if (str == NULL || *str == '\0') {
+		printk(KERN_INFO PREFIX "_OSI method disabled\n");
+		acpi_gbl_create_osi_method = FALSE;
+	} else
+	{
+		/* TBD */
+		printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n", str);
+	}
+
+	return 1;
+}
+
+__setup("acpi_osi=", acpi_osi_setup);
+
+/* enable serialization to combat AE_ALREADY_EXISTS errors */
+static int __init
+acpi_serialize_setup(char *str)
+{
+	printk(KERN_INFO PREFIX "serialize enabled\n");
+
+	acpi_gbl_all_methods_serialized = TRUE;
+
+	return 1;
+}
+
+__setup("acpi_serialize", acpi_serialize_setup);
+
+/*
+ * Wake and Run-Time GPES are expected to be separate.
+ * We disable wake-GPEs at run-time to prevent spurious
+ * interrupts.
+ *
+ * However, if a system exists that shares Wake and
+ * Run-time events on the same GPE this flag is available
+ * to tell Linux to keep the wake-time GPEs enabled at run-time.
+ */
+static int __init
+acpi_wake_gpes_always_on_setup(char *str)
+{
+	printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
+
+	acpi_gbl_leave_wake_gpes_disabled = FALSE;
+
+	return 1;
+}
+
+__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
+
+/*
+ * max_cstate is defined in the base kernel so modules can
+ * change it w/o depending on the state of the processor module.
+ */
+unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
+
+
+EXPORT_SYMBOL(max_cstate);
diff --git a/drivers/acpi/parser/Makefile b/drivers/acpi/parser/Makefile
new file mode 100644
index 0000000..bbdd286
--- /dev/null
+++ b/drivers/acpi/parser/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := psargs.o    psparse.o  pstree.o   pswalk.o  \
+	 psopcode.o  psscope.o  psutils.o  psxface.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
new file mode 100644
index 0000000..b5d9889
--- /dev/null
+++ b/drivers/acpi/parser/psargs.c
@@ -0,0 +1,746 @@
+/******************************************************************************
+ *
+ * Module Name: psargs - Parse AML opcode arguments
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("psargs")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_next_package_length
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Decoded package length.  On completion, the AML pointer points
+ *              past the length byte or bytes.
+ *
+ * DESCRIPTION: Decode and return a package length field
+ *
+ ******************************************************************************/
+
+u32
+acpi_ps_get_next_package_length (
+	struct acpi_parse_state         *parser_state)
+{
+	u32                             encoded_length;
+	u32                             length = 0;
+
+
+	ACPI_FUNCTION_TRACE ("ps_get_next_package_length");
+
+
+	encoded_length = (u32) ACPI_GET8 (parser_state->aml);
+	parser_state->aml++;
+
+
+	switch (encoded_length >> 6) /* bits 6-7 contain encoding scheme */ {
+	case 0: /* 1-byte encoding (bits 0-5) */
+
+		length = (encoded_length & 0x3F);
+		break;
+
+
+	case 1: /* 2-byte encoding (next byte + bits 0-3) */
+
+		length = ((ACPI_GET8 (parser_state->aml) << 04) |
+				 (encoded_length & 0x0F));
+		parser_state->aml++;
+		break;
+
+
+	case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
+
+		length = ((ACPI_GET8 (parser_state->aml + 1) << 12) |
+				  (ACPI_GET8 (parser_state->aml)    << 04) |
+				  (encoded_length & 0x0F));
+		parser_state->aml += 2;
+		break;
+
+
+	case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
+
+		length = ((ACPI_GET8 (parser_state->aml + 2) << 20) |
+				  (ACPI_GET8 (parser_state->aml + 1) << 12) |
+				  (ACPI_GET8 (parser_state->aml)    << 04) |
+				  (encoded_length & 0x0F));
+		parser_state->aml += 3;
+		break;
+
+	default:
+
+		/* Can't get here, only 2 bits / 4 cases */
+		break;
+	}
+
+	return_VALUE (length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_next_package_end
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Pointer to end-of-package +1
+ *
+ * DESCRIPTION: Get next package length and return a pointer past the end of
+ *              the package.  Consumes the package length field
+ *
+ ******************************************************************************/
+
+u8 *
+acpi_ps_get_next_package_end (
+	struct acpi_parse_state         *parser_state)
+{
+	u8                              *start = parser_state->aml;
+	acpi_native_uint                length;
+
+
+	ACPI_FUNCTION_TRACE ("ps_get_next_package_end");
+
+
+	/* Function below changes parser_state->Aml */
+
+	length = (acpi_native_uint) acpi_ps_get_next_package_length (parser_state);
+
+	return_PTR (start + length); /* end of package */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_next_namestring
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Pointer to the start of the name string (pointer points into
+ *              the AML.
+ *
+ * DESCRIPTION: Get next raw namestring within the AML stream.  Handles all name
+ *              prefix characters.  Set parser state to point past the string.
+ *              (Name is consumed from the AML.)
+ *
+ ******************************************************************************/
+
+char *
+acpi_ps_get_next_namestring (
+	struct acpi_parse_state         *parser_state)
+{
+	u8                              *start = parser_state->aml;
+	u8                              *end = parser_state->aml;
+
+
+	ACPI_FUNCTION_TRACE ("ps_get_next_namestring");
+
+
+	/* Handle multiple prefix characters */
+
+	while (acpi_ps_is_prefix_char (ACPI_GET8 (end))) {
+		/* Include prefix '\\' or '^' */
+
+		end++;
+	}
+
+	/* Decode the path */
+
+	switch (ACPI_GET8 (end)) {
+	case 0:
+
+		/* null_name */
+
+		if (end == start) {
+			start = NULL;
+		}
+		end++;
+		break;
+
+	case AML_DUAL_NAME_PREFIX:
+
+		/* Two name segments */
+
+		end += 1 + (2 * ACPI_NAME_SIZE);
+		break;
+
+	case AML_MULTI_NAME_PREFIX_OP:
+
+		/* Multiple name segments, 4 chars each */
+
+		end += 2 + ((acpi_size) ACPI_GET8 (end + 1) * ACPI_NAME_SIZE);
+		break;
+
+	default:
+
+		/* Single name segment */
+
+		end += ACPI_NAME_SIZE;
+		break;
+	}
+
+	parser_state->aml = (u8*) end;
+	return_PTR ((char *) start);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_next_namepath
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *              Arg                 - Where the namepath will be stored
+ *              arg_count           - If the namepath points to a control method
+ *                                    the method's argument is returned here.
+ *              method_call         - Whether the namepath can possibly be the
+ *                                    start of a method call
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get next name (if method call, return # of required args).
+ *              Names are looked up in the internal namespace to determine
+ *              if the name represents a control method.  If a method
+ *              is found, the number of arguments to the method is returned.
+ *              This information is critical for parsing to continue correctly.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_get_next_namepath (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         *arg,
+	u8                              method_call)
+{
+	char                            *path;
+	union acpi_parse_object         *name_op;
+	acpi_status                     status = AE_OK;
+	union acpi_operand_object       *method_desc;
+	struct acpi_namespace_node      *node;
+	union acpi_generic_state        scope_info;
+
+
+	ACPI_FUNCTION_TRACE ("ps_get_next_namepath");
+
+
+	path = acpi_ps_get_next_namestring (parser_state);
+
+	/* Null path case is allowed */
+
+	if (path) {
+		/*
+		 * Lookup the name in the internal namespace
+		 */
+		scope_info.scope.node = NULL;
+		node = parser_state->start_node;
+		if (node) {
+			scope_info.scope.node = node;
+		}
+
+		/*
+		 * Lookup object.  We don't want to add anything new to the namespace
+		 * here, however.  So we use MODE_EXECUTE.  Allow searching of the
+		 * parent tree, but don't open a new scope -- we just want to lookup the
+		 * object  (MUST BE mode EXECUTE to perform upsearch)
+		 */
+		status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+				 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
+		if (ACPI_SUCCESS (status) && method_call) {
+			if (node->type == ACPI_TYPE_METHOD) {
+				/*
+				 * This name is actually a control method invocation
+				 */
+				method_desc = acpi_ns_get_attached_object (node);
+				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+					"Control Method - %p Desc %p Path=%p\n",
+					node, method_desc, path));
+
+				name_op = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
+				if (!name_op) {
+					return_ACPI_STATUS (AE_NO_MEMORY);
+				}
+
+				/* Change arg into a METHOD CALL and attach name to it */
+
+				acpi_ps_init_op (arg, AML_INT_METHODCALL_OP);
+				name_op->common.value.name = path;
+
+				/* Point METHODCALL/NAME to the METHOD Node */
+
+				name_op->common.node = node;
+				acpi_ps_append_arg (arg, name_op);
+
+				if (!method_desc) {
+					ACPI_REPORT_ERROR ((
+						"ps_get_next_namepath: Control Method %p has no attached object\n",
+						node));
+					return_ACPI_STATUS (AE_AML_INTERNAL);
+				}
+
+				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+					"Control Method - %p Args %X\n",
+					node, method_desc->method.param_count));
+
+				/* Get the number of arguments to expect */
+
+				walk_state->arg_count = method_desc->method.param_count;
+				return_ACPI_STATUS (AE_OK);
+			}
+
+			/*
+			 * Else this is normal named object reference.
+			 * Just init the NAMEPATH object with the pathname.
+			 * (See code below)
+			 */
+		}
+
+		if (ACPI_FAILURE (status)) {
+			/*
+			 * 1) Any error other than NOT_FOUND is always severe
+			 * 2) NOT_FOUND is only important if we are executing a method.
+			 * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok.
+			 */
+			if ((((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) &&
+				(status == AE_NOT_FOUND)                                                &&
+				(walk_state->op->common.aml_opcode != AML_COND_REF_OF_OP)) ||
+
+				(status != AE_NOT_FOUND)) {
+				ACPI_REPORT_NSERROR (path, status);
+
+				acpi_os_printf ("search_node %p start_node %p return_node %p\n",
+					scope_info.scope.node, parser_state->start_node, node);
+
+
+			}
+			else {
+				/*
+				 * We got a NOT_FOUND during table load or we encountered
+				 * a cond_ref_of(x) where the target does not exist.
+				 * -- either case is ok
+				 */
+				status = AE_OK;
+			}
+		}
+	}
+
+	/*
+	 * Regardless of success/failure above,
+	 * Just initialize the Op with the pathname.
+	 */
+	acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
+	arg->common.value.name = path;
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_next_simple_arg
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *              arg_type            - The argument type (AML_*_ARG)
+ *              Arg                 - Where the argument is returned
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_get_next_simple_arg (
+	struct acpi_parse_state         *parser_state,
+	u32                             arg_type,
+	union acpi_parse_object         *arg)
+{
+
+	ACPI_FUNCTION_TRACE_U32 ("ps_get_next_simple_arg", arg_type);
+
+
+	switch (arg_type) {
+	case ARGP_BYTEDATA:
+
+		acpi_ps_init_op (arg, AML_BYTE_OP);
+		arg->common.value.integer = (u32) ACPI_GET8 (parser_state->aml);
+		parser_state->aml++;
+		break;
+
+
+	case ARGP_WORDDATA:
+
+		acpi_ps_init_op (arg, AML_WORD_OP);
+
+		/* Get 2 bytes from the AML stream */
+
+		ACPI_MOVE_16_TO_32 (&arg->common.value.integer, parser_state->aml);
+		parser_state->aml += 2;
+		break;
+
+
+	case ARGP_DWORDDATA:
+
+		acpi_ps_init_op (arg, AML_DWORD_OP);
+
+		/* Get 4 bytes from the AML stream */
+
+		ACPI_MOVE_32_TO_32 (&arg->common.value.integer, parser_state->aml);
+		parser_state->aml += 4;
+		break;
+
+
+	case ARGP_QWORDDATA:
+
+		acpi_ps_init_op (arg, AML_QWORD_OP);
+
+		/* Get 8 bytes from the AML stream */
+
+		ACPI_MOVE_64_TO_64 (&arg->common.value.integer, parser_state->aml);
+		parser_state->aml += 8;
+		break;
+
+
+	case ARGP_CHARLIST:
+
+		acpi_ps_init_op (arg, AML_STRING_OP);
+		arg->common.value.string = (char *) parser_state->aml;
+
+		while (ACPI_GET8 (parser_state->aml) != '\0') {
+			parser_state->aml++;
+		}
+		parser_state->aml++;
+		break;
+
+
+	case ARGP_NAME:
+	case ARGP_NAMESTRING:
+
+		acpi_ps_init_op (arg, AML_INT_NAMEPATH_OP);
+		arg->common.value.name = acpi_ps_get_next_namestring (parser_state);
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("Invalid arg_type %X\n", arg_type));
+		break;
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_next_field
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      A newly allocated FIELD op
+ *
+ * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
+ *
+ ******************************************************************************/
+
+union acpi_parse_object *
+acpi_ps_get_next_field (
+	struct acpi_parse_state         *parser_state)
+{
+	u32                             aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
+			 parser_state->aml_start);
+	union acpi_parse_object         *field;
+	u16                             opcode;
+	u32                             name;
+
+
+	ACPI_FUNCTION_TRACE ("ps_get_next_field");
+
+
+	/* determine field type */
+
+	switch (ACPI_GET8 (parser_state->aml)) {
+	default:
+
+		opcode = AML_INT_NAMEDFIELD_OP;
+		break;
+
+	case 0x00:
+
+		opcode = AML_INT_RESERVEDFIELD_OP;
+		parser_state->aml++;
+		break;
+
+	case 0x01:
+
+		opcode = AML_INT_ACCESSFIELD_OP;
+		parser_state->aml++;
+		break;
+	}
+
+
+	/* Allocate a new field op */
+
+	field = acpi_ps_alloc_op (opcode);
+	if (!field) {
+		return_PTR (NULL);
+	}
+
+	field->common.aml_offset = aml_offset;
+
+	/* Decode the field type */
+
+	switch (opcode) {
+	case AML_INT_NAMEDFIELD_OP:
+
+		/* Get the 4-character name */
+
+		ACPI_MOVE_32_TO_32 (&name, parser_state->aml);
+		acpi_ps_set_name (field, name);
+		parser_state->aml += ACPI_NAME_SIZE;
+
+		/* Get the length which is encoded as a package length */
+
+		field->common.value.size = acpi_ps_get_next_package_length (parser_state);
+		break;
+
+
+	case AML_INT_RESERVEDFIELD_OP:
+
+		/* Get the length which is encoded as a package length */
+
+		field->common.value.size = acpi_ps_get_next_package_length (parser_state);
+		break;
+
+
+	case AML_INT_ACCESSFIELD_OP:
+
+		/*
+		 * Get access_type and access_attrib and merge into the field Op
+		 * access_type is first operand, access_attribute is second
+		 */
+		field->common.value.integer = (ACPI_GET8 (parser_state->aml) << 8);
+		parser_state->aml++;
+		field->common.value.integer |= ACPI_GET8 (parser_state->aml);
+		parser_state->aml++;
+		break;
+
+	default:
+
+		/* Opcode was set in previous switch */
+		break;
+	}
+
+	return_PTR (field);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_next_arg
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *              arg_type            - The argument type (AML_*_ARG)
+ *              arg_count           - If the argument points to a control method
+ *                                    the method's argument is returned here.
+ *
+ * RETURN:      Status, and an op object containing the next argument.
+ *
+ * DESCRIPTION: Get next argument (including complex list arguments that require
+ *              pushing the parser stack)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_get_next_arg (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_parse_state         *parser_state,
+	u32                             arg_type,
+	union acpi_parse_object         **return_arg)
+{
+	union acpi_parse_object         *arg = NULL;
+	union acpi_parse_object         *prev = NULL;
+	union acpi_parse_object         *field;
+	u32                             subop;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_get_next_arg", parser_state);
+
+
+	switch (arg_type) {
+	case ARGP_BYTEDATA:
+	case ARGP_WORDDATA:
+	case ARGP_DWORDDATA:
+	case ARGP_CHARLIST:
+	case ARGP_NAME:
+	case ARGP_NAMESTRING:
+
+		/* constants, strings, and namestrings are all the same size */
+
+		arg = acpi_ps_alloc_op (AML_BYTE_OP);
+		if (!arg) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+		acpi_ps_get_next_simple_arg (parser_state, arg_type, arg);
+		break;
+
+
+	case ARGP_PKGLENGTH:
+
+		/* Package length, nothing returned */
+
+		parser_state->pkg_end = acpi_ps_get_next_package_end (parser_state);
+		break;
+
+
+	case ARGP_FIELDLIST:
+
+		if (parser_state->aml < parser_state->pkg_end) {
+			/* Non-empty list */
+
+			while (parser_state->aml < parser_state->pkg_end) {
+				field = acpi_ps_get_next_field (parser_state);
+				if (!field) {
+					return_ACPI_STATUS (AE_NO_MEMORY);
+				}
+
+				if (prev) {
+					prev->common.next = field;
+				}
+				else {
+					arg = field;
+				}
+
+				prev = field;
+			}
+
+			/* Skip to End of byte data */
+
+			parser_state->aml = parser_state->pkg_end;
+		}
+		break;
+
+
+	case ARGP_BYTELIST:
+
+		if (parser_state->aml < parser_state->pkg_end) {
+			/* Non-empty list */
+
+			arg = acpi_ps_alloc_op (AML_INT_BYTELIST_OP);
+			if (!arg) {
+				return_ACPI_STATUS (AE_NO_MEMORY);
+			}
+
+			/* Fill in bytelist data */
+
+			arg->common.value.size = (u32) ACPI_PTR_DIFF (parser_state->pkg_end,
+					  parser_state->aml);
+			arg->named.data = parser_state->aml;
+
+			/* Skip to End of byte data */
+
+			parser_state->aml = parser_state->pkg_end;
+		}
+		break;
+
+
+	case ARGP_TARGET:
+	case ARGP_SUPERNAME:
+	case ARGP_SIMPLENAME:
+
+		subop = acpi_ps_peek_opcode (parser_state);
+		if (subop == 0                  ||
+			acpi_ps_is_leading_char (subop) ||
+			acpi_ps_is_prefix_char (subop)) {
+			/* null_name or name_string */
+
+			arg = acpi_ps_alloc_op (AML_INT_NAMEPATH_OP);
+			if (!arg) {
+				return_ACPI_STATUS (AE_NO_MEMORY);
+			}
+
+			status = acpi_ps_get_next_namepath (walk_state, parser_state, arg, 0);
+		}
+		else {
+			/* single complex argument, nothing returned */
+
+			walk_state->arg_count = 1;
+		}
+		break;
+
+
+	case ARGP_DATAOBJ:
+	case ARGP_TERMARG:
+
+		/* single complex argument, nothing returned */
+
+		walk_state->arg_count = 1;
+		break;
+
+
+	case ARGP_DATAOBJLIST:
+	case ARGP_TERMLIST:
+	case ARGP_OBJLIST:
+
+		if (parser_state->aml < parser_state->pkg_end) {
+			/* non-empty list of variable arguments, nothing returned */
+
+			walk_state->arg_count = ACPI_VAR_ARGS;
+		}
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("Invalid arg_type: %X\n", arg_type));
+		status = AE_AML_OPERAND_TYPE;
+		break;
+	}
+
+	*return_arg = arg;
+	return_ACPI_STATUS (status);
+}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
new file mode 100644
index 0000000..03e33fe
--- /dev/null
+++ b/drivers/acpi/parser/psopcode.c
@@ -0,0 +1,778 @@
+/******************************************************************************
+ *
+ * Module Name: psopcode - Parser/Interpreter opcode information table
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("psopcode")
+
+
+#define _UNK                        0x6B
+/*
+ * Reserved ASCII characters.  Do not use any of these for
+ * internal opcodes, since they are used to differentiate
+ * name strings from AML opcodes
+ */
+#define _ASC                        0x6C
+#define _NAM                        0x6C
+#define _PFX                        0x6D
+#define _UNKNOWN_OPCODE             0x02    /* An example unknown opcode */
+
+#define MAX_EXTENDED_OPCODE         0x88
+#define NUM_EXTENDED_OPCODE         (MAX_EXTENDED_OPCODE + 1)
+#define MAX_INTERNAL_OPCODE
+#define NUM_INTERNAL_OPCODE         (MAX_INTERNAL_OPCODE + 1)
+
+
+/*******************************************************************************
+ *
+ * NAME:        acpi_gbl_aml_op_info
+ *
+ * DESCRIPTION: Opcode table. Each entry contains <opcode, type, name, operands>
+ *              The name is a simple ascii string, the operand specifier is an
+ *              ascii string with one letter per operand.  The letter specifies
+ *              the operand type.
+ *
+ ******************************************************************************/
+
+
+/*
+ * All AML opcodes and the parse-time arguments for each.  Used by the AML parser  Each list is compressed
+ * into a 32-bit number and stored in the master opcode table at the end of this file.
+ */
+
+
+#define ARGP_ACCESSFIELD_OP             ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_ACQUIRE_OP                 ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_WORDDATA)
+#define ARGP_ADD_OP                     ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_ALIAS_OP                   ARGP_LIST2 (ARGP_NAMESTRING, ARGP_NAME)
+#define ARGP_ARG0                       ARG_NONE
+#define ARGP_ARG1                       ARG_NONE
+#define ARGP_ARG2                       ARG_NONE
+#define ARGP_ARG3                       ARG_NONE
+#define ARGP_ARG4                       ARG_NONE
+#define ARGP_ARG5                       ARG_NONE
+#define ARGP_ARG6                       ARG_NONE
+#define ARGP_BANK_FIELD_OP              ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_NAMESTRING,ARGP_TERMARG,   ARGP_BYTEDATA,  ARGP_FIELDLIST)
+#define ARGP_BIT_AND_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_NAND_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_NOR_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_NOT_OP                 ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_BIT_OR_OP                  ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_XOR_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BREAK_OP                   ARG_NONE
+#define ARGP_BREAK_POINT_OP             ARG_NONE
+#define ARGP_BUFFER_OP                  ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_BYTELIST)
+#define ARGP_BYTE_OP                    ARGP_LIST1 (ARGP_BYTEDATA)
+#define ARGP_BYTELIST_OP                ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_CONCAT_OP                  ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_CONCAT_RES_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_COND_REF_OF_OP             ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_SUPERNAME)
+#define ARGP_CONTINUE_OP                ARG_NONE
+#define ARGP_COPY_OP                    ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_SIMPLENAME)
+#define ARGP_CREATE_BIT_FIELD_OP        ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_BYTE_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_DWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_FIELD_OP            ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_NAME)
+#define ARGP_CREATE_QWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_WORD_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_DATA_REGION_OP             ARGP_LIST4 (ARGP_NAME,       ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_DEBUG_OP                   ARG_NONE
+#define ARGP_DECREMENT_OP               ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_DEREF_OF_OP                ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_DEVICE_OP                  ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_OBJLIST)
+#define ARGP_DIVIDE_OP                  ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET,    ARGP_TARGET)
+#define ARGP_DWORD_OP                   ARGP_LIST1 (ARGP_DWORDDATA)
+#define ARGP_ELSE_OP                    ARGP_LIST2 (ARGP_PKGLENGTH,  ARGP_TERMLIST)
+#define ARGP_EVENT_OP                   ARGP_LIST1 (ARGP_NAME)
+#define ARGP_FATAL_OP                   ARGP_LIST3 (ARGP_BYTEDATA,   ARGP_DWORDDATA,     ARGP_TERMARG)
+#define ARGP_FIELD_OP                   ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_BYTEDATA,  ARGP_FIELDLIST)
+#define ARGP_FIND_SET_LEFT_BIT_OP       ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_FIND_SET_RIGHT_BIT_OP      ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_FROM_BCD_OP                ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_IF_OP                      ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_TERMLIST)
+#define ARGP_INCREMENT_OP               ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_INDEX_FIELD_OP             ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_NAMESTRING,ARGP_BYTEDATA,  ARGP_FIELDLIST)
+#define ARGP_INDEX_OP                   ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_LAND_OP                    ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LEQUAL_OP                  ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LGREATER_OP                ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LGREATEREQUAL_OP           ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LLESS_OP                   ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LLESSEQUAL_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LNOT_OP                    ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_LNOTEQUAL_OP               ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LOAD_OP                    ARGP_LIST2 (ARGP_NAMESTRING, ARGP_SUPERNAME)
+#define ARGP_LOAD_TABLE_OP              ARGP_LIST6 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TERMARG,  ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_LOCAL0                     ARG_NONE
+#define ARGP_LOCAL1                     ARG_NONE
+#define ARGP_LOCAL2                     ARG_NONE
+#define ARGP_LOCAL3                     ARG_NONE
+#define ARGP_LOCAL4                     ARG_NONE
+#define ARGP_LOCAL5                     ARG_NONE
+#define ARGP_LOCAL6                     ARG_NONE
+#define ARGP_LOCAL7                     ARG_NONE
+#define ARGP_LOR_OP                     ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_MATCH_OP                   ARGP_LIST6 (ARGP_TERMARG,    ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_BYTEDATA,  ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_METHOD_OP                  ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_TERMLIST)
+#define ARGP_METHODCALL_OP              ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_MID_OP                     ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TARGET)
+#define ARGP_MOD_OP                     ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_MULTIPLY_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_MUTEX_OP                   ARGP_LIST2 (ARGP_NAME,       ARGP_BYTEDATA)
+#define ARGP_NAME_OP                    ARGP_LIST2 (ARGP_NAME,       ARGP_DATAOBJ)
+#define ARGP_NAMEDFIELD_OP              ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_NAMEPATH_OP                ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_NOOP_OP                    ARG_NONE
+#define ARGP_NOTIFY_OP                  ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG)
+#define ARGP_ONE_OP                     ARG_NONE
+#define ARGP_ONES_OP                    ARG_NONE
+#define ARGP_PACKAGE_OP                 ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_BYTEDATA,      ARGP_DATAOBJLIST)
+#define ARGP_POWER_RES_OP               ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_WORDDATA,  ARGP_OBJLIST)
+#define ARGP_PROCESSOR_OP               ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_DWORDDATA, ARGP_BYTEDATA,  ARGP_OBJLIST)
+#define ARGP_QWORD_OP                   ARGP_LIST1 (ARGP_QWORDDATA)
+#define ARGP_REF_OF_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_REGION_OP                  ARGP_LIST4 (ARGP_NAME,       ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_RELEASE_OP                 ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_RESERVEDFIELD_OP           ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_RESET_OP                   ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_RETURN_OP                  ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_REVISION_OP                ARG_NONE
+#define ARGP_SCOPE_OP                   ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_TERMLIST)
+#define ARGP_SHIFT_LEFT_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_SHIFT_RIGHT_OP             ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_SIGNAL_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_SIZE_OF_OP                 ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_SLEEP_OP                   ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_STALL_OP                   ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_STATICSTRING_OP            ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_STORE_OP                   ARGP_LIST2 (ARGP_TERMARG,    ARGP_SUPERNAME)
+#define ARGP_STRING_OP                  ARGP_LIST1 (ARGP_CHARLIST)
+#define ARGP_SUBTRACT_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_THERMAL_ZONE_OP            ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_OBJLIST)
+#define ARGP_TIMER_OP                   ARG_NONE
+#define ARGP_TO_BCD_OP                  ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_BUFFER_OP               ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_DEC_STR_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_HEX_STR_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_INTEGER_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_STRING_OP               ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_TYPE_OP                    ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_UNLOAD_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_VAR_PACKAGE_OP             ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_DATAOBJLIST)
+#define ARGP_WAIT_OP                    ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG)
+#define ARGP_WHILE_OP                   ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_TERMLIST)
+#define ARGP_WORD_OP                    ARGP_LIST1 (ARGP_WORDDATA)
+#define ARGP_ZERO_OP                    ARG_NONE
+
+
+/*
+ * All AML opcodes and the runtime arguments for each.  Used by the AML interpreter  Each list is compressed
+ * into a 32-bit number and stored in the master opcode table at the end of this file.
+ *
+ * (Used by prep_operands procedure and the ASL Compiler)
+ */
+
+
+#define ARGI_ACCESSFIELD_OP             ARGI_INVALID_OPCODE
+#define ARGI_ACQUIRE_OP                 ARGI_LIST2 (ARGI_MUTEX,      ARGI_INTEGER)
+#define ARGI_ADD_OP                     ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_ALIAS_OP                   ARGI_INVALID_OPCODE
+#define ARGI_ARG0                       ARG_NONE
+#define ARGI_ARG1                       ARG_NONE
+#define ARGI_ARG2                       ARG_NONE
+#define ARGI_ARG3                       ARG_NONE
+#define ARGI_ARG4                       ARG_NONE
+#define ARGI_ARG5                       ARG_NONE
+#define ARGI_ARG6                       ARG_NONE
+#define ARGI_BANK_FIELD_OP              ARGI_INVALID_OPCODE
+#define ARGI_BIT_AND_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_NAND_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_NOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_NOT_OP                 ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_BIT_OR_OP                  ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_XOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BREAK_OP                   ARG_NONE
+#define ARGI_BREAK_POINT_OP             ARG_NONE
+#define ARGI_BUFFER_OP                  ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_BYTE_OP                    ARGI_INVALID_OPCODE
+#define ARGI_BYTELIST_OP                ARGI_INVALID_OPCODE
+#define ARGI_CONCAT_OP                  ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA,   ARGI_TARGETREF)
+#define ARGI_CONCAT_RES_OP              ARGI_LIST3 (ARGI_BUFFER,     ARGI_BUFFER,        ARGI_TARGETREF)
+#define ARGI_COND_REF_OF_OP             ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)
+#define ARGI_CONTINUE_OP                ARGI_INVALID_OPCODE
+#define ARGI_COPY_OP                    ARGI_LIST2 (ARGI_ANYTYPE,    ARGI_SIMPLE_TARGET)
+#define ARGI_CREATE_BIT_FIELD_OP        ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_BYTE_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_DWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_FIELD_OP            ARGI_LIST4 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_INTEGER,      ARGI_REFERENCE)
+#define ARGI_CREATE_QWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_WORD_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_DATA_REGION_OP             ARGI_LIST3 (ARGI_STRING,     ARGI_STRING,        ARGI_STRING)
+#define ARGI_DEBUG_OP                   ARG_NONE
+#define ARGI_DECREMENT_OP               ARGI_LIST1 (ARGI_INTEGER_REF)
+#define ARGI_DEREF_OF_OP                ARGI_LIST1 (ARGI_REF_OR_STRING)
+#define ARGI_DEVICE_OP                  ARGI_INVALID_OPCODE
+#define ARGI_DIVIDE_OP                  ARGI_LIST4 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF,    ARGI_TARGETREF)
+#define ARGI_DWORD_OP                   ARGI_INVALID_OPCODE
+#define ARGI_ELSE_OP                    ARGI_INVALID_OPCODE
+#define ARGI_EVENT_OP                   ARGI_INVALID_OPCODE
+#define ARGI_FATAL_OP                   ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_INTEGER)
+#define ARGI_FIELD_OP                   ARGI_INVALID_OPCODE
+#define ARGI_FIND_SET_LEFT_BIT_OP       ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_FIND_SET_RIGHT_BIT_OP      ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_FROM_BCD_OP                ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_IF_OP                      ARGI_INVALID_OPCODE
+#define ARGI_INCREMENT_OP               ARGI_LIST1 (ARGI_INTEGER_REF)
+#define ARGI_INDEX_FIELD_OP             ARGI_INVALID_OPCODE
+#define ARGI_INDEX_OP                   ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_LAND_OP                    ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_LEQUAL_OP                  ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LGREATER_OP                ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LGREATEREQUAL_OP           ARGI_INVALID_OPCODE
+#define ARGI_LLESS_OP                   ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LLESSEQUAL_OP              ARGI_INVALID_OPCODE
+#define ARGI_LNOT_OP                    ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_LNOTEQUAL_OP               ARGI_INVALID_OPCODE
+#define ARGI_LOAD_OP                    ARGI_LIST2 (ARGI_REGION_OR_FIELD,ARGI_TARGETREF)
+#define ARGI_LOAD_TABLE_OP              ARGI_LIST6 (ARGI_STRING,     ARGI_STRING,        ARGI_STRING,       ARGI_STRING,    ARGI_STRING, ARGI_ANYTYPE)
+#define ARGI_LOCAL0                     ARG_NONE
+#define ARGI_LOCAL1                     ARG_NONE
+#define ARGI_LOCAL2                     ARG_NONE
+#define ARGI_LOCAL3                     ARG_NONE
+#define ARGI_LOCAL4                     ARG_NONE
+#define ARGI_LOCAL5                     ARG_NONE
+#define ARGI_LOCAL6                     ARG_NONE
+#define ARGI_LOCAL7                     ARG_NONE
+#define ARGI_LOR_OP                     ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_MATCH_OP                   ARGI_LIST6 (ARGI_PACKAGE,    ARGI_INTEGER,   ARGI_COMPUTEDATA,      ARGI_INTEGER,ARGI_COMPUTEDATA,ARGI_INTEGER)
+#define ARGI_METHOD_OP                  ARGI_INVALID_OPCODE
+#define ARGI_METHODCALL_OP              ARGI_INVALID_OPCODE
+#define ARGI_MID_OP                     ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER,  ARGI_INTEGER,      ARGI_TARGETREF)
+#define ARGI_MOD_OP                     ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_MULTIPLY_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_MUTEX_OP                   ARGI_INVALID_OPCODE
+#define ARGI_NAME_OP                    ARGI_INVALID_OPCODE
+#define ARGI_NAMEDFIELD_OP              ARGI_INVALID_OPCODE
+#define ARGI_NAMEPATH_OP                ARGI_INVALID_OPCODE
+#define ARGI_NOOP_OP                    ARG_NONE
+#define ARGI_NOTIFY_OP                  ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER)
+#define ARGI_ONE_OP                     ARG_NONE
+#define ARGI_ONES_OP                    ARG_NONE
+#define ARGI_PACKAGE_OP                 ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_POWER_RES_OP               ARGI_INVALID_OPCODE
+#define ARGI_PROCESSOR_OP               ARGI_INVALID_OPCODE
+#define ARGI_QWORD_OP                   ARGI_INVALID_OPCODE
+#define ARGI_REF_OF_OP                  ARGI_LIST1 (ARGI_OBJECT_REF)
+#define ARGI_REGION_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_RELEASE_OP                 ARGI_LIST1 (ARGI_MUTEX)
+#define ARGI_RESERVEDFIELD_OP           ARGI_INVALID_OPCODE
+#define ARGI_RESET_OP                   ARGI_LIST1 (ARGI_EVENT)
+#define ARGI_RETURN_OP                  ARGI_INVALID_OPCODE
+#define ARGI_REVISION_OP                ARG_NONE
+#define ARGI_SCOPE_OP                   ARGI_INVALID_OPCODE
+#define ARGI_SHIFT_LEFT_OP              ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_SHIFT_RIGHT_OP             ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_SIGNAL_OP                  ARGI_LIST1 (ARGI_EVENT)
+#define ARGI_SIZE_OF_OP                 ARGI_LIST1 (ARGI_DATAOBJECT)
+#define ARGI_SLEEP_OP                   ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_STALL_OP                   ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_STATICSTRING_OP            ARGI_INVALID_OPCODE
+#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
+#define ARGI_STRING_OP                  ARGI_INVALID_OPCODE
+#define ARGI_SUBTRACT_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_THERMAL_ZONE_OP            ARGI_INVALID_OPCODE
+#define ARGI_TIMER_OP                   ARG_NONE
+#define ARGI_TO_BCD_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_FIXED_TARGET)
+#define ARGI_TO_BUFFER_OP               ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_DEC_STR_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_HEX_STR_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_INTEGER_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_STRING_OP               ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_FIXED_TARGET)
+#define ARGI_TYPE_OP                    ARGI_LIST1 (ARGI_ANYTYPE)
+#define ARGI_UNLOAD_OP                  ARGI_LIST1 (ARGI_DDBHANDLE)
+#define ARGI_VAR_PACKAGE_OP             ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_WAIT_OP                    ARGI_LIST2 (ARGI_EVENT,      ARGI_INTEGER)
+#define ARGI_WHILE_OP                   ARGI_INVALID_OPCODE
+#define ARGI_WORD_OP                    ARGI_INVALID_OPCODE
+#define ARGI_ZERO_OP                    ARG_NONE
+
+
+/*
+ * Summary of opcode types/flags
+ */
+
+/******************************************************************************
+
+ Opcodes that have associated namespace objects (AML_NSOBJECT flag)
+
+	AML_SCOPE_OP
+	AML_DEVICE_OP
+	AML_THERMAL_ZONE_OP
+	AML_METHOD_OP
+	AML_POWER_RES_OP
+	AML_PROCESSOR_OP
+	AML_FIELD_OP
+	AML_INDEX_FIELD_OP
+	AML_BANK_FIELD_OP
+	AML_NAME_OP
+	AML_ALIAS_OP
+	AML_MUTEX_OP
+	AML_EVENT_OP
+	AML_REGION_OP
+	AML_CREATE_FIELD_OP
+	AML_CREATE_BIT_FIELD_OP
+	AML_CREATE_BYTE_FIELD_OP
+	AML_CREATE_WORD_FIELD_OP
+	AML_CREATE_DWORD_FIELD_OP
+	AML_CREATE_QWORD_FIELD_OP
+	AML_INT_NAMEDFIELD_OP
+	AML_INT_METHODCALL_OP
+	AML_INT_NAMEPATH_OP
+
+  Opcodes that are "namespace" opcodes (AML_NSOPCODE flag)
+
+	AML_SCOPE_OP
+	AML_DEVICE_OP
+	AML_THERMAL_ZONE_OP
+	AML_METHOD_OP
+	AML_POWER_RES_OP
+	AML_PROCESSOR_OP
+	AML_FIELD_OP
+	AML_INDEX_FIELD_OP
+	AML_BANK_FIELD_OP
+	AML_NAME_OP
+	AML_ALIAS_OP
+	AML_MUTEX_OP
+	AML_EVENT_OP
+	AML_REGION_OP
+	AML_INT_NAMEDFIELD_OP
+
+  Opcodes that have an associated namespace node (AML_NSNODE flag)
+
+	AML_SCOPE_OP
+	AML_DEVICE_OP
+	AML_THERMAL_ZONE_OP
+	AML_METHOD_OP
+	AML_POWER_RES_OP
+	AML_PROCESSOR_OP
+	AML_NAME_OP
+	AML_ALIAS_OP
+	AML_MUTEX_OP
+	AML_EVENT_OP
+	AML_REGION_OP
+	AML_CREATE_FIELD_OP
+	AML_CREATE_BIT_FIELD_OP
+	AML_CREATE_BYTE_FIELD_OP
+	AML_CREATE_WORD_FIELD_OP
+	AML_CREATE_DWORD_FIELD_OP
+	AML_CREATE_QWORD_FIELD_OP
+	AML_INT_NAMEDFIELD_OP
+	AML_INT_METHODCALL_OP
+	AML_INT_NAMEPATH_OP
+
+  Opcodes that define named ACPI objects (AML_NAMED flag)
+
+	AML_SCOPE_OP
+	AML_DEVICE_OP
+	AML_THERMAL_ZONE_OP
+	AML_METHOD_OP
+	AML_POWER_RES_OP
+	AML_PROCESSOR_OP
+	AML_NAME_OP
+	AML_ALIAS_OP
+	AML_MUTEX_OP
+	AML_EVENT_OP
+	AML_REGION_OP
+	AML_INT_NAMEDFIELD_OP
+
+  Opcodes that contain executable AML as part of the definition that
+  must be deferred until needed
+
+	AML_METHOD_OP
+	AML_VAR_PACKAGE_OP
+	AML_CREATE_FIELD_OP
+	AML_CREATE_BIT_FIELD_OP
+	AML_CREATE_BYTE_FIELD_OP
+	AML_CREATE_WORD_FIELD_OP
+	AML_CREATE_DWORD_FIELD_OP
+	AML_CREATE_QWORD_FIELD_OP
+	AML_REGION_OP
+	AML_BUFFER_OP
+
+  Field opcodes
+
+	AML_CREATE_FIELD_OP
+	AML_FIELD_OP
+	AML_INDEX_FIELD_OP
+	AML_BANK_FIELD_OP
+
+  Field "Create" opcodes
+
+	AML_CREATE_FIELD_OP
+	AML_CREATE_BIT_FIELD_OP
+	AML_CREATE_BYTE_FIELD_OP
+	AML_CREATE_WORD_FIELD_OP
+	AML_CREATE_DWORD_FIELD_OP
+	AML_CREATE_QWORD_FIELD_OP
+
+******************************************************************************/
+
+
+/*
+ * Master Opcode information table.  A summary of everything we know about each opcode, all in one place.
+ */
+
+
+const struct acpi_opcode_info     acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
+{
+/*! [Begin] no source code translation */
+/* Index           Name                 Parser Args               Interpreter Args                ObjectType                    Class                      Type                  Flags */
+
+/* 00 */ ACPI_OP ("Zero",               ARGP_ZERO_OP,              ARGI_ZERO_OP,               ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
+/* 01 */ ACPI_OP ("One",                ARGP_ONE_OP,               ARGI_ONE_OP,                ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
+/* 02 */ ACPI_OP ("Alias",              ARGP_ALIAS_OP,             ARGI_ALIAS_OP,              ACPI_TYPE_LOCAL_ALIAS,       AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_SIMPLE,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 03 */ ACPI_OP ("Name",               ARGP_NAME_OP,              ARGI_NAME_OP,               ACPI_TYPE_ANY,               AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_COMPLEX,   AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 04 */ ACPI_OP ("ByteConst",          ARGP_BYTE_OP,              ARGI_BYTE_OP,               ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         AML_CONSTANT),
+/* 05 */ ACPI_OP ("WordConst",          ARGP_WORD_OP,              ARGI_WORD_OP,               ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         AML_CONSTANT),
+/* 06 */ ACPI_OP ("DwordConst",         ARGP_DWORD_OP,             ARGI_DWORD_OP,              ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         AML_CONSTANT),
+/* 07 */ ACPI_OP ("String",             ARGP_STRING_OP,            ARGI_STRING_OP,             ACPI_TYPE_STRING,            AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         AML_CONSTANT),
+/* 08 */ ACPI_OP ("Scope",              ARGP_SCOPE_OP,             ARGI_SCOPE_OP,              ACPI_TYPE_LOCAL_SCOPE,       AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_NO_OBJ,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 09 */ ACPI_OP ("Buffer",             ARGP_BUFFER_OP,            ARGI_BUFFER_OP,             ACPI_TYPE_BUFFER,            AML_CLASS_CREATE,          AML_TYPE_CREATE_OBJECT,   AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
+/* 0A */ ACPI_OP ("Package",            ARGP_PACKAGE_OP,           ARGI_PACKAGE_OP,            ACPI_TYPE_PACKAGE,           AML_CLASS_CREATE,          AML_TYPE_CREATE_OBJECT,   AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
+/* 0B */ ACPI_OP ("Method",             ARGP_METHOD_OP,            ARGI_METHOD_OP,             ACPI_TYPE_METHOD,            AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_COMPLEX,   AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
+/* 0C */ ACPI_OP ("Local0",             ARGP_LOCAL0,               ARGI_LOCAL0,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 0D */ ACPI_OP ("Local1",             ARGP_LOCAL1,               ARGI_LOCAL1,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 0E */ ACPI_OP ("Local2",             ARGP_LOCAL2,               ARGI_LOCAL2,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 0F */ ACPI_OP ("Local3",             ARGP_LOCAL3,               ARGI_LOCAL3,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 10 */ ACPI_OP ("Local4",             ARGP_LOCAL4,               ARGI_LOCAL4,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 11 */ ACPI_OP ("Local5",             ARGP_LOCAL5,               ARGI_LOCAL5,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 12 */ ACPI_OP ("Local6",             ARGP_LOCAL6,               ARGI_LOCAL6,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 13 */ ACPI_OP ("Local7",             ARGP_LOCAL7,               ARGI_LOCAL7,                ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LOCAL_VARIABLE,  0),
+/* 14 */ ACPI_OP ("Arg0",               ARGP_ARG0,                 ARGI_ARG0,                  ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_METHOD_ARGUMENT, 0),
+/* 15 */ ACPI_OP ("Arg1",               ARGP_ARG1,                 ARGI_ARG1,                  ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_METHOD_ARGUMENT, 0),
+/* 16 */ ACPI_OP ("Arg2",               ARGP_ARG2,                 ARGI_ARG2,                  ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_METHOD_ARGUMENT, 0),
+/* 17 */ ACPI_OP ("Arg3",               ARGP_ARG3,                 ARGI_ARG3,                  ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_METHOD_ARGUMENT, 0),
+/* 18 */ ACPI_OP ("Arg4",               ARGP_ARG4,                 ARGI_ARG4,                  ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_METHOD_ARGUMENT, 0),
+/* 19 */ ACPI_OP ("Arg5",               ARGP_ARG5,                 ARGI_ARG5,                  ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_METHOD_ARGUMENT, 0),
+/* 1A */ ACPI_OP ("Arg6",               ARGP_ARG6,                 ARGI_ARG6,                  ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_METHOD_ARGUMENT, 0),
+/* 1B */ ACPI_OP ("Store",              ARGP_STORE_OP,             ARGI_STORE_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R),
+/* 1C */ ACPI_OP ("RefOf",              ARGP_REF_OF_OP,            ARGI_REF_OF_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R),
+/* 1D */ ACPI_OP ("Add",                ARGP_ADD_OP,               ARGI_ADD_OP,                ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 1E */ ACPI_OP ("Concatenate",        ARGP_CONCAT_OP,            ARGI_CONCAT_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 1F */ ACPI_OP ("Subtract",           ARGP_SUBTRACT_OP,          ARGI_SUBTRACT_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 20 */ ACPI_OP ("Increment",          ARGP_INCREMENT_OP,         ARGI_INCREMENT_OP,          ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 21 */ ACPI_OP ("Decrement",          ARGP_DECREMENT_OP,         ARGI_DECREMENT_OP,          ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 22 */ ACPI_OP ("Multiply",           ARGP_MULTIPLY_OP,          ARGI_MULTIPLY_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 23 */ ACPI_OP ("Divide",             ARGP_DIVIDE_OP,            ARGI_DIVIDE_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_2T_1R,   AML_FLAGS_EXEC_2A_2T_1R | AML_CONSTANT),
+/* 24 */ ACPI_OP ("ShiftLeft",          ARGP_SHIFT_LEFT_OP,        ARGI_SHIFT_LEFT_OP,         ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 25 */ ACPI_OP ("ShiftRight",         ARGP_SHIFT_RIGHT_OP,       ARGI_SHIFT_RIGHT_OP,        ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 26 */ ACPI_OP ("And",                ARGP_BIT_AND_OP,           ARGI_BIT_AND_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 27 */ ACPI_OP ("NAnd",               ARGP_BIT_NAND_OP,          ARGI_BIT_NAND_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 28 */ ACPI_OP ("Or",                 ARGP_BIT_OR_OP,            ARGI_BIT_OR_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 29 */ ACPI_OP ("NOr",                ARGP_BIT_NOR_OP,           ARGI_BIT_NOR_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 2A */ ACPI_OP ("XOr",                ARGP_BIT_XOR_OP,           ARGI_BIT_XOR_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
+/* 2B */ ACPI_OP ("Not",                ARGP_BIT_NOT_OP,           ARGI_BIT_NOT_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2C */ ACPI_OP ("FindSetLeftBit",     ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP,  ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2D */ ACPI_OP ("FindSetRightBit",    ARGP_FIND_SET_RIGHT_BIT_OP,ARGI_FIND_SET_RIGHT_BIT_OP, ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 2E */ ACPI_OP ("DerefOf",            ARGP_DEREF_OF_OP,          ARGI_DEREF_OF_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R),
+/* 2F */ ACPI_OP ("Notify",             ARGP_NOTIFY_OP,            ARGI_NOTIFY_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_0R,   AML_FLAGS_EXEC_2A_0T_0R),
+/* 30 */ ACPI_OP ("SizeOf",             ARGP_SIZE_OF_OP,           ARGI_SIZE_OF_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
+/* 31 */ ACPI_OP ("Index",              ARGP_INDEX_OP,             ARGI_INDEX_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R),
+/* 32 */ ACPI_OP ("Match",              ARGP_MATCH_OP,             ARGI_MATCH_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_6A_0T_1R,   AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
+/* 33 */ ACPI_OP ("CreateDWordField",   ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 34 */ ACPI_OP ("CreateWordField",    ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP,  ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 35 */ ACPI_OP ("CreateByteField",    ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP,  ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 36 */ ACPI_OP ("CreateBitField",     ARGP_CREATE_BIT_FIELD_OP,  ARGI_CREATE_BIT_FIELD_OP,   ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 37 */ ACPI_OP ("ObjectType",         ARGP_TYPE_OP,              ARGI_TYPE_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
+/* 38 */ ACPI_OP ("LAnd",               ARGP_LAND_OP,              ARGI_LAND_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
+/* 39 */ ACPI_OP ("LOr",                ARGP_LOR_OP,               ARGI_LOR_OP,                ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
+/* 3A */ ACPI_OP ("LNot",               ARGP_LNOT_OP,              ARGI_LNOT_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
+/* 3B */ ACPI_OP ("LEqual",             ARGP_LEQUAL_OP,            ARGI_LEQUAL_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3C */ ACPI_OP ("LGreater",           ARGP_LGREATER_OP,          ARGI_LGREATER_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3D */ ACPI_OP ("LLess",              ARGP_LLESS_OP,             ARGI_LLESS_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 3E */ ACPI_OP ("If",                 ARGP_IF_OP,                ARGI_IF_OP,                 ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         AML_HAS_ARGS),
+/* 3F */ ACPI_OP ("Else",               ARGP_ELSE_OP,              ARGI_ELSE_OP,               ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         AML_HAS_ARGS),
+/* 40 */ ACPI_OP ("While",              ARGP_WHILE_OP,             ARGI_WHILE_OP,              ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         AML_HAS_ARGS),
+/* 41 */ ACPI_OP ("Noop",               ARGP_NOOP_OP,              ARGI_NOOP_OP,               ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         0),
+/* 42 */ ACPI_OP ("Return",             ARGP_RETURN_OP,            ARGI_RETURN_OP,             ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         AML_HAS_ARGS),
+/* 43 */ ACPI_OP ("Break",              ARGP_BREAK_OP,             ARGI_BREAK_OP,              ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         0),
+/* 44 */ ACPI_OP ("BreakPoint",         ARGP_BREAK_POINT_OP,       ARGI_BREAK_POINT_OP,        ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         0),
+/* 45 */ ACPI_OP ("Ones",               ARGP_ONES_OP,              ARGI_ONES_OP,               ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        AML_CONSTANT),
+
+/* Prefixed opcodes (Two-byte opcodes with a prefix op) */
+
+/* 46 */ ACPI_OP ("Mutex",              ARGP_MUTEX_OP,             ARGI_MUTEX_OP,              ACPI_TYPE_MUTEX,             AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_SIMPLE,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 47 */ ACPI_OP ("Event",              ARGP_EVENT_OP,             ARGI_EVENT_OP,              ACPI_TYPE_EVENT,             AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_SIMPLE,    AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ),
+/* 48 */ ACPI_OP ("CondRefOf",          ARGP_COND_REF_OF_OP,       ARGI_COND_REF_OF_OP,        ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R),
+/* 49 */ ACPI_OP ("CreateField",        ARGP_CREATE_FIELD_OP,      ARGI_CREATE_FIELD_OP,       ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_FIELD | AML_CREATE),
+/* 4A */ ACPI_OP ("Load",               ARGP_LOAD_OP,              ARGI_LOAD_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_0R,   AML_FLAGS_EXEC_1A_1T_0R),
+/* 4B */ ACPI_OP ("Stall",              ARGP_STALL_OP,             ARGI_STALL_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_0R,   AML_FLAGS_EXEC_1A_0T_0R),
+/* 4C */ ACPI_OP ("Sleep",              ARGP_SLEEP_OP,             ARGI_SLEEP_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_0R,   AML_FLAGS_EXEC_1A_0T_0R),
+/* 4D */ ACPI_OP ("Acquire",            ARGP_ACQUIRE_OP,           ARGI_ACQUIRE_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R),
+/* 4E */ ACPI_OP ("Signal",             ARGP_SIGNAL_OP,            ARGI_SIGNAL_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_0R,   AML_FLAGS_EXEC_1A_0T_0R),
+/* 4F */ ACPI_OP ("Wait",               ARGP_WAIT_OP,              ARGI_WAIT_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_1R,   AML_FLAGS_EXEC_2A_0T_1R),
+/* 50 */ ACPI_OP ("Reset",              ARGP_RESET_OP,             ARGI_RESET_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_0R,   AML_FLAGS_EXEC_1A_0T_0R),
+/* 51 */ ACPI_OP ("Release",            ARGP_RELEASE_OP,           ARGI_RELEASE_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_0R,   AML_FLAGS_EXEC_1A_0T_0R),
+/* 52 */ ACPI_OP ("FromBCD",            ARGP_FROM_BCD_OP,          ARGI_FROM_BCD_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 53 */ ACPI_OP ("ToBCD",              ARGP_TO_BCD_OP,            ARGI_TO_BCD_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 54 */ ACPI_OP ("Unload",             ARGP_UNLOAD_OP,            ARGI_UNLOAD_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_0R,   AML_FLAGS_EXEC_1A_0T_0R),
+/* 55 */ ACPI_OP ("Revision",           ARGP_REVISION_OP,          ARGI_REVISION_OP,           ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        0),
+/* 56 */ ACPI_OP ("Debug",              ARGP_DEBUG_OP,             ARGI_DEBUG_OP,              ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_CONSTANT,        0),
+/* 57 */ ACPI_OP ("Fatal",              ARGP_FATAL_OP,             ARGI_FATAL_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_3A_0T_0R,   AML_FLAGS_EXEC_3A_0T_0R),
+/* 58 */ ACPI_OP ("OperationRegion",    ARGP_REGION_OP,            ARGI_REGION_OP,             ACPI_TYPE_REGION,            AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_COMPLEX,   AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED | AML_DEFER),
+/* 59 */ ACPI_OP ("Field",              ARGP_FIELD_OP,             ARGI_FIELD_OP,              ACPI_TYPE_ANY,               AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_FIELD,     AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+/* 5A */ ACPI_OP ("Device",             ARGP_DEVICE_OP,            ARGI_DEVICE_OP,             ACPI_TYPE_DEVICE,            AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_NO_OBJ,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5B */ ACPI_OP ("Processor",          ARGP_PROCESSOR_OP,         ARGI_PROCESSOR_OP,          ACPI_TYPE_PROCESSOR,         AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_SIMPLE,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5C */ ACPI_OP ("PowerResource",      ARGP_POWER_RES_OP,         ARGI_POWER_RES_OP,          ACPI_TYPE_POWER,             AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_SIMPLE,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5D */ ACPI_OP ("ThermalZone",        ARGP_THERMAL_ZONE_OP,      ARGI_THERMAL_ZONE_OP,       ACPI_TYPE_THERMAL,           AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_NO_OBJ,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 5E */ ACPI_OP ("IndexField",         ARGP_INDEX_FIELD_OP,       ARGI_INDEX_FIELD_OP,        ACPI_TYPE_ANY,               AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_FIELD,     AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+/* 5F */ ACPI_OP ("BankField",          ARGP_BANK_FIELD_OP,        ARGI_BANK_FIELD_OP,         ACPI_TYPE_ANY,               AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_FIELD,     AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
+
+/* Internal opcodes that map to invalid AML opcodes */
+
+/* 60 */ ACPI_OP ("LNotEqual",          ARGP_LNOTEQUAL_OP,         ARGI_LNOTEQUAL_OP,          ACPI_TYPE_ANY,               AML_CLASS_INTERNAL,        AML_TYPE_BOGUS,           AML_HAS_ARGS | AML_CONSTANT),
+/* 61 */ ACPI_OP ("LLessEqual",         ARGP_LLESSEQUAL_OP,        ARGI_LLESSEQUAL_OP,         ACPI_TYPE_ANY,               AML_CLASS_INTERNAL,        AML_TYPE_BOGUS,           AML_HAS_ARGS | AML_CONSTANT),
+/* 62 */ ACPI_OP ("LGreaterEqual",      ARGP_LGREATEREQUAL_OP,     ARGI_LGREATEREQUAL_OP,      ACPI_TYPE_ANY,               AML_CLASS_INTERNAL,        AML_TYPE_BOGUS,           AML_HAS_ARGS | AML_CONSTANT),
+/* 63 */ ACPI_OP ("-NamePath-",         ARGP_NAMEPATH_OP,          ARGI_NAMEPATH_OP,           ACPI_TYPE_LOCAL_REFERENCE,   AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         AML_NSOBJECT | AML_NSNODE ),
+/* 64 */ ACPI_OP ("-MethodCall-",       ARGP_METHODCALL_OP,        ARGI_METHODCALL_OP,         ACPI_TYPE_METHOD,            AML_CLASS_METHOD_CALL,     AML_TYPE_METHOD_CALL,     AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE),
+/* 65 */ ACPI_OP ("-ByteList-",         ARGP_BYTELIST_OP,          ARGI_BYTELIST_OP,           ACPI_TYPE_ANY,               AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         0),
+/* 66 */ ACPI_OP ("-ReservedField-",    ARGP_RESERVEDFIELD_OP,     ARGI_RESERVEDFIELD_OP,      ACPI_TYPE_ANY,               AML_CLASS_INTERNAL,        AML_TYPE_BOGUS,           0),
+/* 67 */ ACPI_OP ("-NamedField-",       ARGP_NAMEDFIELD_OP,        ARGI_NAMEDFIELD_OP,         ACPI_TYPE_ANY,               AML_CLASS_INTERNAL,        AML_TYPE_BOGUS,           AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED ),
+/* 68 */ ACPI_OP ("-AccessField-",      ARGP_ACCESSFIELD_OP,       ARGI_ACCESSFIELD_OP,        ACPI_TYPE_ANY,               AML_CLASS_INTERNAL,        AML_TYPE_BOGUS,           0),
+/* 69 */ ACPI_OP ("-StaticString",      ARGP_STATICSTRING_OP,      ARGI_STATICSTRING_OP,       ACPI_TYPE_ANY,               AML_CLASS_INTERNAL,        AML_TYPE_BOGUS,           0),
+/* 6A */ ACPI_OP ("-Return Value-",     ARG_NONE,                  ARG_NONE,                   ACPI_TYPE_ANY,               AML_CLASS_RETURN_VALUE,    AML_TYPE_RETURN,          AML_HAS_ARGS | AML_HAS_RETVAL),
+/* 6B */ ACPI_OP ("-UNKNOWN_OP-",       ARG_NONE,                  ARG_NONE,                   ACPI_TYPE_INVALID,           AML_CLASS_UNKNOWN,         AML_TYPE_BOGUS,           AML_HAS_ARGS),
+/* 6C */ ACPI_OP ("-ASCII_ONLY-",       ARG_NONE,                  ARG_NONE,                   ACPI_TYPE_ANY,               AML_CLASS_ASCII,           AML_TYPE_BOGUS,           AML_HAS_ARGS),
+/* 6D */ ACPI_OP ("-PREFIX_ONLY-",      ARG_NONE,                  ARG_NONE,                   ACPI_TYPE_ANY,               AML_CLASS_PREFIX,          AML_TYPE_BOGUS,           AML_HAS_ARGS),
+
+/* ACPI 2.0 opcodes */
+
+/* 6E */ ACPI_OP ("QwordConst",         ARGP_QWORD_OP,             ARGI_QWORD_OP,              ACPI_TYPE_INTEGER,           AML_CLASS_ARGUMENT,        AML_TYPE_LITERAL,         AML_CONSTANT),
+/* 6F */ ACPI_OP ("Package /*Var*/",    ARGP_VAR_PACKAGE_OP,       ARGI_VAR_PACKAGE_OP,        ACPI_TYPE_PACKAGE,           AML_CLASS_CREATE,          AML_TYPE_CREATE_OBJECT,   AML_HAS_ARGS | AML_DEFER),
+/* 70 */ ACPI_OP ("ConcatenateResTemplate", ARGP_CONCAT_RES_OP,    ARGI_CONCAT_RES_OP,         ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 71 */ ACPI_OP ("Mod",                ARGP_MOD_OP,               ARGI_MOD_OP,                ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 72 */ ACPI_OP ("CreateQWordField",   ARGP_CREATE_QWORD_FIELD_OP,ARGI_CREATE_QWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
+/* 73 */ ACPI_OP ("ToBuffer",           ARGP_TO_BUFFER_OP,         ARGI_TO_BUFFER_OP,          ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 74 */ ACPI_OP ("ToDecimalString",    ARGP_TO_DEC_STR_OP,        ARGI_TO_DEC_STR_OP,         ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 75 */ ACPI_OP ("ToHexString",        ARGP_TO_HEX_STR_OP,        ARGI_TO_HEX_STR_OP,         ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 76 */ ACPI_OP ("ToInteger",          ARGP_TO_INTEGER_OP,        ARGI_TO_INTEGER_OP,         ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
+/* 77 */ ACPI_OP ("ToString",           ARGP_TO_STRING_OP,         ARGI_TO_STRING_OP,          ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 78 */ ACPI_OP ("CopyObject",         ARGP_COPY_OP,              ARGI_COPY_OP,               ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_1T_1R,   AML_FLAGS_EXEC_1A_1T_1R),
+/* 79 */ ACPI_OP ("Mid",                ARGP_MID_OP,               ARGI_MID_OP,                ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_3A_1T_1R,   AML_FLAGS_EXEC_3A_1T_1R | AML_CONSTANT),
+/* 7A */ ACPI_OP ("Continue",           ARGP_CONTINUE_OP,          ARGI_CONTINUE_OP,           ACPI_TYPE_ANY,               AML_CLASS_CONTROL,         AML_TYPE_CONTROL,         0),
+/* 7B */ ACPI_OP ("LoadTable",          ARGP_LOAD_TABLE_OP,        ARGI_LOAD_TABLE_OP,         ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_6A_0T_1R,   AML_FLAGS_EXEC_6A_0T_1R),
+/* 7C */ ACPI_OP ("DataTableRegion",    ARGP_DATA_REGION_OP,       ARGI_DATA_REGION_OP,        ACPI_TYPE_REGION,            AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_SIMPLE,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
+/* 7D */ ACPI_OP ("[EvalSubTree]",      ARGP_SCOPE_OP,             ARGI_SCOPE_OP,              ACPI_TYPE_ANY,               AML_CLASS_NAMED_OBJECT,    AML_TYPE_NAMED_NO_OBJ,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE),
+
+/* ACPI 3.0 opcodes */
+
+/* 7E */ ACPI_OP ("Timer",              ARGP_TIMER_OP,             ARGI_TIMER_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_0A_0T_1R,   AML_FLAGS_EXEC_0A_0T_1R)
+
+/*! [End] no source code translation !*/
+};
+
+/*
+ * This table is directly indexed by the opcodes, and returns an
+ * index into the table above
+ */
+static const u8 acpi_gbl_short_op_index[256] =
+{
+/*              0     1     2     3     4     5     6     7  */
+/*              8     9     A     B     C     D     E     F  */
+/* 0x00 */	0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
+/* 0x08 */	0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
+/* 0x10 */	0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
+/* 0x18 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x20 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x28 */	_UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
+/* 0x30 */	0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
+/* 0x38 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */	_UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x48 */	_ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x50 */	_ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x58 */	_ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
+/* 0x60 */	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+/* 0x68 */	0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
+/* 0x70 */	0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
+/* 0x78 */	0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+/* 0x80 */	0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
+/* 0x88 */	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
+/* 0x90 */	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
+/* 0x98 */	0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
+/* 0xA0 */	0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
+/* 0xA8 */	0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xB8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xC8 */	_UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
+/* 0xD0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xD8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xE8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF0 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0xF8 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
+};
+
+/*
+ * This table is indexed by the second opcode of the extended opcode
+ * pair.  It returns an index into the opcode table (acpi_gbl_aml_op_info)
+ */
+static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] =
+{
+/*              0     1     2     3     4     5     6     7  */
+/*              8     9     A     B     C     D     E     F  */
+/* 0x00 */	_UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x08 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x10 */	_UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
+/* 0x18 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
+/* 0x20 */	0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+/* 0x28 */	0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x30 */	0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
+/* 0x38 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x48 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x50 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x58 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x60 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x68 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x70 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x78 */	_UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x80 */	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+/* 0x88 */	0x7C,
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_opcode_info
+ *
+ * PARAMETERS:  Opcode              - The AML opcode
+ *
+ * RETURN:      A pointer to the info about the opcode.  NULL if the opcode was
+ *              not found in the table.
+ *
+ * DESCRIPTION: Find AML opcode description based on the opcode.
+ *              NOTE: This procedure must ALWAYS return a valid pointer!
+ *
+ ******************************************************************************/
+
+const struct acpi_opcode_info *
+acpi_ps_get_opcode_info (
+	u16                             opcode)
+{
+	ACPI_FUNCTION_NAME ("ps_get_opcode_info");
+
+
+	/*
+	 * Detect normal 8-bit opcode or extended 16-bit opcode
+	 */
+	switch ((u8) (opcode >> 8)) {
+	case 0:
+
+		/* Simple (8-bit) opcode: 0-255, can't index beyond table  */
+
+		return (&acpi_gbl_aml_op_info [acpi_gbl_short_op_index [(u8) opcode]]);
+
+	case AML_EXTOP:
+
+		/* Extended (16-bit, prefix+opcode) opcode */
+
+		if (((u8) opcode) <= MAX_EXTENDED_OPCODE) {
+			return (&acpi_gbl_aml_op_info [acpi_gbl_long_op_index [(u8) opcode]]);
+		}
+
+		/* Else fall through to error case below */
+		/*lint -fallthrough */
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown AML opcode [%4.4X]\n", opcode));
+		break;
+	}
+
+
+	/* Default is "unknown opcode" */
+
+	return (&acpi_gbl_aml_op_info [_UNK]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_opcode_name
+ *
+ * PARAMETERS:  Opcode              - The AML opcode
+ *
+ * RETURN:      A pointer to the name of the opcode (ASCII String)
+ *              Note: Never returns NULL.
+ *
+ * DESCRIPTION: Translate an opcode into a human-readable string
+ *
+ ******************************************************************************/
+
+char *
+acpi_ps_get_opcode_name (
+	u16                             opcode)
+{
+#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
+
+	const struct acpi_opcode_info   *op;
+
+
+	op = acpi_ps_get_opcode_info (opcode);
+
+	/* Always guaranteed to return a valid pointer */
+
+	return (op->name);
+
+#else
+	return ("AE_NOT_CONFIGURED");
+
+#endif
+}
+
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
new file mode 100644
index 0000000..e79edb5
--- /dev/null
+++ b/drivers/acpi/parser/psparse.c
@@ -0,0 +1,1266 @@
+/******************************************************************************
+ *
+ * Module Name: psparse - Parser top level AML parse routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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.
+ */
+
+
+/*
+ * Parse the AML and build an operation tree as most interpreters,
+ * like Perl, do.  Parsing is done by hand rather than with a YACC
+ * generated parser to tightly constrain stack and dynamic memory
+ * usage.  At the same time, parsing is kept flexible and the code
+ * fairly compact by parsing based on a list of AML opcode
+ * templates in aml_op_info[]
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("psparse")
+
+
+static u32                          acpi_gbl_depth = 0;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_opcode_size
+ *
+ * PARAMETERS:  Opcode          - An AML opcode
+ *
+ * RETURN:      Size of the opcode, in bytes (1 or 2)
+ *
+ * DESCRIPTION: Get the size of the current opcode.
+ *
+ ******************************************************************************/
+
+u32
+acpi_ps_get_opcode_size (
+	u32                             opcode)
+{
+
+	/* Extended (2-byte) opcode if > 255 */
+
+	if (opcode > 0x00FF) {
+		return (2);
+	}
+
+	/* Otherwise, just a single byte opcode */
+
+	return (1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_peek_opcode
+ *
+ * PARAMETERS:  parser_state        - A parser state object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
+ *
+ ******************************************************************************/
+
+u16
+acpi_ps_peek_opcode (
+	struct acpi_parse_state         *parser_state)
+{
+	u8                              *aml;
+	u16                             opcode;
+
+
+	aml = parser_state->aml;
+	opcode = (u16) ACPI_GET8 (aml);
+
+
+	if (opcode == AML_EXTOP) {
+		/* Extended opcode */
+
+		aml++;
+		opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml));
+	}
+
+	return (opcode);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_complete_this_op
+ *
+ * PARAMETERS:  walk_state      - Current State
+ *              Op              - Op to complete
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Perform any cleanup at the completion of an Op.
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_complete_this_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op)
+{
+	union acpi_parse_object         *prev;
+	union acpi_parse_object         *next;
+	const struct acpi_opcode_info   *parent_info;
+	union acpi_parse_object         *replacement_op = NULL;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_complete_this_op", op);
+
+
+	/* Check for null Op, can happen if AML code is corrupt */
+
+	if (!op) {
+		return_VOID;
+	}
+
+	/* Delete this op and the subtree below it if asked to */
+
+	if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
+		 (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
+		return_VOID;
+	}
+
+	/* Make sure that we only delete this subtree */
+
+	if (op->common.parent) {
+		/*
+		 * Check if we need to replace the operator and its subtree
+		 * with a return value op (placeholder op)
+		 */
+		parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
+
+		switch (parent_info->class) {
+		case AML_CLASS_CONTROL:
+			break;
+
+		case AML_CLASS_CREATE:
+
+			/*
+			 * These opcodes contain term_arg operands. The current
+			 * op must be replaced by a placeholder return op
+			 */
+			replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
+			if (!replacement_op) {
+				goto cleanup;
+			}
+			break;
+
+		case AML_CLASS_NAMED_OBJECT:
+
+			/*
+			 * These opcodes contain term_arg operands. The current
+			 * op must be replaced by a placeholder return op
+			 */
+			if ((op->common.parent->common.aml_opcode == AML_REGION_OP)      ||
+				(op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
+				(op->common.parent->common.aml_opcode == AML_BUFFER_OP)      ||
+				(op->common.parent->common.aml_opcode == AML_PACKAGE_OP)     ||
+				(op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
+				replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
+				if (!replacement_op) {
+					goto cleanup;
+				}
+			}
+
+			if ((op->common.parent->common.aml_opcode == AML_NAME_OP) &&
+				(walk_state->descending_callback != acpi_ds_exec_begin_op)) {
+				if ((op->common.aml_opcode == AML_BUFFER_OP) ||
+					(op->common.aml_opcode == AML_PACKAGE_OP) ||
+					(op->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
+					replacement_op = acpi_ps_alloc_op (op->common.aml_opcode);
+					if (!replacement_op) {
+						goto cleanup;
+					}
+
+					replacement_op->named.data = op->named.data;
+					replacement_op->named.length = op->named.length;
+				}
+			}
+			break;
+
+		default:
+			replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
+			if (!replacement_op) {
+				goto cleanup;
+			}
+		}
+
+		/* We must unlink this op from the parent tree */
+
+		prev = op->common.parent->common.value.arg;
+		if (prev == op) {
+			/* This op is the first in the list */
+
+			if (replacement_op) {
+				replacement_op->common.parent       = op->common.parent;
+				replacement_op->common.value.arg    = NULL;
+				replacement_op->common.node         = op->common.node;
+				op->common.parent->common.value.arg = replacement_op;
+				replacement_op->common.next         = op->common.next;
+			}
+			else {
+				op->common.parent->common.value.arg = op->common.next;
+			}
+		}
+
+		/* Search the parent list */
+
+		else while (prev) {
+			/* Traverse all siblings in the parent's argument list */
+
+			next = prev->common.next;
+			if (next == op) {
+				if (replacement_op) {
+					replacement_op->common.parent   = op->common.parent;
+					replacement_op->common.value.arg = NULL;
+					replacement_op->common.node     = op->common.node;
+					prev->common.next               = replacement_op;
+					replacement_op->common.next     = op->common.next;
+					next = NULL;
+				}
+				else {
+					prev->common.next = op->common.next;
+					next = NULL;
+				}
+			}
+
+			prev = next;
+		}
+	}
+
+
+cleanup:
+
+	/* Now we can actually delete the subtree rooted at op */
+
+	acpi_ps_delete_parse_tree (op);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_next_parse_state
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Update the parser state based upon the return exception from
+ *              the parser callback.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_next_parse_state (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	acpi_status                     callback_status)
+{
+	struct acpi_parse_state         *parser_state = &walk_state->parser_state;
+	acpi_status                     status = AE_CTRL_PENDING;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_next_parse_state", op);
+
+
+	switch (callback_status) {
+	case AE_CTRL_TERMINATE:
+
+		/*
+		 * A control method was terminated via a RETURN statement.
+		 * The walk of this method is complete.
+		 */
+		parser_state->aml = parser_state->aml_end;
+		status = AE_CTRL_TERMINATE;
+		break;
+
+
+	case AE_CTRL_BREAK:
+
+		parser_state->aml = walk_state->aml_last_while;
+		walk_state->control_state->common.value = FALSE;
+		status = AE_CTRL_BREAK;
+		break;
+
+	case AE_CTRL_CONTINUE:
+
+
+		parser_state->aml = walk_state->aml_last_while;
+		status = AE_CTRL_CONTINUE;
+		break;
+
+	case AE_CTRL_PENDING:
+
+		parser_state->aml = walk_state->aml_last_while;
+		break;
+
+#if 0
+	case AE_CTRL_SKIP:
+
+		parser_state->aml = parser_state->scope->parse_scope.pkg_end;
+		status = AE_OK;
+		break;
+#endif
+
+	case AE_CTRL_TRUE:
+
+		/*
+		 * Predicate of an IF was true, and we are at the matching ELSE.
+		 * Just close out this package
+		 */
+		parser_state->aml = acpi_ps_get_next_package_end (parser_state);
+		break;
+
+
+	case AE_CTRL_FALSE:
+
+		/*
+		 * Either an IF/WHILE Predicate was false or we encountered a BREAK
+		 * opcode.  In both cases, we do not execute the rest of the
+		 * package;  We simply close out the parent (finishing the walk of
+		 * this branch of the tree) and continue execution at the parent
+		 * level.
+		 */
+		parser_state->aml = parser_state->scope->parse_scope.pkg_end;
+
+		/* In the case of a BREAK, just force a predicate (if any) to FALSE */
+
+		walk_state->control_state->common.value = FALSE;
+		status = AE_CTRL_END;
+		break;
+
+
+	case AE_CTRL_TRANSFER:
+
+		/*
+		 * A method call (invocation) -- transfer control
+		 */
+		status = AE_CTRL_TRANSFER;
+		walk_state->prev_op = op;
+		walk_state->method_call_op = op;
+		walk_state->method_call_node = (op->common.value.arg)->common.node;
+
+		/* Will return value (if any) be used by the caller? */
+
+		walk_state->return_used = acpi_ds_is_result_used (op, walk_state);
+		break;
+
+
+	default:
+		status = callback_status;
+		if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
+			status = AE_OK;
+		}
+		break;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_parse_loop
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
+ *              a tree of ops.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_parse_loop (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_parse_object         *op = NULL;     /* current op */
+	union acpi_parse_object         *arg = NULL;
+	union acpi_parse_object         *pre_op = NULL;
+	struct acpi_parse_state         *parser_state;
+	u8                              *aml_op_start = NULL;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state);
+
+	if (walk_state->descending_callback == NULL) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	parser_state = &walk_state->parser_state;
+	walk_state->arg_types = 0;
+
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+	if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
+		/* We are restarting a preempted control method */
+
+		if (acpi_ps_has_completed_scope (parser_state)) {
+			/*
+			 * We must check if a predicate to an IF or WHILE statement
+			 * was just completed
+			 */
+			if ((parser_state->scope->parse_scope.op) &&
+			   ((parser_state->scope->parse_scope.op->common.aml_opcode == AML_IF_OP) ||
+				(parser_state->scope->parse_scope.op->common.aml_opcode == AML_WHILE_OP)) &&
+				(walk_state->control_state) &&
+				(walk_state->control_state->common.state ==
+					ACPI_CONTROL_PREDICATE_EXECUTING)) {
+				/*
+				 * A predicate was just completed, get the value of the
+				 * predicate and branch based on that value
+				 */
+				walk_state->op = NULL;
+				status = acpi_ds_get_predicate_value (walk_state, ACPI_TO_POINTER (TRUE));
+				if (ACPI_FAILURE (status) &&
+					((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
+					if (status == AE_AML_NO_RETURN_VALUE) {
+						ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+							"Invoked method did not return a value, %s\n",
+							acpi_format_exception (status)));
+
+					}
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "get_predicate Failed, %s\n",
+						acpi_format_exception (status)));
+					return_ACPI_STATUS (status);
+				}
+
+				status = acpi_ps_next_parse_state (walk_state, op, status);
+			}
+
+			acpi_ps_pop_scope (parser_state, &op,
+				&walk_state->arg_types, &walk_state->arg_count);
+			ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
+		}
+		else if (walk_state->prev_op) {
+			/* We were in the middle of an op */
+
+			op = walk_state->prev_op;
+			walk_state->arg_types = walk_state->prev_arg_types;
+		}
+	}
+#endif
+
+	/*
+	 * Iterative parsing loop, while there is more aml to process:
+	 */
+	while ((parser_state->aml < parser_state->aml_end) || (op)) {
+		aml_op_start = parser_state->aml;
+		if (!op) {
+			/* Get the next opcode from the AML stream */
+
+			walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
+					   parser_state->aml_start);
+			walk_state->opcode   = acpi_ps_peek_opcode (parser_state);
+
+			/*
+			 * First cut to determine what we have found:
+			 * 1) A valid AML opcode
+			 * 2) A name string
+			 * 3) An unknown/invalid opcode
+			 */
+			walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
+			switch (walk_state->op_info->class) {
+			case AML_CLASS_ASCII:
+			case AML_CLASS_PREFIX:
+				/*
+				 * Starts with a valid prefix or ASCII char, this is a name
+				 * string.  Convert the bare name string to a namepath.
+				 */
+				walk_state->opcode = AML_INT_NAMEPATH_OP;
+				walk_state->arg_types = ARGP_NAMESTRING;
+				break;
+
+			case AML_CLASS_UNKNOWN:
+
+				/* The opcode is unrecognized.  Just skip unknown opcodes */
+
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Found unknown opcode %X at AML address %p offset %X, ignoring\n",
+					walk_state->opcode, parser_state->aml, walk_state->aml_offset));
+
+				ACPI_DUMP_BUFFER (parser_state->aml, 128);
+
+				/* Assume one-byte bad opcode */
+
+				parser_state->aml++;
+				continue;
+
+			default:
+
+				/* Found opcode info, this is a normal opcode */
+
+				parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode);
+				walk_state->arg_types = walk_state->op_info->parse_args;
+				break;
+			}
+
+			/* Create Op structure and append to parent's argument list */
+
+			if (walk_state->op_info->flags & AML_NAMED) {
+				/* Allocate a new pre_op if necessary */
+
+				if (!pre_op) {
+					pre_op = acpi_ps_alloc_op (walk_state->opcode);
+					if (!pre_op) {
+						status = AE_NO_MEMORY;
+						goto close_this_op;
+					}
+				}
+
+				pre_op->common.value.arg = NULL;
+				pre_op->common.aml_opcode = walk_state->opcode;
+
+				/*
+				 * Get and append arguments until we find the node that contains
+				 * the name (the type ARGP_NAME).
+				 */
+				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
+					  (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) {
+					status = acpi_ps_get_next_arg (walk_state, parser_state,
+							 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
+					if (ACPI_FAILURE (status)) {
+						goto close_this_op;
+					}
+
+					acpi_ps_append_arg (pre_op, arg);
+					INCREMENT_ARG_LIST (walk_state->arg_types);
+				}
+
+				/* Make sure that we found a NAME and didn't run out of arguments */
+
+				if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
+					status = AE_AML_NO_OPERAND;
+					goto close_this_op;
+				}
+
+				/* We know that this arg is a name, move to next arg */
+
+				INCREMENT_ARG_LIST (walk_state->arg_types);
+
+				/*
+				 * Find the object.  This will either insert the object into
+				 * the namespace or simply look it up
+				 */
+				walk_state->op = NULL;
+
+				status = walk_state->descending_callback (walk_state, &op);
+				if (ACPI_FAILURE (status)) {
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n",
+							acpi_format_exception (status)));
+					goto close_this_op;
+				}
+
+				if (op == NULL) {
+					continue;
+				}
+
+				status = acpi_ps_next_parse_state (walk_state, op, status);
+				if (status == AE_CTRL_PENDING) {
+					status = AE_OK;
+					goto close_this_op;
+				}
+
+				if (ACPI_FAILURE (status)) {
+					goto close_this_op;
+				}
+
+				acpi_ps_append_arg (op, pre_op->common.value.arg);
+				acpi_gbl_depth++;
+
+				if (op->common.aml_opcode == AML_REGION_OP) {
+					/*
+					 * Defer final parsing of an operation_region body,
+					 * because we don't have enough info in the first pass
+					 * to parse it correctly (i.e., there may be method
+					 * calls within the term_arg elements of the body.)
+					 *
+					 * However, we must continue parsing because
+					 * the opregion is not a standalone package --
+					 * we don't know where the end is at this point.
+					 *
+					 * (Length is unknown until parse of the body complete)
+					 */
+					op->named.data    = aml_op_start;
+					op->named.length  = 0;
+				}
+			}
+			else {
+				/* Not a named opcode, just allocate Op and append to parent */
+
+				walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
+				op = acpi_ps_alloc_op (walk_state->opcode);
+				if (!op) {
+					status = AE_NO_MEMORY;
+					goto close_this_op;
+				}
+
+				if (walk_state->op_info->flags & AML_CREATE) {
+					/*
+					 * Backup to beginning of create_xXXfield declaration
+					 * body_length is unknown until we parse the body
+					 */
+					op->named.data    = aml_op_start;
+					op->named.length  = 0;
+				}
+
+				acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
+
+				if ((walk_state->descending_callback != NULL)) {
+					/*
+					 * Find the object.  This will either insert the object into
+					 * the namespace or simply look it up
+					 */
+					walk_state->op = op;
+
+					status = walk_state->descending_callback (walk_state, &op);
+					status = acpi_ps_next_parse_state (walk_state, op, status);
+					if (status == AE_CTRL_PENDING) {
+						status = AE_OK;
+						goto close_this_op;
+					}
+
+					if (ACPI_FAILURE (status)) {
+						goto close_this_op;
+					}
+				}
+			}
+
+			op->common.aml_offset = walk_state->aml_offset;
+
+			if (walk_state->op_info) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+					"Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n",
+					 (u32) op->common.aml_opcode, walk_state->op_info->name,
+					 op, parser_state->aml, op->common.aml_offset));
+			}
+		}
+
+
+		/* Start arg_count at zero because we don't know if there are any args yet */
+
+		walk_state->arg_count = 0;
+
+		if (walk_state->arg_types) /* Are there any arguments that must be processed? */ {
+			/* Get arguments */
+
+			switch (op->common.aml_opcode) {
+			case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
+			case AML_WORD_OP:       /* AML_WORDDATA_ARG */
+			case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
+			case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
+			case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
+
+				/* Fill in constant or string argument directly */
+
+				acpi_ps_get_next_simple_arg (parser_state,
+					GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
+				break;
+
+			case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
+
+				status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1);
+				if (ACPI_FAILURE (status)) {
+					goto close_this_op;
+				}
+
+				walk_state->arg_types = 0;
+				break;
+
+			default:
+
+				/* Op is not a constant or string, append each argument to the Op */
+
+				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
+						!walk_state->arg_count) {
+					walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
+							   parser_state->aml_start);
+					status = acpi_ps_get_next_arg (walk_state, parser_state,
+							 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
+					if (ACPI_FAILURE (status)) {
+						goto close_this_op;
+					}
+
+					if (arg) {
+						arg->common.aml_offset = walk_state->aml_offset;
+						acpi_ps_append_arg (op, arg);
+					}
+					INCREMENT_ARG_LIST (walk_state->arg_types);
+				}
+
+				/* Special processing for certain opcodes */
+
+				switch (op->common.aml_opcode) {
+				case AML_METHOD_OP:
+
+					/*
+					 * Skip parsing of control method
+					 * because we don't have enough info in the first pass
+					 * to parse it correctly.
+					 *
+					 * Save the length and address of the body
+					 */
+					op->named.data   = parser_state->aml;
+					op->named.length = (u32) (parser_state->pkg_end - parser_state->aml);
+
+					/* Skip body of method */
+
+					parser_state->aml   = parser_state->pkg_end;
+					walk_state->arg_count = 0;
+					break;
+
+				case AML_BUFFER_OP:
+				case AML_PACKAGE_OP:
+				case AML_VAR_PACKAGE_OP:
+
+					if ((op->common.parent) &&
+						(op->common.parent->common.aml_opcode == AML_NAME_OP) &&
+						(walk_state->descending_callback != acpi_ds_exec_begin_op)) {
+						/*
+						 * Skip parsing of Buffers and Packages
+						 * because we don't have enough info in the first pass
+						 * to parse them correctly.
+						 */
+						op->named.data   = aml_op_start;
+						op->named.length = (u32) (parser_state->pkg_end - aml_op_start);
+
+						/* Skip body */
+
+						parser_state->aml   = parser_state->pkg_end;
+						walk_state->arg_count = 0;
+					}
+					break;
+
+				case AML_WHILE_OP:
+
+					if (walk_state->control_state) {
+						walk_state->control_state->control.package_end = parser_state->pkg_end;
+					}
+					break;
+
+				default:
+
+					/* No action for all other opcodes */
+					break;
+				}
+				break;
+			}
+		}
+
+		/* Check for arguments that need to be processed */
+
+		if (walk_state->arg_count) {
+			/* There are arguments (complex ones), push Op and prepare for argument */
+
+			status = acpi_ps_push_scope (parser_state, op,
+					 walk_state->arg_types, walk_state->arg_count);
+			if (ACPI_FAILURE (status)) {
+				goto close_this_op;
+			}
+			op = NULL;
+			continue;
+		}
+
+		/* All arguments have been processed -- Op is complete, prepare for next */
+
+		walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+		if (walk_state->op_info->flags & AML_NAMED) {
+			if (acpi_gbl_depth) {
+				acpi_gbl_depth--;
+			}
+
+			if (op->common.aml_opcode == AML_REGION_OP) {
+				/*
+				 * Skip parsing of control method or opregion body,
+				 * because we don't have enough info in the first pass
+				 * to parse them correctly.
+				 *
+				 * Completed parsing an op_region declaration, we now
+				 * know the length.
+				 */
+				op->named.length = (u32) (parser_state->aml - op->named.data);
+			}
+		}
+
+		if (walk_state->op_info->flags & AML_CREATE) {
+			/*
+			 * Backup to beginning of create_xXXfield declaration (1 for
+			 * Opcode)
+			 *
+			 * body_length is unknown until we parse the body
+			 */
+			op->named.length = (u32) (parser_state->aml - op->named.data);
+		}
+
+		/* This op complete, notify the dispatcher */
+
+		if (walk_state->ascending_callback != NULL) {
+			walk_state->op    = op;
+			walk_state->opcode = op->common.aml_opcode;
+
+			status = walk_state->ascending_callback (walk_state);
+			status = acpi_ps_next_parse_state (walk_state, op, status);
+			if (status == AE_CTRL_PENDING) {
+				status = AE_OK;
+				goto close_this_op;
+			}
+		}
+
+
+close_this_op:
+		/*
+		 * Finished one argument of the containing scope
+		 */
+		parser_state->scope->parse_scope.arg_count--;
+
+		/* Close this Op (will result in parse subtree deletion) */
+
+		acpi_ps_complete_this_op (walk_state, op);
+		op = NULL;
+		if (pre_op) {
+			acpi_ps_free_op (pre_op);
+			pre_op = NULL;
+		}
+
+		switch (status) {
+		case AE_OK:
+			break;
+
+
+		case AE_CTRL_TRANSFER:
+
+			/*
+			 * We are about to transfer to a called method.
+			 */
+			walk_state->prev_op = op;
+			walk_state->prev_arg_types = walk_state->arg_types;
+			return_ACPI_STATUS (status);
+
+
+		case AE_CTRL_END:
+
+			acpi_ps_pop_scope (parser_state, &op,
+				&walk_state->arg_types, &walk_state->arg_count);
+
+			if (op) {
+				walk_state->op    = op;
+				walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+				walk_state->opcode = op->common.aml_opcode;
+
+				status = walk_state->ascending_callback (walk_state);
+				status = acpi_ps_next_parse_state (walk_state, op, status);
+
+				acpi_ps_complete_this_op (walk_state, op);
+				op = NULL;
+			}
+			status = AE_OK;
+			break;
+
+
+		case AE_CTRL_BREAK:
+		case AE_CTRL_CONTINUE:
+
+			/* Pop off scopes until we find the While */
+
+			while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
+			}
+
+			/* Close this iteration of the While loop */
+
+			walk_state->op    = op;
+			walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+			walk_state->opcode = op->common.aml_opcode;
+
+			status = walk_state->ascending_callback (walk_state);
+			status = acpi_ps_next_parse_state (walk_state, op, status);
+
+			acpi_ps_complete_this_op (walk_state, op);
+			op = NULL;
+
+			status = AE_OK;
+			break;
+
+
+		case AE_CTRL_TERMINATE:
+
+			status = AE_OK;
+
+			/* Clean up */
+			do {
+				if (op) {
+					acpi_ps_complete_this_op (walk_state, op);
+				}
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
+
+			} while (op);
+
+			return_ACPI_STATUS (status);
+
+
+		default:  /* All other non-AE_OK status */
+
+			do {
+				if (op) {
+					acpi_ps_complete_this_op (walk_state, op);
+				}
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
+
+			} while (op);
+
+
+			/*
+			 * TBD: Cleanup parse ops on error
+			 */
+#if 0
+			if (op == NULL) {
+				acpi_ps_pop_scope (parser_state, &op,
+					&walk_state->arg_types, &walk_state->arg_count);
+			}
+#endif
+			walk_state->prev_op = op;
+			walk_state->prev_arg_types = walk_state->arg_types;
+			return_ACPI_STATUS (status);
+		}
+
+		/* This scope complete? */
+
+		if (acpi_ps_has_completed_scope (parser_state)) {
+			acpi_ps_pop_scope (parser_state, &op,
+				&walk_state->arg_types, &walk_state->arg_count);
+			ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
+		}
+		else {
+			op = NULL;
+		}
+
+	} /* while parser_state->Aml */
+
+
+	/*
+	 * Complete the last Op (if not completed), and clear the scope stack.
+	 * It is easily possible to end an AML "package" with an unbounded number
+	 * of open scopes (such as when several ASL blocks are closed with
+	 * sequential closing braces).  We want to terminate each one cleanly.
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op));
+	do {
+		if (op) {
+			if (walk_state->ascending_callback != NULL) {
+				walk_state->op    = op;
+				walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+				walk_state->opcode = op->common.aml_opcode;
+
+				status = walk_state->ascending_callback (walk_state);
+				status = acpi_ps_next_parse_state (walk_state, op, status);
+				if (status == AE_CTRL_PENDING) {
+					status = AE_OK;
+					goto close_this_op;
+				}
+
+				if (status == AE_CTRL_TERMINATE) {
+					status = AE_OK;
+
+					/* Clean up */
+					do {
+						if (op) {
+							acpi_ps_complete_this_op (walk_state, op);
+						}
+
+						acpi_ps_pop_scope (parser_state, &op,
+							&walk_state->arg_types, &walk_state->arg_count);
+
+					} while (op);
+
+					return_ACPI_STATUS (status);
+				}
+
+				else if (ACPI_FAILURE (status)) {
+					acpi_ps_complete_this_op (walk_state, op);
+					return_ACPI_STATUS (status);
+				}
+			}
+
+			acpi_ps_complete_this_op (walk_state, op);
+		}
+
+		acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,
+			&walk_state->arg_count);
+
+	} while (op);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_parse_aml
+ *
+ * PARAMETERS:  start_scope     - The starting point of the parse.  Becomes the
+ *                                root of the parsed op tree.
+ *              Aml             - Pointer to the raw AML code to parse
+ *              aml_size        - Length of the AML to parse
+ *
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse raw AML and return a tree of ops
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_parse_aml (
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	acpi_status                     terminate_status;
+	struct acpi_thread_state        *thread;
+	struct acpi_thread_state        *prev_walk_list = acpi_gbl_current_walk_list;
+	struct acpi_walk_state          *previous_walk_state;
+
+
+	ACPI_FUNCTION_TRACE ("ps_parse_aml");
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with walk_state=%p Aml=%p size=%X\n",
+		walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size));
+
+
+	/* Create and initialize a new thread state */
+
+	thread = acpi_ut_create_thread_state ();
+	if (!thread) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	walk_state->thread = thread;
+	acpi_ds_push_walk_state (walk_state, thread);
+
+	/*
+	 * This global allows the AML debugger to get a handle to the currently
+	 * executing control method.
+	 */
+	acpi_gbl_current_walk_list = thread;
+
+	/*
+	 * Execute the walk loop as long as there is a valid Walk State.  This
+	 * handles nested control method invocations without recursion.
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", walk_state));
+
+	status = AE_OK;
+	while (walk_state) {
+		if (ACPI_SUCCESS (status)) {
+			/*
+			 * The parse_loop executes AML until the method terminates
+			 * or calls another method.
+			 */
+			status = acpi_ps_parse_loop (walk_state);
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+			"Completed one call to walk loop, %s State=%p\n",
+			acpi_format_exception (status), walk_state));
+
+		if (status == AE_CTRL_TRANSFER) {
+			/*
+			 * A method call was detected.
+			 * Transfer control to the called control method
+			 */
+			status = acpi_ds_call_control_method (thread, walk_state, NULL);
+
+			/*
+			 * If the transfer to the new method method call worked, a new walk
+			 * state was created -- get it
+			 */
+			walk_state = acpi_ds_get_current_walk_state (thread);
+			continue;
+		}
+		else if (status == AE_CTRL_TERMINATE) {
+			status = AE_OK;
+		}
+		else if ((status != AE_OK) && (walk_state->method_desc)) {
+			ACPI_REPORT_METHOD_ERROR ("Method execution failed",
+				walk_state->method_node, NULL, status);
+
+			/* Check for possible multi-thread reentrancy problem */
+
+			if ((status == AE_ALREADY_EXISTS) &&
+				(!walk_state->method_desc->method.semaphore)) {
+				/*
+				 * This method is marked not_serialized, but it tried to create a named
+				 * object, causing the second thread entrance to fail.  We will workaround
+				 * this by marking the method permanently as Serialized.
+				 */
+				walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED;
+				walk_state->method_desc->method.concurrency = 1;
+			}
+		}
+
+		if (walk_state->method_desc) {
+			/* Decrement the thread count on the method parse tree */
+
+			if (walk_state->method_desc->method.thread_count) {
+				walk_state->method_desc->method.thread_count--;
+			}
+		}
+
+		/* We are done with this walk, move on to the parent if any */
+
+		walk_state = acpi_ds_pop_walk_state (thread);
+
+		/* Reset the current scope to the beginning of scope stack */
+
+		acpi_ds_scope_stack_clear (walk_state);
+
+		/*
+		 * If we just returned from the execution of a control method,
+		 * there's lots of cleanup to do
+		 */
+		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
+			terminate_status = acpi_ds_terminate_control_method (walk_state);
+			if (ACPI_FAILURE (terminate_status)) {
+				ACPI_REPORT_ERROR ((
+					"Could not terminate control method properly\n"));
+
+				/* Ignore error and continue */
+			}
+		}
+
+		/* Delete this walk state and all linked control states */
+
+		acpi_ps_cleanup_scope (&walk_state->parser_state);
+
+		previous_walk_state = walk_state;
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, implicit_value=%p State=%p\n",
+			walk_state->return_desc, walk_state->implicit_return_obj, walk_state));
+
+		/* Check if we have restarted a preempted walk */
+
+		walk_state = acpi_ds_get_current_walk_state (thread);
+		if (walk_state) {
+			if (ACPI_SUCCESS (status)) {
+				/*
+				 * There is another walk state, restart it.
+				 * If the method return value is not used by the parent,
+				 * The object is deleted
+				 */
+				if (!previous_walk_state->return_desc) {
+					status = acpi_ds_restart_control_method (walk_state,
+							 previous_walk_state->implicit_return_obj);
+				}
+				else {
+					/*
+					 * We have a valid return value, delete any implicit
+					 * return value.
+					 */
+					acpi_ds_clear_implicit_return (previous_walk_state);
+
+					status = acpi_ds_restart_control_method (walk_state,
+							 previous_walk_state->return_desc);
+				}
+				if (ACPI_SUCCESS (status)) {
+					walk_state->walk_type |= ACPI_WALK_METHOD_RESTART;
+				}
+			}
+			else {
+				/* On error, delete any return object */
+
+				acpi_ut_remove_reference (previous_walk_state->return_desc);
+			}
+		}
+
+		/*
+		 * Just completed a 1st-level method, save the final internal return
+		 * value (if any)
+		 */
+		else if (previous_walk_state->caller_return_desc) {
+			if (previous_walk_state->implicit_return_obj) {
+				*(previous_walk_state->caller_return_desc) = previous_walk_state->implicit_return_obj;
+			}
+			else {
+				 /* NULL if no return value */
+
+				*(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc;
+			}
+		}
+		else {
+			if (previous_walk_state->return_desc) {
+				/* Caller doesn't want it, must delete it */
+
+				acpi_ut_remove_reference (previous_walk_state->return_desc);
+			}
+			if (previous_walk_state->implicit_return_obj) {
+				/* Caller doesn't want it, must delete it */
+
+				acpi_ut_remove_reference (previous_walk_state->implicit_return_obj);
+			}
+		}
+
+		acpi_ds_delete_walk_state (previous_walk_state);
+	}
+
+	/* Normal exit */
+
+	acpi_ex_release_all_mutexes (thread);
+	acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread));
+	acpi_gbl_current_walk_list = prev_walk_list;
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
new file mode 100644
index 0000000..dcbed49
--- /dev/null
+++ b/drivers/acpi/parser/psscope.c
@@ -0,0 +1,290 @@
+/******************************************************************************
+ *
+ * Module Name: psscope - Parser scope stack management routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("psscope")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_parent_scope
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Pointer to an Op object
+ *
+ * DESCRIPTION: Get parent of current op being parsed
+ *
+ ******************************************************************************/
+
+union acpi_parse_object *
+acpi_ps_get_parent_scope (
+	struct acpi_parse_state         *parser_state)
+{
+	return (parser_state->scope->parse_scope.op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_has_completed_scope
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Boolean, TRUE = scope completed.
+ *
+ * DESCRIPTION: Is parsing of current argument complete?  Determined by
+ *              1) AML pointer is at or beyond the end of the scope
+ *              2) The scope argument count has reached zero.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ps_has_completed_scope (
+	struct acpi_parse_state         *parser_state)
+{
+	return ((u8) ((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
+			   !parser_state->scope->parse_scope.arg_count)));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_init_scope
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *              Root                - the Root Node of this new scope
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Allocate and init a new scope object
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_init_scope (
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         *root_op)
+{
+	union acpi_generic_state        *scope;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_init_scope", root_op);
+
+
+	scope = acpi_ut_create_generic_state ();
+	if (!scope) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	scope->common.data_type     = ACPI_DESC_TYPE_STATE_RPSCOPE;
+	scope->parse_scope.op       = root_op;
+	scope->parse_scope.arg_count = ACPI_VAR_ARGS;
+	scope->parse_scope.arg_end  = parser_state->aml_end;
+	scope->parse_scope.pkg_end  = parser_state->aml_end;
+
+	parser_state->scope         = scope;
+	parser_state->start_op      = root_op;
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_push_scope
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *              Op                  - Current op to be pushed
+ *              remaining_args      - List of args remaining
+ *              arg_count           - Fixed or variable number of args
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Push current op to begin parsing its argument
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ps_push_scope (
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         *op,
+	u32                             remaining_args,
+	u32                             arg_count)
+{
+	union acpi_generic_state        *scope;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_push_scope", op);
+
+
+	scope = acpi_ut_create_generic_state ();
+	if (!scope) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	scope->common.data_type        = ACPI_DESC_TYPE_STATE_PSCOPE;
+	scope->parse_scope.op          = op;
+	scope->parse_scope.arg_list    = remaining_args;
+	scope->parse_scope.arg_count   = arg_count;
+	scope->parse_scope.pkg_end     = parser_state->pkg_end;
+
+	/* Push onto scope stack */
+
+	acpi_ut_push_generic_state (&parser_state->scope, scope);
+
+	if (arg_count == ACPI_VAR_ARGS) {
+		/* multiple arguments */
+
+		scope->parse_scope.arg_end = parser_state->pkg_end;
+	}
+	else {
+		/* single argument */
+
+		scope->parse_scope.arg_end = ACPI_TO_POINTER (ACPI_MAX_PTR);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_pop_scope
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *              Op                  - Where the popped op is returned
+ *              arg_list            - Where the popped "next argument" is
+ *                                    returned
+ *              arg_count           - Count of objects in arg_list
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return to parsing a previous op
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_pop_scope (
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         **op,
+	u32                             *arg_list,
+	u32                             *arg_count)
+{
+	union acpi_generic_state        *scope = parser_state->scope;
+
+
+	ACPI_FUNCTION_TRACE ("ps_pop_scope");
+
+
+	/*
+	 * Only pop the scope if there is in fact a next scope
+	 */
+	if (scope->common.next) {
+		scope = acpi_ut_pop_generic_state (&parser_state->scope);
+
+		/* return to parsing previous op */
+
+		*op                     = scope->parse_scope.op;
+		*arg_list               = scope->parse_scope.arg_list;
+		*arg_count              = scope->parse_scope.arg_count;
+		parser_state->pkg_end   = scope->parse_scope.pkg_end;
+
+		/* All done with this scope state structure */
+
+		acpi_ut_delete_generic_state (scope);
+	}
+	else {
+		/* empty parse stack, prepare to fetch next opcode */
+
+		*op                     = NULL;
+		*arg_list               = 0;
+		*arg_count              = 0;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_cleanup_scope
+ *
+ * PARAMETERS:  parser_state        - Current parser state object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Destroy available list, remaining stack levels, and return
+ *              root scope
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_cleanup_scope (
+	struct acpi_parse_state         *parser_state)
+{
+	union acpi_generic_state        *scope;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state);
+
+
+	if (!parser_state) {
+		return_VOID;
+	}
+
+	/* Delete anything on the scope stack */
+
+	while (parser_state->scope) {
+		scope = acpi_ut_pop_generic_state (&parser_state->scope);
+		acpi_ut_delete_generic_state (scope);
+	}
+
+	return_VOID;
+}
+
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
new file mode 100644
index 0000000..2140bd1
--- /dev/null
+++ b/drivers/acpi/parser/pstree.c
@@ -0,0 +1,327 @@
+/******************************************************************************
+ *
+ * Module Name: pstree - Parser op tree manipulation/traversal/search
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("pstree")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_arg
+ *
+ * PARAMETERS:  Op              - Get an argument for this op
+ *              Argn            - Nth argument to get
+ *
+ * RETURN:      The argument (as an Op object).  NULL if argument does not exist
+ *
+ * DESCRIPTION: Get the specified op's argument.
+ *
+ ******************************************************************************/
+
+union acpi_parse_object *
+acpi_ps_get_arg (
+	union acpi_parse_object         *op,
+	u32                             argn)
+{
+	union acpi_parse_object         *arg = NULL;
+	const struct acpi_opcode_info   *op_info;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Get the info structure for this opcode */
+
+	op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+	if (op_info->class == AML_CLASS_UNKNOWN) {
+		/* Invalid opcode or ASCII character */
+
+		return (NULL);
+	}
+
+	/* Check if this opcode requires argument sub-objects */
+
+	if (!(op_info->flags & AML_HAS_ARGS)) {
+		/* Has no linked argument objects */
+
+		return (NULL);
+	}
+
+	/* Get the requested argument object */
+
+	arg = op->common.value.arg;
+	while (arg && argn) {
+		argn--;
+		arg = arg->common.next;
+	}
+
+	return (arg);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_append_arg
+ *
+ * PARAMETERS:  Op              - Append an argument to this Op.
+ *              Arg             - Argument Op to append
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_append_arg (
+	union acpi_parse_object         *op,
+	union acpi_parse_object         *arg)
+{
+	union acpi_parse_object         *prev_arg;
+	const struct acpi_opcode_info   *op_info;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (!op) {
+		return;
+	}
+
+	/* Get the info structure for this opcode */
+
+	op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
+	if (op_info->class == AML_CLASS_UNKNOWN) {
+		/* Invalid opcode */
+
+		ACPI_REPORT_ERROR (("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n",
+			op->common.aml_opcode));
+		return;
+	}
+
+	/* Check if this opcode requires argument sub-objects */
+
+	if (!(op_info->flags & AML_HAS_ARGS)) {
+		/* Has no linked argument objects */
+
+		return;
+	}
+
+
+	/* Append the argument to the linked argument list */
+
+	if (op->common.value.arg) {
+		/* Append to existing argument list */
+
+		prev_arg = op->common.value.arg;
+		while (prev_arg->common.next) {
+			prev_arg = prev_arg->common.next;
+		}
+		prev_arg->common.next = arg;
+	}
+
+	else {
+		/* No argument list, this will be the first argument */
+
+		op->common.value.arg = arg;
+	}
+
+
+	/* Set the parent in this arg and any args linked after it */
+
+	while (arg) {
+		arg->common.parent = op;
+		arg = arg->common.next;
+	}
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_child
+ *
+ * PARAMETERS:  Op              - Get the child of this Op
+ *
+ * RETURN:      Child Op, Null if none is found.
+ *
+ * DESCRIPTION: Get op's children or NULL if none
+ *
+ ******************************************************************************/
+union acpi_parse_object *
+acpi_ps_get_child (
+	union acpi_parse_object         *op)
+{
+	union acpi_parse_object         *child = NULL;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	switch (op->common.aml_opcode) {
+	case AML_SCOPE_OP:
+	case AML_ELSE_OP:
+	case AML_DEVICE_OP:
+	case AML_THERMAL_ZONE_OP:
+	case AML_INT_METHODCALL_OP:
+
+		child = acpi_ps_get_arg (op, 0);
+		break;
+
+
+	case AML_BUFFER_OP:
+	case AML_PACKAGE_OP:
+	case AML_METHOD_OP:
+	case AML_IF_OP:
+	case AML_WHILE_OP:
+	case AML_FIELD_OP:
+
+		child = acpi_ps_get_arg (op, 1);
+		break;
+
+
+	case AML_POWER_RES_OP:
+	case AML_INDEX_FIELD_OP:
+
+		child = acpi_ps_get_arg (op, 2);
+		break;
+
+
+	case AML_PROCESSOR_OP:
+	case AML_BANK_FIELD_OP:
+
+		child = acpi_ps_get_arg (op, 3);
+		break;
+
+
+	default:
+		/* All others have no children */
+		break;
+	}
+
+	return (child);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_depth_next
+ *
+ * PARAMETERS:  Origin          - Root of subtree to search
+ *              Op              - Last (previous) Op that was found
+ *
+ * RETURN:      Next Op found in the search.
+ *
+ * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
+ *              Return NULL when reaching "origin" or when walking up from root
+ *
+ ******************************************************************************/
+
+union acpi_parse_object *
+acpi_ps_get_depth_next (
+	union acpi_parse_object         *origin,
+	union acpi_parse_object         *op)
+{
+	union acpi_parse_object         *next = NULL;
+	union acpi_parse_object         *parent;
+	union acpi_parse_object         *arg;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (!op) {
+		return (NULL);
+	}
+
+	/* look for an argument or child */
+
+	next = acpi_ps_get_arg (op, 0);
+	if (next) {
+		return (next);
+	}
+
+	/* look for a sibling */
+
+	next = op->common.next;
+	if (next) {
+		return (next);
+	}
+
+	/* look for a sibling of parent */
+
+	parent = op->common.parent;
+
+	while (parent) {
+		arg = acpi_ps_get_arg (parent, 0);
+		while (arg && (arg != origin) && (arg != op)) {
+			arg = arg->common.next;
+		}
+
+		if (arg == origin) {
+			/* reached parent of origin, end search */
+
+			return (NULL);
+		}
+
+		if (parent->common.next) {
+			/* found sibling of parent */
+
+			return (parent->common.next);
+		}
+
+		op = parent;
+		parent = parent->common.parent;
+	}
+
+	return (next);
+}
+
+#endif  /*  ACPI_FUTURE_USAGE  */
+
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
new file mode 100644
index 0000000..b3597cb
--- /dev/null
+++ b/drivers/acpi/parser/psutils.c
@@ -0,0 +1,309 @@
+/******************************************************************************
+ *
+ * Module Name: psutils - Parser miscellaneous utilities (Parser only)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("psutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_create_scope_op
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      scope_op
+ *
+ * DESCRIPTION: Create a Scope and associated namepath op with the root name
+ *
+ ******************************************************************************/
+
+union acpi_parse_object *
+acpi_ps_create_scope_op (
+	void)
+{
+	union acpi_parse_object         *scope_op;
+
+
+	scope_op = acpi_ps_alloc_op (AML_SCOPE_OP);
+	if (!scope_op) {
+		return (NULL);
+	}
+
+
+	scope_op->named.name = ACPI_ROOT_NAME;
+	return (scope_op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_init_op
+ *
+ * PARAMETERS:  Op              - A newly allocated Op object
+ *              Opcode          - Opcode to store in the Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
+ *              opcode
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_init_op (
+	union acpi_parse_object         *op,
+	u16                             opcode)
+{
+	ACPI_FUNCTION_ENTRY ();
+
+
+	op->common.data_type = ACPI_DESC_TYPE_PARSER;
+	op->common.aml_opcode = opcode;
+
+	ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name,
+			(acpi_ps_get_opcode_info (opcode))->name, sizeof (op->common.aml_op_name)));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_alloc_op
+ *
+ * PARAMETERS:  Opcode          - Opcode that will be stored in the new Op
+ *
+ * RETURN:      Pointer to the new Op.
+ *
+ * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
+ *              opcode.  A cache of opcodes is available for the pure
+ *              GENERIC_OP, since this is by far the most commonly used.
+ *
+ ******************************************************************************/
+
+union acpi_parse_object*
+acpi_ps_alloc_op (
+	u16                             opcode)
+{
+	union acpi_parse_object         *op;
+	const struct acpi_opcode_info   *op_info;
+	u8                              flags = ACPI_PARSEOP_GENERIC;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	op_info = acpi_ps_get_opcode_info (opcode);
+
+	/* Determine type of parse_op required */
+
+	if (op_info->flags & AML_DEFER) {
+		flags = ACPI_PARSEOP_DEFERRED;
+	}
+	else if (op_info->flags & AML_NAMED) {
+		flags = ACPI_PARSEOP_NAMED;
+	}
+	else if (opcode == AML_INT_BYTELIST_OP) {
+		flags = ACPI_PARSEOP_BYTELIST;
+	}
+
+	/* Allocate the minimum required size object */
+
+	if (flags == ACPI_PARSEOP_GENERIC) {
+		/* The generic op (default) is by far the most common (16 to 1) */
+
+		op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE);
+	}
+	else {
+		/* Extended parseop */
+
+		op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT);
+	}
+
+	/* Initialize the Op */
+
+	if (op) {
+		acpi_ps_init_op (op, opcode);
+		op->common.flags = flags;
+	}
+
+	return (op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_free_op
+ *
+ * PARAMETERS:  Op              - Op to be freed
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Free an Op object.  Either put it on the GENERIC_OP cache list
+ *              or actually free it.
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_free_op (
+	union acpi_parse_object         *op)
+{
+	ACPI_FUNCTION_NAME ("ps_free_op");
+
+
+	if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n", op));
+	}
+
+	if (op->common.flags & ACPI_PARSEOP_GENERIC) {
+		acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op);
+	}
+	else {
+		acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE_EXT, op);
+	}
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_delete_parse_cache
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Free all objects that are on the parse cache list.
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_delete_parse_cache (
+	void)
+{
+	ACPI_FUNCTION_TRACE ("ps_delete_parse_cache");
+
+
+	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE);
+	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE_EXT);
+	return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Utility functions
+ *
+ * DESCRIPTION: Low level character and object functions
+ *
+ ******************************************************************************/
+
+
+/*
+ * Is "c" a namestring lead character?
+ */
+u8
+acpi_ps_is_leading_char (
+	u32                             c)
+{
+	return ((u8) (c == '_' || (c >= 'A' && c <= 'Z')));
+}
+
+
+/*
+ * Is "c" a namestring prefix character?
+ */
+u8
+acpi_ps_is_prefix_char (
+	u32                             c)
+{
+	return ((u8) (c == '\\' || c == '^'));
+}
+
+
+/*
+ * Get op's name (4-byte name segment) or 0 if unnamed
+ */
+#ifdef ACPI_FUTURE_USAGE
+u32
+acpi_ps_get_name (
+	union acpi_parse_object         *op)
+{
+
+
+	/* The "generic" object has no name associated with it */
+
+	if (op->common.flags & ACPI_PARSEOP_GENERIC) {
+		return (0);
+	}
+
+	/* Only the "Extended" parse objects have a name */
+
+	return (op->named.name);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*
+ * Set op's name
+ */
+void
+acpi_ps_set_name (
+	union acpi_parse_object         *op,
+	u32                             name)
+{
+
+	/* The "generic" object has no name associated with it */
+
+	if (op->common.flags & ACPI_PARSEOP_GENERIC) {
+		return;
+	}
+
+	op->named.name = name;
+}
+
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
new file mode 100644
index 0000000..110d2ce
--- /dev/null
+++ b/drivers/acpi/parser/pswalk.c
@@ -0,0 +1,115 @@
+/******************************************************************************
+ *
+ * Module Name: pswalk - Parser routines to walk parsed op tree(s)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("pswalk")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_delete_parse_tree
+ *
+ * PARAMETERS:  subtree_root        - Root of tree (or subtree) to delete
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete a portion of or an entire parse tree.
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_delete_parse_tree (
+	union acpi_parse_object         *subtree_root)
+{
+	union acpi_parse_object         *op = subtree_root;
+	union acpi_parse_object         *next = NULL;
+	union acpi_parse_object         *parent = NULL;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root);
+
+
+	/* Visit all nodes in the subtree */
+
+	while (op) {
+		/* Check if we are not ascending */
+
+		if (op != parent) {
+			/* Look for an argument or child of the current op */
+
+			next = acpi_ps_get_arg (op, 0);
+			if (next) {
+				/* Still going downward in tree (Op is not completed yet) */
+
+				op = next;
+				continue;
+			}
+		}
+
+		/*
+		 * No more children, this Op is complete.
+		 */
+		next = op->common.next;
+		parent = op->common.parent;
+
+		acpi_ps_free_op (op);
+
+		/*
+		 * If we are back to the starting point, the walk is complete.
+		 */
+		if (op == subtree_root) {
+			return_VOID;
+		}
+		if (next) {
+			op = next;
+		}
+		else {
+			op = parent;
+		}
+	}
+	return_VOID;
+}
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
new file mode 100644
index 0000000..b318ad2
--- /dev/null
+++ b/drivers/acpi/parser/psxface.c
@@ -0,0 +1,243 @@
+/******************************************************************************
+ *
+ * Module Name: psxface - Parser external interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_PARSER
+	 ACPI_MODULE_NAME    ("psxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_psx_execute
+ *
+ * PARAMETERS:  Info->Node          - A method object containing both the AML
+ *                                    address and length.
+ *              **Params            - List of parameters to pass to method,
+ *                                    terminated by NULL. Params itself may be
+ *                                    NULL if no parameters are being passed.
+ *              **return_obj_desc   - Return object from execution of the
+ *                                    method.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_psx_execute (
+	struct acpi_parameter_info      *info)
+{
+	acpi_status                     status;
+	union acpi_operand_object       *obj_desc;
+	u32                             i;
+	union acpi_parse_object         *op;
+	struct acpi_walk_state          *walk_state;
+
+
+	ACPI_FUNCTION_TRACE ("psx_execute");
+
+
+	/* Validate the Node and get the attached object */
+
+	if (!info || !info->node) {
+		return_ACPI_STATUS (AE_NULL_ENTRY);
+	}
+
+	obj_desc = acpi_ns_get_attached_object (info->node);
+	if (!obj_desc) {
+		return_ACPI_STATUS (AE_NULL_OBJECT);
+	}
+
+	/* Init for new method, wait on concurrency semaphore */
+
+	status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if ((info->parameter_type == ACPI_PARAM_ARGS) &&
+		(info->parameters)) {
+		/*
+		 * The caller "owns" the parameters, so give each one an extra
+		 * reference
+		 */
+		for (i = 0; info->parameters[i]; i++) {
+			acpi_ut_add_reference (info->parameters[i]);
+		}
+	}
+
+	/*
+	 * 1) Perform the first pass parse of the method to enter any
+	 * named objects that it creates into the namespace
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+		"**** Begin Method Parse **** Entry=%p obj=%p\n",
+		info->node, obj_desc));
+
+	/* Create and init a Root Node */
+
+	op = acpi_ps_create_scope_op ();
+	if (!op) {
+		status = AE_NO_MEMORY;
+		goto cleanup1;
+	}
+
+	/*
+	 * Get a new owner_id for objects created by this method. Namespace
+	 * objects (such as Operation Regions) can be created during the
+	 * first pass parse.
+	 */
+	obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
+
+	/* Create and initialize a new walk state */
+
+	walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
+			   NULL, NULL, NULL);
+	if (!walk_state) {
+		status = AE_NO_MEMORY;
+		goto cleanup2;
+	}
+
+	status = acpi_ds_init_aml_walk (walk_state, op, info->node,
+			  obj_desc->method.aml_start,
+			  obj_desc->method.aml_length, NULL, 1);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup3;
+	}
+
+	/* Parse the AML */
+
+	status = acpi_ps_parse_aml (walk_state);
+	acpi_ps_delete_parse_tree (op);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup1; /* Walk state is already deleted */
+	}
+
+	/*
+	 * 2) Execute the method.  Performs second pass parse simultaneously
+	 */
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+		"**** Begin Method Execution **** Entry=%p obj=%p\n",
+		info->node, obj_desc));
+
+	/* Create and init a Root Node */
+
+	op = acpi_ps_create_scope_op ();
+	if (!op) {
+		status = AE_NO_MEMORY;
+		goto cleanup1;
+	}
+
+	/* Init new op with the method name and pointer back to the NS node */
+
+	acpi_ps_set_name (op, info->node->name.integer);
+	op->common.node = info->node;
+
+	/* Create and initialize a new walk state */
+
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+	if (!walk_state) {
+		status = AE_NO_MEMORY;
+		goto cleanup2;
+	}
+
+	status = acpi_ds_init_aml_walk (walk_state, op, info->node,
+			  obj_desc->method.aml_start,
+			  obj_desc->method.aml_length, info, 3);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup3;
+	}
+
+	/*
+	 * The walk of the parse tree is where we actually execute the method
+	 */
+	status = acpi_ps_parse_aml (walk_state);
+	goto cleanup2; /* Walk state already deleted */
+
+
+cleanup3:
+	acpi_ds_delete_walk_state (walk_state);
+
+cleanup2:
+	acpi_ps_delete_parse_tree (op);
+
+cleanup1:
+	if ((info->parameter_type == ACPI_PARAM_ARGS) &&
+		(info->parameters)) {
+		/* Take away the extra reference that we gave the parameters above */
+
+		for (i = 0; info->parameters[i]; i++) {
+			/* Ignore errors, just do them all */
+
+			(void) acpi_ut_update_object_reference (info->parameters[i], REF_DECREMENT);
+		}
+	}
+
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * If the method has returned an object, signal this to the caller with
+	 * a control exception code
+	 */
+	if (info->return_object) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n",
+			info->return_object));
+		ACPI_DUMP_STACK_ENTRY (info->return_object);
+
+		status = AE_CTRL_RETURN_VALUE;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
new file mode 100644
index 0000000..5d19b39
--- /dev/null
+++ b/drivers/acpi/pci_bind.c
@@ -0,0 +1,384 @@
+/*
+ *  pci_bind.c - ACPI PCI Device Binding ($Revision: 2 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_PCI_COMPONENT
+ACPI_MODULE_NAME		("pci_bind")
+
+struct acpi_pci_data {
+	struct acpi_pci_id	id;
+	struct pci_bus		*bus;
+	struct pci_dev		*dev;
+};
+
+
+void
+acpi_pci_data_handler (
+	acpi_handle		handle,
+	u32			function,
+	void			*context)
+{
+	ACPI_FUNCTION_TRACE("acpi_pci_data_handler");
+
+	/* TBD: Anything we need to do here? */
+
+	return_VOID;
+}
+
+
+/**
+ * acpi_os_get_pci_id
+ * ------------------
+ * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
+ * to resolve PCI information for ACPI-PCI devices defined in the namespace.
+ * This typically occurs when resolving PCI operation region information.
+ */
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_os_get_pci_id (
+	acpi_handle		handle,
+	struct acpi_pci_id	*id)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_device	*device = NULL;
+	struct acpi_pci_data	*data = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");
+
+	if (!id)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Invalid ACPI Bus context for device %s\n",
+			acpi_device_bid(device)));
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+
+	status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
+	if (ACPI_FAILURE(status) || !data || !data->dev) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Invalid ACPI-PCI context for device %s\n",
+			acpi_device_bid(device)));
+		return_ACPI_STATUS(status);
+	}
+
+	*id = data->id;
+	
+	/*
+	id->segment = data->id.segment;
+	id->bus = data->id.bus;
+	id->device = data->id.device;
+	id->function = data->id.function;
+	*/
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+		"Device %s has PCI address %02x:%02x:%02x.%02x\n", 
+		acpi_device_bid(device), id->segment, id->bus, 
+		id->device, id->function));
+
+	return_ACPI_STATUS(AE_OK);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+	
+int
+acpi_pci_bind (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_pci_data	*data = NULL;
+	struct acpi_pci_data	*pdata = NULL;
+	char			*pathname = NULL;
+	struct acpi_buffer	buffer = {0, NULL};
+	acpi_handle		handle = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_bind");
+
+	if (!device || !device->parent)
+		return_VALUE(-EINVAL);
+
+	pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+	buffer.length = ACPI_PATHNAME_MAX;
+	buffer.pointer = pathname;
+
+	data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
+	if (!data){
+		kfree (pathname);
+		return_VALUE(-ENOMEM);
+	}
+	memset(data, 0, sizeof(struct acpi_pci_data));
+
+	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", 
+		pathname));
+
+	/* 
+	 * Segment & Bus
+	 * -------------
+	 * These are obtained via the parent device's ACPI-PCI context.
+	 */
+	status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, 
+		(void**) &pdata);
+	if (ACPI_FAILURE(status) || !pdata || !pdata->bus) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Invalid ACPI-PCI context for parent device %s\n",
+			acpi_device_bid(device->parent)));
+		result = -ENODEV;
+		goto end;
+	}
+	data->id.segment = pdata->id.segment;
+	data->id.bus = pdata->bus->number;
+
+	/*
+	 * Device & Function
+	 * -----------------
+	 * These are simply obtained from the device's _ADR method.  Note
+	 * that a value of zero is valid.
+	 */
+	data->id.device = device->pnp.bus_address >> 16;
+	data->id.function = device->pnp.bus_address & 0xFFFF;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n",
+		data->id.segment, data->id.bus, data->id.device, 
+		data->id.function));
+
+	/*
+	 * TBD: Support slot devices (e.g. function=0xFFFF).
+	 */
+
+	/* 
+	 * Locate PCI Device
+	 * -----------------
+	 * Locate matching device in PCI namespace.  If it doesn't exist
+	 * this typically means that the device isn't currently inserted
+	 * (e.g. docking station, port replicator, etc.).
+	 */
+	data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));
+	if (!data->dev) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
+			data->id.segment, data->id.bus, 
+			data->id.device, data->id.function));
+		result = -ENODEV;
+		goto end;
+	}
+	if (!data->dev->bus) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
+			data->id.segment, data->id.bus, 
+			data->id.device, data->id.function));
+		result = -ENODEV;
+		goto end;
+	}
+
+	/*
+	 * PCI Bridge?
+	 * -----------
+	 * If so, set the 'bus' field and install the 'bind' function to 
+	 * facilitate callbacks for all of its children.
+	 */
+	if (data->dev->subordinate) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"Device %02x:%02x:%02x.%02x is a PCI bridge\n",
+			data->id.segment, data->id.bus, 
+			data->id.device, data->id.function));
+		data->bus = data->dev->subordinate;
+		device->ops.bind = acpi_pci_bind;
+		device->ops.unbind = acpi_pci_unbind;
+	}
+
+	/*
+	 * Attach ACPI-PCI Context
+	 * -----------------------
+	 * Thus binding the ACPI and PCI devices.
+	 */
+	status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to attach ACPI-PCI context to device %s\n",
+			acpi_device_bid(device)));
+		result = -ENODEV;
+		goto end;
+	}
+
+	/*
+	 * PCI Routing Table
+	 * -----------------
+	 * Evaluate and parse _PRT, if exists.  This code is independent of 
+	 * PCI bridges (above) to allow parsing of _PRT objects within the
+	 * scope of non-bridge devices.  Note that _PRTs within the scope of
+	 * a PCI bridge assume the bridge's subordinate bus number.
+	 *
+	 * TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
+	 */
+	status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
+	if (ACPI_SUCCESS(status)) {
+		if (data->bus)				    /* PCI-PCI bridge */
+			acpi_pci_irq_add_prt(device->handle, data->id.segment, 
+				data->bus->number);
+		else				     /* non-bridge PCI device */
+			acpi_pci_irq_add_prt(device->handle, data->id.segment,
+				data->id.bus);
+	}
+
+end:
+	kfree(pathname);
+	if (result)
+		kfree(data);
+
+	return_VALUE(result);
+}
+
+int acpi_pci_unbind(
+	struct acpi_device      *device)
+{
+	int                     result = 0;
+	acpi_status             status = AE_OK;
+	struct acpi_pci_data    *data = NULL;
+	char                    *pathname = NULL;
+	struct acpi_buffer      buffer = {0, NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_pci_unbind");
+
+	if (!device || !device->parent)
+		return_VALUE(-EINVAL);
+
+	pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+
+	buffer.length = ACPI_PATHNAME_MAX;
+	buffer.pointer = pathname;
+	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
+		pathname));
+	kfree(pathname);
+
+	status = acpi_get_data(device->handle, acpi_pci_data_handler, (void**)&data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to get data from device %s\n",
+			acpi_device_bid(device)));
+		result = -ENODEV;
+		goto end;
+	}
+
+	status = acpi_detach_data(device->handle, acpi_pci_data_handler);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to detach data from device %s\n",
+			acpi_device_bid(device)));
+		result = -ENODEV;
+		goto end;
+	}
+	if (data->dev->subordinate) {
+		acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
+	}
+	kfree(data);
+
+end:
+	return_VALUE(result);
+}
+
+int 
+acpi_pci_bind_root (
+	struct acpi_device	*device,
+	struct acpi_pci_id	*id,
+	struct pci_bus		*bus) 
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_pci_data	*data = NULL;
+	char			*pathname = NULL;
+	struct acpi_buffer	buffer = {0, NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_pci_bind_root");
+
+	pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+
+	buffer.length = ACPI_PATHNAME_MAX;
+	buffer.pointer = pathname;
+
+	if (!device || !id || !bus){
+		kfree(pathname);
+		return_VALUE(-EINVAL);
+	}
+
+	data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
+	if (!data){
+		kfree(pathname);
+		return_VALUE(-ENOMEM);
+	}
+	memset(data, 0, sizeof(struct acpi_pci_data));
+
+	data->id = *id;
+	data->bus = bus;
+	device->ops.bind = acpi_pci_bind;
+	device->ops.unbind = acpi_pci_unbind;
+
+	acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
+		"%02x:%02x\n", pathname, id->segment, id->bus));
+
+	status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to attach ACPI-PCI context to device %s\n",
+			pathname));
+		result = -ENODEV;
+		goto end;
+	}
+
+end:
+	kfree(pathname);
+	if (result != 0)
+		kfree(data);
+
+	return_VALUE(result);
+}
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
new file mode 100644
index 0000000..12b0eea
--- /dev/null
+++ b/drivers/acpi/pci_irq.c
@@ -0,0 +1,518 @@
+/*
+ *  pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 11 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2002       Dominik Brodowski <devel@brodo.de>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/config.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_PCI_COMPONENT
+ACPI_MODULE_NAME		("pci_irq")
+
+static struct acpi_prt_list	acpi_prt;
+static DEFINE_SPINLOCK(acpi_prt_lock);
+
+/* --------------------------------------------------------------------------
+                         PCI IRQ Routing Table (PRT) Support
+   -------------------------------------------------------------------------- */
+
+static struct acpi_prt_entry *
+acpi_pci_irq_find_prt_entry (
+	int			segment,
+	int			bus,
+	int			device,
+	int			pin)
+{
+	struct list_head	*node = NULL;
+	struct acpi_prt_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry");
+
+	if (!acpi_prt.count)
+		return_PTR(NULL);
+
+	/*
+	 * Parse through all PRT entries looking for a match on the specified
+	 * PCI device's segment, bus, device, and pin (don't care about func).
+	 *
+	 */
+	spin_lock(&acpi_prt_lock);
+	list_for_each(node, &acpi_prt.entries) {
+		entry = list_entry(node, struct acpi_prt_entry, node);
+		if ((segment == entry->id.segment) 
+			&& (bus == entry->id.bus) 
+			&& (device == entry->id.device)
+			&& (pin == entry->pin)) {
+			spin_unlock(&acpi_prt_lock);
+			return_PTR(entry);
+		}
+	}
+
+	spin_unlock(&acpi_prt_lock);
+	return_PTR(NULL);
+}
+
+
+static int
+acpi_pci_irq_add_entry (
+	acpi_handle			handle,
+	int				segment,
+	int				bus,
+	struct acpi_pci_routing_table	*prt)
+{
+	struct acpi_prt_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_add_entry");
+
+	if (!prt)
+		return_VALUE(-EINVAL);
+
+	entry = kmalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
+	if (!entry)
+		return_VALUE(-ENOMEM);
+	memset(entry, 0, sizeof(struct acpi_prt_entry));
+
+	entry->id.segment = segment;
+	entry->id.bus = bus;
+	entry->id.device = (prt->address >> 16) & 0xFFFF;
+	entry->id.function = prt->address & 0xFFFF;
+	entry->pin = prt->pin;
+
+	/*
+	 * Type 1: Dynamic
+	 * ---------------
+	 * The 'source' field specifies the PCI interrupt link device used to
+	 * configure the IRQ assigned to this slot|dev|pin.  The 'source_index'
+	 * indicates which resource descriptor in the resource template (of
+	 * the link device) this interrupt is allocated from.
+	 * 
+	 * NOTE: Don't query the Link Device for IRQ information at this time
+	 *       because Link Device enumeration may not have occurred yet
+	 *       (e.g. exists somewhere 'below' this _PRT entry in the ACPI
+	 *       namespace).
+	 */
+	if (prt->source[0]) {
+		acpi_get_handle(handle, prt->source, &entry->link.handle);
+		entry->link.index = prt->source_index;
+	}
+	/*
+	 * Type 2: Static
+	 * --------------
+	 * The 'source' field is NULL, and the 'source_index' field specifies
+	 * the IRQ value, which is hardwired to specific interrupt inputs on
+	 * the interrupt controller.
+	 */
+	else
+		entry->link.index = prt->source_index;
+
+	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
+		"      %02X:%02X:%02X[%c] -> %s[%d]\n", 
+		entry->id.segment, entry->id.bus, entry->id.device, 
+		('A' + entry->pin), prt->source, entry->link.index));
+
+	spin_lock(&acpi_prt_lock);
+	list_add_tail(&entry->node, &acpi_prt.entries);
+	acpi_prt.count++;
+	spin_unlock(&acpi_prt_lock);
+
+	return_VALUE(0);
+}
+
+
+static void
+acpi_pci_irq_del_entry (
+	int				segment,
+	int				bus,
+	struct acpi_prt_entry		*entry)
+{
+	if (segment == entry->id.segment && bus == entry->id.bus){
+		acpi_prt.count--;
+		list_del(&entry->node);
+		kfree(entry);
+	}
+}
+
+
+int
+acpi_pci_irq_add_prt (
+	acpi_handle		handle,
+	int			segment,
+	int			bus)
+{
+	acpi_status			status = AE_OK;
+	char				*pathname = NULL;
+	struct acpi_buffer		buffer = {0, NULL};
+	struct acpi_pci_routing_table	*prt = NULL;
+	struct acpi_pci_routing_table	*entry = NULL;
+	static int			first_time = 1;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt");
+
+	pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
+	if(!pathname)
+		return_VALUE(-ENOMEM);
+	memset(pathname, 0, ACPI_PATHNAME_MAX);
+
+	if (first_time) {
+		acpi_prt.count = 0;
+		INIT_LIST_HEAD(&acpi_prt.entries);
+		first_time = 0;
+	}
+
+	/* 
+	 * NOTE: We're given a 'handle' to the _PRT object's parent device
+	 *       (either a PCI root bridge or PCI-PCI bridge).
+	 */
+
+	buffer.length = ACPI_PATHNAME_MAX;
+	buffer.pointer = pathname;
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+	printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
+		pathname);
+
+	/* 
+	 * Evaluate this _PRT and add its entries to our global list (acpi_prt).
+	 */
+
+	buffer.length = 0;
+	buffer.pointer = NULL;
+	kfree(pathname);
+	status = acpi_get_irq_routing_table(handle, &buffer);
+	if (status != AE_BUFFER_OVERFLOW) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
+			acpi_format_exception(status)));
+		return_VALUE(-ENODEV);
+	}
+
+	prt = kmalloc(buffer.length, GFP_KERNEL);
+	if (!prt){
+		return_VALUE(-ENOMEM);
+	}
+	memset(prt, 0, buffer.length);
+	buffer.pointer = prt;
+
+	status = acpi_get_irq_routing_table(handle, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n",
+			acpi_format_exception(status)));
+		kfree(buffer.pointer);
+		return_VALUE(-ENODEV);
+	}
+
+	entry = prt;
+
+	while (entry && (entry->length > 0)) {
+		acpi_pci_irq_add_entry(handle, segment, bus, entry);
+		entry = (struct acpi_pci_routing_table *)
+			((unsigned long) entry + entry->length);
+	}
+
+	kfree(prt);
+
+	return_VALUE(0);
+}
+
+void
+acpi_pci_irq_del_prt (int segment, int bus)
+{
+	struct list_head        *node = NULL, *n = NULL;
+	struct acpi_prt_entry   *entry = NULL;
+
+	if (!acpi_prt.count)    {
+		return;
+	}
+
+	printk(KERN_DEBUG "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n",
+		segment, bus);
+	spin_lock(&acpi_prt_lock);
+	list_for_each_safe(node, n, &acpi_prt.entries) {
+		entry = list_entry(node, struct acpi_prt_entry, node);
+
+		acpi_pci_irq_del_entry(segment, bus, entry);
+	}
+	spin_unlock(&acpi_prt_lock);
+}
+/* --------------------------------------------------------------------------
+                          PCI Interrupt Routing Support
+   -------------------------------------------------------------------------- */
+
+/*
+ * acpi_pci_irq_lookup
+ * success: return IRQ >= 0
+ * failure: return -1
+ */
+static int
+acpi_pci_irq_lookup (
+	struct pci_bus		*bus,
+	int			device,
+	int			pin,
+	int			*edge_level,
+	int			*active_high_low,
+	char			**link)
+{
+	struct acpi_prt_entry	*entry = NULL;
+	int segment = pci_domain_nr(bus);
+	int bus_nr = bus->number;
+	int irq;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+		"Searching for PRT entry for %02x:%02x:%02x[%c]\n", 
+		segment, bus_nr, device, ('A' + pin)));
+
+	entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin); 
+	if (!entry) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
+		return_VALUE(-1);
+	}
+	
+	if (entry->link.handle) {
+		irq = acpi_pci_link_get_irq(entry->link.handle,
+			entry->link.index, edge_level, active_high_low, link);
+		if (irq < 0) {
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
+			return_VALUE(-1);
+		}
+	} else {
+		irq = entry->link.index;
+		*edge_level = ACPI_LEVEL_SENSITIVE;
+		*active_high_low = ACPI_ACTIVE_LOW;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
+
+	return_VALUE(irq);
+}
+
+/*
+ * acpi_pci_irq_derive
+ * success: return IRQ >= 0
+ * failure: return < 0
+ */
+static int
+acpi_pci_irq_derive (
+	struct pci_dev		*dev,
+	int			pin,
+	int			*edge_level,
+	int			*active_high_low,
+	char			**link)
+{
+	struct pci_dev		*bridge = dev;
+	int			irq = -1;
+	u8			bridge_pin = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_derive");
+
+	if (!dev)
+		return_VALUE(-EINVAL);
+
+	/* 
+	 * Attempt to derive an IRQ for this device from a parent bridge's
+	 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
+	 */
+	while (irq < 0 && bridge->bus->self) {
+		pin = (pin + PCI_SLOT(bridge->devfn)) % 4;
+		bridge = bridge->bus->self;
+
+		if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
+			/* PC card has the same IRQ as its cardbridge */
+			pci_read_config_byte(bridge, PCI_INTERRUPT_PIN, &bridge_pin);
+			if (!bridge_pin) {
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+					"No interrupt pin configured for device %s\n", pci_name(bridge)));
+				return_VALUE(-1);
+			}
+			/* Pin is from 0 to 3 */
+			bridge_pin --;
+			pin = bridge_pin;
+		}
+
+		irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
+			pin, edge_level, active_high_low, link);
+	}
+
+	if (irq < 0) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to derive IRQ for device %s\n", pci_name(dev)));
+		return_VALUE(-1);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n",
+		irq, pci_name(dev), pci_name(bridge)));
+
+	return_VALUE(irq);
+}
+
+/*
+ * acpi_pci_irq_enable
+ * success: return 0
+ * failure: return < 0
+ */
+
+int
+acpi_pci_irq_enable (
+	struct pci_dev		*dev)
+{
+	int			irq = 0;
+	u8			pin = 0;
+	int			edge_level = ACPI_LEVEL_SENSITIVE;
+	int			active_high_low = ACPI_ACTIVE_LOW;
+	extern int		via_interrupt_line_quirk;
+	char			*link = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
+
+	if (!dev)
+		return_VALUE(-EINVAL);
+	
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (!pin) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", pci_name(dev)));
+		return_VALUE(0);
+	}
+	pin--;
+
+	if (!dev->bus) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) 'bus' field\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	/* 
+	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
+	 * values override any BIOS-assigned IRQs set during boot.
+	 */
+ 	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+		&edge_level, &active_high_low, &link);
+
+	/*
+	 * If no PRT entry was found, we'll try to derive an IRQ from the
+	 * device's parent bridge.
+	 */
+	if (irq < 0)
+ 		irq = acpi_pci_irq_derive(dev, pin, &edge_level,
+			&active_high_low, &link);
+ 
+	/*
+	 * No IRQ known to the ACPI subsystem - maybe the BIOS / 
+	 * driver reported one, then use it. Exit in any case.
+	 */
+	if (irq < 0) {
+		printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
+			pci_name(dev), ('A' + pin));
+		/* Interrupt Line values above 0xF are forbidden */
+		if (dev->irq >= 0 && (dev->irq <= 0xF)) {
+			printk(" - using IRQ %d\n", dev->irq);
+			return_VALUE(0);
+		}
+		else {
+			printk("\n");
+			return_VALUE(0);
+		}
+ 	}
+
+	if (via_interrupt_line_quirk)
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15);
+
+	dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
+
+	printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
+		pci_name(dev), 'A' + pin);
+
+	if (link)
+		printk("Link [%s] -> ", link);
+
+	printk("GSI %u (%s, %s) -> IRQ %d\n", irq,
+		(edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
+		(active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high",
+		dev->irq);
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_pci_irq_enable);
+
+
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+void
+acpi_pci_irq_disable (
+	struct pci_dev		*dev)
+{
+	int			gsi = 0;
+	u8			pin = 0;
+	int			edge_level = ACPI_LEVEL_SENSITIVE;
+	int			active_high_low = ACPI_ACTIVE_LOW;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_irq_disable");
+
+	if (!dev)
+		return_VOID;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (!pin)
+		return_VOID;
+	pin--;
+
+	if (!dev->bus)
+		return_VOID;
+
+	/*
+	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
+	 */
+ 	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+				  &edge_level, &active_high_low, NULL);
+	/*
+	 * If no PRT entry was found, we'll try to derive an IRQ from the
+	 * device's parent bridge.
+	 */
+	if (gsi < 0)
+ 		gsi = acpi_pci_irq_derive(dev, pin,
+					  &edge_level, &active_high_low, NULL);
+	if (gsi < 0)
+		return_VOID;
+
+	/*
+	 * TBD: It might be worth clearing dev->irq by magic constant
+	 * (e.g. PCI_UNDEFINED_IRQ).
+	 */
+
+	printk(KERN_INFO PREFIX "PCI interrupt for device %s disabled\n",
+	       pci_name(dev));
+
+	acpi_unregister_gsi(gsi);
+
+	return_VOID;
+}
+#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
new file mode 100644
index 0000000..520b28a
--- /dev/null
+++ b/drivers/acpi/pci_link.c
@@ -0,0 +1,904 @@
+/*
+ *  pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2002       Dominik Brodowski <devel@brodo.de>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * TBD: 
+ *      1. Support more than one IRQ resource entry per link device (index).
+ *	2. Implement start/stop mechanism and use ACPI Bus Driver facilities
+ *	   for IRQ management (e.g. start()->_SRS).
+ */
+
+#include <linux/sysdev.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <linux/pci.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_PCI_COMPONENT
+ACPI_MODULE_NAME		("pci_link")
+
+#define ACPI_PCI_LINK_CLASS		"pci_irq_routing"
+#define ACPI_PCI_LINK_HID		"PNP0C0F"
+#define ACPI_PCI_LINK_DRIVER_NAME	"ACPI PCI Interrupt Link Driver"
+#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
+
+static int acpi_pci_link_add (struct acpi_device *device);
+static int acpi_pci_link_remove (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_pci_link_driver = {
+	.name =		ACPI_PCI_LINK_DRIVER_NAME,
+	.class =	ACPI_PCI_LINK_CLASS,
+	.ids =		ACPI_PCI_LINK_HID,
+	.ops =		{
+				.add =    acpi_pci_link_add,
+				.remove = acpi_pci_link_remove,
+			},
+};
+
+struct acpi_pci_link_irq {
+	u8			active;			/* Current IRQ */
+	u8			edge_level;		/* All IRQs */
+	u8			active_high_low;	/* All IRQs */
+	u8			initialized;
+	u8			resource_type;
+	u8			possible_count;
+	u8			possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+};
+
+struct acpi_pci_link {
+	struct list_head	node;
+	struct acpi_device	*device;
+	acpi_handle		handle;
+	struct acpi_pci_link_irq irq;
+};
+
+static struct {
+	int			count;
+	struct list_head	entries;
+}				acpi_link;
+
+
+/* --------------------------------------------------------------------------
+                            PCI Link Device Management
+   -------------------------------------------------------------------------- */
+
+/*
+ * set context (link) possible list from resource list
+ */
+static acpi_status
+acpi_pci_link_check_possible (
+	struct acpi_resource	*resource,
+	void			*context)
+{
+	struct acpi_pci_link	*link = (struct acpi_pci_link *) context;
+	u32			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible");
+
+	switch (resource->id) {
+	case ACPI_RSTYPE_START_DPF:
+		return_ACPI_STATUS(AE_OK);
+	case ACPI_RSTYPE_IRQ:
+	{
+		struct acpi_resource_irq *p = &resource->data.irq;
+		if (!p || !p->number_of_interrupts) {
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n"));
+			return_ACPI_STATUS(AE_OK);
+		}
+		for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
+			if (!p->interrupts[i]) {
+				ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i]));
+				continue;
+			}
+			link->irq.possible[i] = p->interrupts[i];
+			link->irq.possible_count++;
+		}
+		link->irq.edge_level = p->edge_level;
+		link->irq.active_high_low = p->active_high_low;
+		link->irq.resource_type = ACPI_RSTYPE_IRQ;
+		break;
+	}
+	case ACPI_RSTYPE_EXT_IRQ:
+	{
+		struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
+		if (!p || !p->number_of_interrupts) {
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
+				"Blank EXT IRQ resource\n"));
+			return_ACPI_STATUS(AE_OK);
+		}
+		for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
+			if (!p->interrupts[i]) {
+				ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i]));
+				continue;
+			}
+			link->irq.possible[i] = p->interrupts[i];
+			link->irq.possible_count++;
+		}
+		link->irq.edge_level = p->edge_level;
+		link->irq.active_high_low = p->active_high_low;
+		link->irq.resource_type = ACPI_RSTYPE_EXT_IRQ;
+		break;
+	}
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Resource is not an IRQ entry\n"));
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	return_ACPI_STATUS(AE_CTRL_TERMINATE);
+}
+
+
+static int
+acpi_pci_link_get_possible (
+	struct acpi_pci_link	*link)
+{
+	acpi_status		status;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible");
+
+	if (!link)
+		return_VALUE(-EINVAL);
+
+	status = acpi_walk_resources(link->handle, METHOD_NAME__PRS,
+			acpi_pci_link_check_possible, link);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+		"Found %d possible IRQs\n", link->irq.possible_count));
+
+	return_VALUE(0);
+}
+
+
+static acpi_status
+acpi_pci_link_check_current (
+	struct acpi_resource	*resource,
+	void			*context)
+{
+	int			*irq = (int *) context;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_check_current");
+
+	switch (resource->id) {
+	case ACPI_RSTYPE_IRQ:
+	{
+		struct acpi_resource_irq *p = &resource->data.irq;
+		if (!p || !p->number_of_interrupts) {
+			/*
+			 * IRQ descriptors may have no IRQ# bits set,
+			 * particularly those those w/ _STA disabled
+			 */
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				"Blank IRQ resource\n")); 
+			return_ACPI_STATUS(AE_OK);
+		}
+		*irq = p->interrupts[0];
+		break;
+	}
+	case ACPI_RSTYPE_EXT_IRQ:
+	{
+		struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
+		if (!p || !p->number_of_interrupts) {
+			/*
+			 * extended IRQ descriptors must
+			 * return at least 1 IRQ
+			 */
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+				"Blank EXT IRQ resource\n"));
+			return_ACPI_STATUS(AE_OK);
+		}
+		*irq = p->interrupts[0];
+		break;
+	}
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Resource isn't an IRQ\n"));
+		return_ACPI_STATUS(AE_OK);
+	}
+	return_ACPI_STATUS(AE_CTRL_TERMINATE);
+}
+
+/*
+ * Run _CRS and set link->irq.active
+ *
+ * return value:
+ * 0 - success
+ * !0 - failure
+ */
+static int
+acpi_pci_link_get_current (
+	struct acpi_pci_link	*link)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	int			irq = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_get_current");
+
+	if (!link || !link->handle)
+		return_VALUE(-EINVAL);
+
+	link->irq.active = 0;
+
+	/* in practice, status disabled is meaningless, ignore it */
+	if (acpi_strict) {
+		/* Query _STA, set link->device->status */
+		result = acpi_bus_get_status(link->device);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
+			goto end;
+		}
+
+		if (!link->device->status.enabled) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n"));
+			return_VALUE(0);
+		}
+	}
+
+	/* 
+	 * Query and parse _CRS to get the current IRQ assignment. 
+	 */
+
+	status = acpi_walk_resources(link->handle, METHOD_NAME__CRS,
+			acpi_pci_link_check_current, &irq);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	if (acpi_strict && !irq) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "_CRS returned 0\n"));
+		result = -ENODEV;
+	}
+
+	link->irq.active = irq;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
+
+end:
+	return_VALUE(result);
+}
+
+static int
+acpi_pci_link_set (
+	struct acpi_pci_link	*link,
+	int			irq)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct {
+		struct acpi_resource	res;
+		struct acpi_resource	end;
+	}    *resource;
+	struct acpi_buffer	buffer = {0, NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_set");
+
+	if (!link || !irq)
+		return_VALUE(-EINVAL);
+
+	resource = kmalloc( sizeof(*resource)+1, GFP_KERNEL);
+	if(!resource)
+		return_VALUE(-ENOMEM);
+
+	memset(resource, 0, sizeof(*resource)+1);
+	buffer.length = sizeof(*resource) +1;
+	buffer.pointer = resource;
+
+	switch(link->irq.resource_type) {
+	case ACPI_RSTYPE_IRQ:
+		resource->res.id = ACPI_RSTYPE_IRQ;
+		resource->res.length = sizeof(struct acpi_resource);
+		resource->res.data.irq.edge_level = link->irq.edge_level;
+		resource->res.data.irq.active_high_low = link->irq.active_high_low;
+		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
+			resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+		else
+			resource->res.data.irq.shared_exclusive = ACPI_SHARED;
+		resource->res.data.irq.number_of_interrupts = 1;
+		resource->res.data.irq.interrupts[0] = irq;
+		break;
+	   
+	case ACPI_RSTYPE_EXT_IRQ:
+		resource->res.id = ACPI_RSTYPE_EXT_IRQ;
+		resource->res.length = sizeof(struct acpi_resource);
+		resource->res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
+		resource->res.data.extended_irq.edge_level = link->irq.edge_level;
+		resource->res.data.extended_irq.active_high_low = link->irq.active_high_low;
+		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
+			resource->res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+		else
+			resource->res.data.irq.shared_exclusive = ACPI_SHARED;
+		resource->res.data.extended_irq.number_of_interrupts = 1;
+		resource->res.data.extended_irq.interrupts[0] = irq;
+		/* ignore resource_source, it's optional */
+		break;
+	default:
+		printk("ACPI BUG: resource_type %d\n", link->irq.resource_type);
+		result = -EINVAL;
+		goto end;
+
+	}
+	resource->end.id = ACPI_RSTYPE_END_TAG;
+
+	/* Attempt to set the resource */
+	status = acpi_set_current_resources(link->handle, &buffer);
+
+	/* check for total failure */
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	/* Query _STA, set device->status */
+	result = acpi_bus_get_status(link->device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n"));
+		goto end;
+	}
+	if (!link->device->status.enabled) {
+		printk(KERN_WARNING PREFIX
+			"%s [%s] disabled and referenced, BIOS bug.\n",
+			acpi_device_name(link->device),
+			acpi_device_bid(link->device));
+	}
+
+	/* Query _CRS, set link->irq.active */
+	result = acpi_pci_link_get_current(link);
+	if (result) {
+		goto end;
+	}
+
+	/*
+	 * Is current setting not what we set?
+	 * set link->irq.active
+	 */
+	if (link->irq.active != irq) {
+		/*
+		 * policy: when _CRS doesn't return what we just _SRS
+		 * assume _SRS worked and override _CRS value.
+		 */
+		printk(KERN_WARNING PREFIX 
+			"%s [%s] BIOS reported IRQ %d, using IRQ %d\n",
+			acpi_device_name(link->device),
+			acpi_device_bid(link->device),
+			link->irq.active, irq);
+		link->irq.active = irq;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
+	
+end:
+	kfree(resource);
+	return_VALUE(result);
+}
+
+
+/* --------------------------------------------------------------------------
+                            PCI Link IRQ Management
+   -------------------------------------------------------------------------- */
+
+/*
+ * "acpi_irq_balance" (default in APIC mode) enables ACPI to use PIC Interrupt
+ * Link Devices to move the PIRQs around to minimize sharing.
+ * 
+ * "acpi_irq_nobalance" (default in PIC mode) tells ACPI not to move any PIC IRQs
+ * that the BIOS has already set to active.  This is necessary because
+ * ACPI has no automatic means of knowing what ISA IRQs are used.  Note that
+ * if the BIOS doesn't set a Link Device active, ACPI needs to program it
+ * even if acpi_irq_nobalance is set.
+ *
+ * A tables of penalties avoids directing PCI interrupts to well known
+ * ISA IRQs. Boot params are available to over-ride the default table:
+ *
+ * List interrupts that are free for PCI use.
+ * acpi_irq_pci=n[,m]
+ *
+ * List interrupts that should not be used for PCI:
+ * acpi_irq_isa=n[,m]
+ *
+ * Note that PCI IRQ routers have a list of possible IRQs,
+ * which may not include the IRQs this table says are available.
+ * 
+ * Since this heuristic can't tell the difference between a link
+ * that no device will attach to, vs. a link which may be shared
+ * by multiple active devices -- it is not optimal.
+ *
+ * If interrupt performance is that important, get an IO-APIC system
+ * with a pin dedicated to each device.  Or for that matter, an MSI
+ * enabled system.
+ */
+
+#define ACPI_MAX_IRQS		256
+#define ACPI_MAX_ISA_IRQ	16
+
+#define PIRQ_PENALTY_PCI_AVAILABLE	(0)
+#define PIRQ_PENALTY_PCI_POSSIBLE	(16*16)
+#define PIRQ_PENALTY_PCI_USING		(16*16*16)
+#define PIRQ_PENALTY_ISA_TYPICAL	(16*16*16*16)
+#define PIRQ_PENALTY_ISA_USED		(16*16*16*16*16)
+#define PIRQ_PENALTY_ISA_ALWAYS		(16*16*16*16*16*16)
+
+static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
+	PIRQ_PENALTY_ISA_ALWAYS,	/* IRQ0 timer */
+	PIRQ_PENALTY_ISA_ALWAYS,	/* IRQ1 keyboard */
+	PIRQ_PENALTY_ISA_ALWAYS,	/* IRQ2 cascade */
+	PIRQ_PENALTY_ISA_TYPICAL,	/* IRQ3	serial */
+	PIRQ_PENALTY_ISA_TYPICAL,	/* IRQ4	serial */
+	PIRQ_PENALTY_ISA_TYPICAL,	/* IRQ5 sometimes SoundBlaster */
+	PIRQ_PENALTY_ISA_TYPICAL,	/* IRQ6 */
+	PIRQ_PENALTY_ISA_TYPICAL,	/* IRQ7 parallel, spurious */
+	PIRQ_PENALTY_ISA_TYPICAL,	/* IRQ8 rtc, sometimes */
+	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 */
+			/* >IRQ15 */
+};
+
+int __init
+acpi_irq_penalty_init(void)
+{
+	struct list_head	*node = NULL;
+	struct acpi_pci_link    *link = NULL;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_irq_penalty_init");
+
+	/*
+	 * Update penalties to facilitate IRQ balancing.
+	 */
+	list_for_each(node, &acpi_link.entries) {
+
+		link = list_entry(node, struct acpi_pci_link, node);
+		if (!link) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+			continue;
+		}
+
+		/*
+		 * reflect the possible and active irqs in the penalty table --
+		 * useful for breaking ties.
+		 */
+		if (link->irq.possible_count) {
+			int penalty = PIRQ_PENALTY_PCI_POSSIBLE / link->irq.possible_count;
+
+			for (i = 0; i < link->irq.possible_count; i++) {
+				if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
+					acpi_irq_penalty[link->irq.possible[i]] += penalty;
+			}
+
+		} else if (link->irq.active) {
+			acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_POSSIBLE;
+		}
+	}
+	/* Add a penalty for the SCI */
+	acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING;
+
+	return_VALUE(0);
+}
+
+static int acpi_irq_balance;	/* 0: static, 1: balance */
+
+static int acpi_pci_link_allocate(
+	struct acpi_pci_link	*link)
+{
+	int			irq;
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
+
+	if (link->irq.initialized)
+		return_VALUE(0);
+
+	/*
+	 * search for active IRQ in list of possible IRQs.
+	 */
+	for (i = 0; i < link->irq.possible_count; ++i) {
+		if (link->irq.active == link->irq.possible[i])
+			break;
+	}
+	/*
+	 * forget active IRQ that is not in possible list
+	 */
+	if (i == link->irq.possible_count) {
+		if (acpi_strict)
+			printk(KERN_WARNING PREFIX "_CRS %d not found"
+				" in _PRS\n", link->irq.active);
+		link->irq.active = 0;
+	}
+
+	/*
+	 * if active found, use it; else pick entry from end of possible list.
+	 */
+	if (link->irq.active) {
+		irq = link->irq.active;
+	} else {
+		irq = link->irq.possible[link->irq.possible_count - 1];
+	}
+
+	if (acpi_irq_balance || !link->irq.active) {
+		/*
+		 * Select the best IRQ.  This is done in reverse to promote
+		 * the use of IRQs 9, 10, 11, and >15.
+		 */
+		for (i = (link->irq.possible_count - 1); i >= 0; i--) {
+			if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
+				irq = link->irq.possible[i];
+		}
+	}
+
+	/* Attempt to enable the link device at this IRQ. */
+	if (acpi_pci_link_set(link, irq)) {
+		printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS).\n"
+				"Try pci=noacpi or acpi=off\n",
+			acpi_device_name(link->device),
+			acpi_device_bid(link->device));
+		return_VALUE(-ENODEV);
+	} else {
+		acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
+		printk(PREFIX "%s [%s] enabled at IRQ %d\n", 
+			acpi_device_name(link->device),
+			acpi_device_bid(link->device), link->irq.active);
+	}
+
+	link->irq.initialized = 1;
+
+	return_VALUE(0);
+}
+
+/*
+ * acpi_pci_link_get_irq
+ * success: return IRQ >= 0
+ * failure: return -1
+ */
+
+int
+acpi_pci_link_get_irq (
+	acpi_handle		handle,
+	int			index,
+	int			*edge_level,
+	int			*active_high_low,
+	char			**name)
+{
+	int                     result = 0;
+	struct acpi_device	*device = NULL;
+	struct acpi_pci_link	*link = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_get_irq");
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n"));
+		return_VALUE(-1);
+	}
+
+	link = (struct acpi_pci_link *) acpi_driver_data(device);
+	if (!link) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+		return_VALUE(-1);
+	}
+
+	/* TBD: Support multiple index (IRQ) entries per Link Device */
+	if (index) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid index %d\n", index));
+		return_VALUE(-1);
+	}
+
+	if (acpi_pci_link_allocate(link))
+		return_VALUE(-1);
+	   
+	if (!link->irq.active) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
+		return_VALUE(-1);
+	}
+
+	if (edge_level) *edge_level = link->irq.edge_level;
+	if (active_high_low) *active_high_low = link->irq.active_high_low;
+	if (name) *name = acpi_device_bid(link->device);
+	return_VALUE(link->irq.active);
+}
+
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_pci_link_add (
+	struct acpi_device *device)
+{
+	int			result = 0;
+	struct acpi_pci_link	*link = NULL;
+	int			i = 0;
+	int			found = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
+	if (!link)
+		return_VALUE(-ENOMEM);
+	memset(link, 0, sizeof(struct acpi_pci_link));
+
+	link->device = device;
+	link->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
+	acpi_driver_data(device) = link;
+
+	result = acpi_pci_link_get_possible(link);
+	if (result)
+		goto end;
+
+	/* query and set link->irq.active */
+	acpi_pci_link_get_current(link);
+
+	printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device),
+		acpi_device_bid(device));
+	for (i = 0; i < link->irq.possible_count; i++) {
+		if (link->irq.active == link->irq.possible[i]) {
+			printk(" *%d", link->irq.possible[i]);
+			found = 1;
+		}
+		else
+			printk(" %d", link->irq.possible[i]);
+	}
+
+	printk(")");
+
+	if (!found)
+		printk(" *%d", link->irq.active);
+
+	if(!link->device->status.enabled)
+		printk(", disabled.");
+
+	printk("\n");
+
+	/* TBD: Acquire/release lock */
+	list_add_tail(&link->node, &acpi_link.entries);
+	acpi_link.count++;
+
+end:
+	/* disable all links -- to be activated on use */
+	acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+
+	if (result)
+		kfree(link);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_pci_link_resume (
+	struct acpi_pci_link	*link)
+{
+	ACPI_FUNCTION_TRACE("acpi_pci_link_resume");
+	
+	if (link->irq.active && link->irq.initialized)
+		return_VALUE(acpi_pci_link_set(link, link->irq.active));
+	else
+		return_VALUE(0);
+}
+
+
+static int
+irqrouter_resume(
+	struct sys_device *dev)
+{
+	struct list_head        *node = NULL;
+	struct acpi_pci_link    *link = NULL;
+
+	ACPI_FUNCTION_TRACE("irqrouter_resume");
+
+	list_for_each(node, &acpi_link.entries) {
+
+		link = list_entry(node, struct acpi_pci_link, node);
+		if (!link) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+			continue;
+		}
+
+		acpi_pci_link_resume(link);
+	}
+	return_VALUE(0);
+}
+
+
+static int
+acpi_pci_link_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	struct acpi_pci_link *link = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	link = (struct acpi_pci_link *) acpi_driver_data(device);
+
+	/* TBD: Acquire/release lock */
+	list_del(&link->node);
+
+	kfree(link);
+
+	return_VALUE(0);
+}
+
+/*
+ * modify acpi_irq_penalty[] from cmdline
+ */
+static int __init acpi_irq_penalty_update(char *str, int used)
+{
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		int retval;
+		int irq;
+
+		retval = get_option(&str,&irq);
+
+		if (!retval)
+			break;	/* no number found */
+
+		if (irq < 0)
+			continue;
+		
+		if (irq >= ACPI_MAX_IRQS)
+			continue;
+
+		if (used)
+			acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
+		else
+			acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE;
+
+		if (retval != 2)	/* no next number */
+			break;
+	}
+	return 1;
+}
+
+/*
+ * We'd like PNP to call this routine for the
+ * single ISA_USED value for each legacy device.
+ * But instead it calls us with each POSSIBLE setting.
+ * There is no ISA_POSSIBLE weight, so we simply use
+ * the (small) PCI_USING penalty.
+ */
+void acpi_penalize_isa_irq(int irq)
+{
+	acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
+}
+
+/*
+ * Over-ride default table to reserve additional IRQs for use by ISA
+ * e.g. acpi_irq_isa=5
+ * Useful for telling ACPI how not to interfere with your ISA sound card.
+ */
+static int __init acpi_irq_isa(char *str)
+{
+	return acpi_irq_penalty_update(str, 1);
+}
+__setup("acpi_irq_isa=", acpi_irq_isa);
+
+/*
+ * Over-ride default table to free additional IRQs for use by PCI
+ * e.g. acpi_irq_pci=7,15
+ * Used for acpi_irq_balance to free up IRQs to reduce PCI IRQ sharing.
+ */
+static int __init acpi_irq_pci(char *str)
+{
+	return acpi_irq_penalty_update(str, 0);
+}
+__setup("acpi_irq_pci=", acpi_irq_pci);
+
+static int __init acpi_irq_nobalance_set(char *str)
+{
+	acpi_irq_balance = 0;
+	return 1;
+}
+__setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
+
+int __init acpi_irq_balance_set(char *str)
+{
+	acpi_irq_balance = 1;
+	return 1;
+}
+__setup("acpi_irq_balance", acpi_irq_balance_set);
+
+
+static struct sysdev_class irqrouter_sysdev_class = {
+        set_kset_name("irqrouter"),
+        .resume = irqrouter_resume,
+};
+
+
+static struct sys_device device_irqrouter = {
+	.id     = 0,
+	.cls    = &irqrouter_sysdev_class,
+};
+
+
+static int __init irqrouter_init_sysfs(void)
+{
+	int error;
+
+	ACPI_FUNCTION_TRACE("irqrouter_init_sysfs");
+
+	if (acpi_disabled || acpi_noirq)
+		return_VALUE(0);
+
+	error = sysdev_class_register(&irqrouter_sysdev_class);
+	if (!error)
+		error = sysdev_register(&device_irqrouter);
+
+	return_VALUE(error);
+}                                        
+
+device_initcall(irqrouter_init_sysfs);
+
+
+static int __init acpi_pci_link_init (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_pci_link_init");
+
+	if (acpi_noirq)
+		return_VALUE(0);
+
+	acpi_link.count = 0;
+	INIT_LIST_HEAD(&acpi_link.entries);
+
+	if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
+		return_VALUE(-ENODEV);
+
+	return_VALUE(0);
+}
+
+subsys_initcall(acpi_pci_link_init);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
new file mode 100644
index 0000000..7e6b8e3
--- /dev/null
+++ b/drivers/acpi/pci_root.c
@@ -0,0 +1,347 @@
+/*
+ *  pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 40 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_PCI_COMPONENT
+ACPI_MODULE_NAME		("pci_root")
+
+#define ACPI_PCI_ROOT_CLASS		"pci_bridge"
+#define ACPI_PCI_ROOT_HID		"PNP0A03"
+#define ACPI_PCI_ROOT_DRIVER_NAME	"ACPI PCI Root Bridge Driver"
+#define ACPI_PCI_ROOT_DEVICE_NAME	"PCI Root Bridge"
+
+static int acpi_pci_root_add (struct acpi_device *device);
+static int acpi_pci_root_remove (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_pci_root_driver = {
+	.name =		ACPI_PCI_ROOT_DRIVER_NAME,
+	.class =	ACPI_PCI_ROOT_CLASS,
+	.ids =		ACPI_PCI_ROOT_HID,
+	.ops =		{
+				.add =    acpi_pci_root_add,
+				.remove = acpi_pci_root_remove,
+			},
+};
+
+struct acpi_pci_root {
+	struct list_head	node;
+	acpi_handle		handle;
+	struct acpi_pci_id	id;
+	struct pci_bus		*bus;
+};
+
+static LIST_HEAD(acpi_pci_roots);
+
+static struct acpi_pci_driver *sub_driver;
+
+int acpi_pci_register_driver(struct acpi_pci_driver *driver)
+{
+	int n = 0;
+	struct list_head *entry;
+
+	struct acpi_pci_driver **pptr = &sub_driver;
+	while (*pptr)
+		pptr = &(*pptr)->next;
+	*pptr = driver;
+
+	if (!driver->add)
+		return 0;
+
+	list_for_each(entry, &acpi_pci_roots) {
+		struct acpi_pci_root *root;
+		root = list_entry(entry, struct acpi_pci_root, node);
+		driver->add(root->handle);
+		n++;
+	}
+
+	return n;
+}
+EXPORT_SYMBOL(acpi_pci_register_driver);
+
+void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
+{
+	struct list_head *entry;
+
+	struct acpi_pci_driver **pptr = &sub_driver;
+	while (*pptr) {
+		if (*pptr != driver)
+			continue;
+		*pptr = (*pptr)->next;
+		break;
+	}
+
+	if (!driver->remove)
+		return;
+
+	list_for_each(entry, &acpi_pci_roots) {
+		struct acpi_pci_root *root;
+		root = list_entry(entry, struct acpi_pci_root, node);
+		driver->remove(root->handle);
+	}
+}
+EXPORT_SYMBOL(acpi_pci_unregister_driver);
+
+static acpi_status
+get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data)
+{
+	int *busnr = (int *)data;
+	struct acpi_resource_address64 address;
+
+	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS64)
+		return AE_OK;
+
+	acpi_resource_to_address64(resource, &address);
+	if ((address.address_length > 0) && 
+	   (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+		*busnr = address.min_address_range;
+
+	return AE_OK;
+}
+
+static acpi_status 
+try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
+{
+	acpi_status status;
+
+	*busnum = -1;
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS, get_root_bridge_busnr_callback, busnum);
+	if (ACPI_FAILURE(status))
+		return status;
+	/* Check if we really get a bus number from _CRS */
+	if (*busnum == -1)
+		return AE_ERROR;
+	return AE_OK;
+}
+
+static int
+acpi_pci_root_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	struct acpi_pci_root	*root = NULL;
+	struct acpi_pci_root	*tmp;
+	acpi_status		status = AE_OK;
+	unsigned long		value = 0;
+	acpi_handle		handle = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_root_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
+	if (!root)
+		return_VALUE(-ENOMEM);
+	memset(root, 0, sizeof(struct acpi_pci_root));
+
+	root->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
+	acpi_driver_data(device) = root;
+
+	/*
+	 * TBD: Doesn't the bus driver automatically set this?
+	 */
+	device->ops.bind = acpi_pci_bind;
+
+	/* 
+	 * Segment
+	 * -------
+	 * Obtained via _SEG, if exists, otherwise assumed to be zero (0).
+	 */
+	status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL, 
+		&value);
+	switch (status) {
+	case AE_OK:
+		root->id.segment = (u16) value;
+		break;
+	case AE_NOT_FOUND:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"Assuming segment 0 (no _SEG)\n"));
+		root->id.segment = 0;
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SEG\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	/* 
+	 * Bus
+	 * ---
+	 * Obtained via _BBN, if exists, otherwise assumed to be zero (0).
+	 */
+	status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL, 
+		&value);
+	switch (status) {
+	case AE_OK:
+		root->id.bus = (u16) value;
+		break;
+	case AE_NOT_FOUND:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n"));
+		root->id.bus = 0;
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BBN\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	/* Some systems have wrong _BBN */
+	list_for_each_entry(tmp, &acpi_pci_roots, node) {
+		if ((tmp->id.segment == root->id.segment)
+				&& (tmp->id.bus == root->id.bus)) {
+			int bus = 0;
+			acpi_status status;
+
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				"Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
+
+			status = try_get_root_bridge_busnr(root->handle, &bus);
+			if (ACPI_FAILURE(status))
+				break;
+			if (bus != root->id.bus) {
+				printk(KERN_INFO PREFIX "PCI _CRS %d overrides _BBN 0\n", bus);
+				root->id.bus = bus;
+			}
+			break;
+		}
+	}
+	/*
+	 * Device & Function
+	 * -----------------
+	 * Obtained from _ADR (which has already been evaluated for us).
+	 */
+	root->id.device = device->pnp.bus_address >> 16;
+	root->id.function = device->pnp.bus_address & 0xFFFF;
+
+	/*
+	 * TBD: Need PCI interface for enumeration/configuration of roots.
+	 */
+
+ 	/* TBD: Locking */
+ 	list_add_tail(&root->node, &acpi_pci_roots);
+
+	printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", 
+		acpi_device_name(device), acpi_device_bid(device),
+		root->id.segment, root->id.bus);
+
+	/*
+	 * Scan the Root Bridge
+	 * --------------------
+	 * Must do this prior to any attempt to bind the root device, as the
+	 * PCI namespace does not get created until this call is made (and 
+	 * thus the root bridge's pci_dev does not exist).
+	 */
+	root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus);
+	if (!root->bus) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Bus %04x:%02x not present in PCI namespace\n", 
+			root->id.segment, root->id.bus));
+		result = -ENODEV;
+		goto end;
+	}
+
+	/*
+	 * Attach ACPI-PCI Context
+	 * -----------------------
+	 * Thus binding the ACPI and PCI devices.
+	 */
+	result = acpi_pci_bind_root(device, &root->id, root->bus);
+	if (result)
+		goto end;
+
+	/*
+	 * PCI Routing Table
+	 * -----------------
+	 * Evaluate and parse _PRT, if exists.
+	 */
+	status = acpi_get_handle(root->handle, METHOD_NAME__PRT, &handle);
+	if (ACPI_SUCCESS(status))
+		result = acpi_pci_irq_add_prt(root->handle, root->id.segment,
+			root->id.bus);
+
+end:
+	if (result)
+		kfree(root);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_pci_root_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	struct acpi_pci_root	*root = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_root_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	root = (struct acpi_pci_root *) acpi_driver_data(device);
+
+	kfree(root);
+
+	return_VALUE(0);
+}
+
+
+static int __init acpi_pci_root_init (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_pci_root_init");
+
+	if (acpi_pci_disabled)
+		return_VALUE(0);
+
+	/* DEBUG:
+	acpi_dbg_layer = ACPI_PCI_COMPONENT;
+	acpi_dbg_level = 0xFFFFFFFF;
+	 */
+
+	if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
+		return_VALUE(-ENODEV);
+
+	return_VALUE(0);
+}
+
+subsys_initcall(acpi_pci_root_init);
+
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
new file mode 100644
index 0000000..373a3a9
--- /dev/null
+++ b/drivers/acpi/power.c
@@ -0,0 +1,692 @@
+/*
+ *  acpi_power.c - ACPI Bus Power Management ($Revision: 39 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+/*
+ * ACPI power-managed devices may be controlled in two ways:
+ * 1. via "Device Specific (D-State) Control"
+ * 2. via "Power Resource Control".
+ * This module is used to manage devices relying on Power Resource Control.
+ * 
+ * An ACPI "power resource object" describes a software controllable power
+ * plane, clock plane, or other resource used by a power managed device.
+ * A device may rely on multiple power resources, and a power resource
+ * may be shared by multiple devices.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_POWER_COMPONENT
+ACPI_MODULE_NAME		("acpi_power")
+
+#define ACPI_POWER_COMPONENT		0x00800000
+#define ACPI_POWER_CLASS		"power_resource"
+#define ACPI_POWER_DRIVER_NAME		"ACPI Power Resource Driver"
+#define ACPI_POWER_DEVICE_NAME		"Power Resource"
+#define ACPI_POWER_FILE_INFO		"info"
+#define ACPI_POWER_FILE_STATUS		"state"
+#define ACPI_POWER_RESOURCE_STATE_OFF	0x00
+#define ACPI_POWER_RESOURCE_STATE_ON	0x01
+#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
+
+static int acpi_power_add (struct acpi_device *device);
+static int acpi_power_remove (struct acpi_device *device, int type);
+static int acpi_power_open_fs(struct inode *inode, struct file *file);
+
+static struct acpi_driver acpi_power_driver = {
+	.name =		ACPI_POWER_DRIVER_NAME,
+	.class =	ACPI_POWER_CLASS,
+	.ids =		ACPI_POWER_HID,
+	.ops =		{
+				.add =		acpi_power_add,
+				.remove =	acpi_power_remove,
+			},
+};
+
+struct acpi_power_resource
+{
+	acpi_handle		handle;
+	acpi_bus_id		name;
+	u32			system_level;
+	u32			order;
+	int			state;
+	int			references;
+};
+
+static struct list_head		acpi_power_resource_list;
+
+static struct file_operations acpi_power_fops = {
+	.open		= acpi_power_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+/* --------------------------------------------------------------------------
+                             Power Resource Management
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_power_get_context (
+	acpi_handle		handle,
+	struct acpi_power_resource **resource)
+{
+	int			result = 0;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_power_get_context");
+
+	if (!resource)
+		return_VALUE(-ENODEV);
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context [%p]\n",
+			handle));
+		return_VALUE(result);
+	}
+
+	*resource = (struct acpi_power_resource *) acpi_driver_data(device);
+	if (!resource)
+		return_VALUE(-ENODEV);
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_power_get_state (
+	struct acpi_power_resource *resource)
+{
+	acpi_status		status = AE_OK;
+	unsigned long		sta = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_power_get_state");
+
+	if (!resource)
+		return_VALUE(-EINVAL);
+
+	status = acpi_evaluate_integer(resource->handle, "_STA", NULL, &sta);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	if (sta & 0x01)
+		resource->state = ACPI_POWER_RESOURCE_STATE_ON;
+	else
+		resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
+		resource->name, resource->state?"on":"off"));
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_power_get_list_state (
+	struct acpi_handle_list	*list,
+	int			*state)
+{
+	int			result = 0;
+	struct acpi_power_resource *resource = NULL;
+	u32			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_power_get_list_state");
+
+	if (!list || !state)
+		return_VALUE(-EINVAL);
+
+	/* The state of the list is 'on' IFF all resources are 'on'. */
+
+	for (i=0; i<list->count; i++) {
+		result = acpi_power_get_context(list->handles[i], &resource);
+		if (result)
+			return_VALUE(result);
+		result = acpi_power_get_state(resource);
+		if (result)
+			return_VALUE(result);
+
+		*state = resource->state;
+
+		if (*state != ACPI_POWER_RESOURCE_STATE_ON)
+			break;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
+		*state?"on":"off"));
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_power_on (
+	acpi_handle		handle)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_device	*device = NULL;
+	struct acpi_power_resource *resource = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_power_on");
+
+	result = acpi_power_get_context(handle, &resource);
+	if (result)
+		return_VALUE(result);
+
+	resource->references++;
+
+	if ((resource->references > 1) 
+		|| (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
+			resource->name));
+		return_VALUE(0);
+	}
+
+	status = acpi_evaluate_object(resource->handle, "_ON", NULL, NULL);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	result = acpi_power_get_state(resource);
+	if (result)
+		return_VALUE(result);
+	if (resource->state != ACPI_POWER_RESOURCE_STATE_ON)
+		return_VALUE(-ENOEXEC);
+
+	/* Update the power resource's _device_ power state */
+	result = acpi_bus_get_device(resource->handle, &device);
+	if (result)
+		return_VALUE(result);
+	device->power.state = ACPI_STATE_D0;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n",
+		resource->name));
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_power_off_device (
+	acpi_handle		handle)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_device	*device = NULL;
+	struct acpi_power_resource *resource = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_power_off_device");
+
+	result = acpi_power_get_context(handle, &resource);
+	if (result)
+		return_VALUE(result);
+
+	if (resource->references)
+		resource->references--;
+
+	if (resource->references) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"Resource [%s] is still in use, dereferencing\n",
+			device->pnp.bus_id));
+		return_VALUE(0);
+	}
+
+	if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
+			device->pnp.bus_id));
+		return_VALUE(0);
+	}
+
+	status = acpi_evaluate_object(resource->handle, "_OFF", NULL, NULL);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	result = acpi_power_get_state(resource);
+	if (result)
+		return_VALUE(result);
+	if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF)
+		return_VALUE(-ENOEXEC);
+
+	/* Update the power resource's _device_ power state */
+	result = acpi_bus_get_device(resource->handle, &device);
+	if (result)
+		return_VALUE(result);
+	device->power.state = ACPI_STATE_D3;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
+		resource->name));
+
+	return_VALUE(0);
+}
+
+/*
+ * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229):
+ * 1. Power on the power resources required for the wakeup device 
+ * 2. Enable _PSW (power state wake) for the device if present
+ */
+int acpi_enable_wakeup_device_power (struct acpi_device *dev)
+{
+	union acpi_object 		arg = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	arg_list = {1, &arg};
+	acpi_status			status = AE_OK;
+	int					i;
+	int 					ret = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_power");
+	if (!dev || !dev->wakeup.flags.valid)
+		return_VALUE(-1);
+
+	arg.integer.value = 1;
+	/* Open power resource */
+	for (i = 0; i < dev->wakeup.resources.count; i++) {
+		ret = acpi_power_on(dev->wakeup.resources.handles[i]);
+		if (ret) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				"Error transition power state\n"));
+			dev->wakeup.flags.valid = 0;
+			return_VALUE(-1);
+		}
+	}
+
+	/* Execute PSW */
+	status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n"));
+		dev->wakeup.flags.valid = 0;
+		ret = -1;
+	}
+
+	return_VALUE(ret);
+}
+
+/*
+ * Shutdown a wakeup device, counterpart of above method
+ * 1. Disable _PSW (power state wake)
+ * 2. Shutdown down the power resources
+ */
+int acpi_disable_wakeup_device_power (struct acpi_device *dev)
+{
+	union acpi_object 		arg = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	arg_list = {1, &arg};
+	acpi_status			status = AE_OK;
+	int					i;
+	int 					ret = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device_power");
+
+	if (!dev || !dev->wakeup.flags.valid)
+		return_VALUE(-1);
+
+	arg.integer.value = 0;	
+	/* Execute PSW */
+	status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n"));
+		dev->wakeup.flags.valid = 0;
+		return_VALUE(-1);
+	}
+
+	/* Close power resource */
+	for (i = 0; i < dev->wakeup.resources.count; i++) {
+		ret = acpi_power_off_device(dev->wakeup.resources.handles[i]);
+		if (ret) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				"Error transition power state\n"));
+			dev->wakeup.flags.valid = 0;
+			return_VALUE(-1);
+		}
+	}
+
+	return_VALUE(ret);
+}
+
+/* --------------------------------------------------------------------------
+                             Device Power Management
+   -------------------------------------------------------------------------- */
+
+int
+acpi_power_get_inferred_state (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	struct acpi_handle_list	*list = NULL;
+	int			list_state = 0;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_power_get_inferred_state");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	device->power.state = ACPI_STATE_UNKNOWN;
+
+	/*
+	 * We know a device's inferred power state when all the resources
+	 * required for a given D-state are 'on'.
+	 */
+	for (i=ACPI_STATE_D0; i<ACPI_STATE_D3; i++) {
+		list = &device->power.states[i].resources;
+		if (list->count < 1)
+			continue;
+
+		result = acpi_power_get_list_state(list, &list_state);
+		if (result)
+			return_VALUE(result);
+
+		if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
+			device->power.state = i;
+			return_VALUE(0);
+		}
+	}
+
+	device->power.state = ACPI_STATE_D3;
+
+	return_VALUE(0);
+}
+
+
+int
+acpi_power_transition (
+	struct acpi_device	*device,
+	int			state)
+{
+	int			result = 0;
+	struct acpi_handle_list	*cl = NULL;	/* Current Resources */
+	struct acpi_handle_list	*tl = NULL;	/* Target Resources */
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_power_transition");
+
+	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
+		return_VALUE(-EINVAL);
+
+	if ((device->power.state < ACPI_STATE_D0) || (device->power.state > ACPI_STATE_D3))
+		return_VALUE(-ENODEV);
+
+	cl = &device->power.states[device->power.state].resources;
+	tl = &device->power.states[state].resources;
+
+	device->power.state = ACPI_STATE_UNKNOWN;
+
+	if (!cl->count && !tl->count) {
+		result = -ENODEV;
+		goto end;
+	}
+
+	/* TBD: Resources must be ordered. */
+
+	/*
+	 * First we reference all power resources required in the target list
+	 * (e.g. so the device doesn't lose power while transitioning).
+	 */
+	for (i=0; i<tl->count; i++) {
+		result = acpi_power_on(tl->handles[i]);
+		if (result)
+			goto end;
+	}
+
+	/*
+	 * Then we dereference all power resources used in the current list.
+	 */
+	for (i=0; i<cl->count; i++) {
+		result = acpi_power_off_device(cl->handles[i]);
+		if (result)
+			goto end;
+	}
+
+	/* We shouldn't change the state till all above operations succeed */
+	device->power.state = state;
+end:
+	if (result)
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
+			"Error transitioning device [%s] to D%d\n",
+			device->pnp.bus_id, state));
+
+	return_VALUE(result);
+}
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_power_dir;
+
+static int acpi_power_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_power_resource *resource = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_power_seq_show");
+
+	resource = (struct acpi_power_resource *)seq->private;
+
+	if (!resource)
+		goto end;
+
+	seq_puts(seq, "state:                   ");
+	switch (resource->state) {
+	case ACPI_POWER_RESOURCE_STATE_ON:
+		seq_puts(seq, "on\n");
+		break;
+	case ACPI_POWER_RESOURCE_STATE_OFF:
+		seq_puts(seq, "off\n");
+		break;
+	default:
+		seq_puts(seq, "unknown\n");
+		break;
+	}
+
+	seq_printf(seq, "system level:            S%d\n"
+			"order:                   %d\n"
+			"reference count:         %d\n",
+			resource->system_level,
+			resource->order,
+			resource->references);
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_power_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_power_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_power_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_power_add_fs");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_power_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+	}
+
+	/* 'status' [R] */
+	entry = create_proc_entry(ACPI_POWER_FILE_STATUS,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_POWER_FILE_STATUS));
+	else {
+		entry->proc_fops = &acpi_power_fops;
+		entry->data = acpi_driver_data(device);
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_power_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_power_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_POWER_FILE_STATUS,
+				  acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device), acpi_power_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                                Driver Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_power_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_power_resource *resource = NULL;
+	union acpi_object	acpi_object;
+	struct acpi_buffer	buffer = {sizeof(acpi_object), &acpi_object};
+
+	ACPI_FUNCTION_TRACE("acpi_power_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
+	if (!resource)
+		return_VALUE(-ENOMEM);
+	memset(resource, 0, sizeof(struct acpi_power_resource));
+
+	resource->handle = device->handle;
+	strcpy(resource->name, device->pnp.bus_id);
+	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
+	acpi_driver_data(device) = resource;
+
+	/* Evalute the object to get the system level and resource order. */
+	status = acpi_evaluate_object(resource->handle, NULL, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		result = -ENODEV;
+		goto end;
+	}
+	resource->system_level = acpi_object.power_resource.system_level;
+	resource->order = acpi_object.power_resource.resource_order;
+
+	result = acpi_power_get_state(resource);
+	if (result)
+		goto end;
+
+	switch (resource->state) {
+	case ACPI_POWER_RESOURCE_STATE_ON:
+		device->power.state = ACPI_STATE_D0;
+		break;
+	case ACPI_POWER_RESOURCE_STATE_OFF:
+		device->power.state = ACPI_STATE_D3;
+		break;
+	default:
+		device->power.state = ACPI_STATE_UNKNOWN;
+		break;
+	}
+
+	result = acpi_power_add_fs(device);
+	if (result)
+		goto end;
+	
+	printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
+		acpi_device_bid(device), resource->state?"on":"off");
+
+end:
+	if (result)
+		kfree(resource);
+	
+	return_VALUE(result);
+}
+
+
+static int
+acpi_power_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	struct acpi_power_resource *resource = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_power_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	resource = (struct acpi_power_resource *) acpi_driver_data(device);
+
+	acpi_power_remove_fs(device);
+
+	kfree(resource);
+
+	return_VALUE(0);
+}
+
+
+static int __init acpi_power_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_power_init");
+
+	if (acpi_disabled)
+		return_VALUE(0);
+
+	INIT_LIST_HEAD(&acpi_power_resource_list);
+
+	acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
+	if (!acpi_power_dir)
+		return_VALUE(-ENODEV);
+
+	result = acpi_bus_register_driver(&acpi_power_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+subsys_initcall(acpi_power_init);
+
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
new file mode 100644
index 0000000..f477874
--- /dev/null
+++ b/drivers/acpi/processor_core.c
@@ -0,0 +1,989 @@
+/*
+ * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug support
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *  TBD:
+ *	1. Make # power states dynamic.
+ *	2. Support duty_cycle values that span bit 4.
+ *	3. Optimize by having scheduler determine business instead of
+ *	   having us try to calculate it here.
+ *	4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/dmi.h>
+#include <linux/moduleparam.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cpu.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+#include <asm/acpi.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/processor.h>
+
+
+#define ACPI_PROCESSOR_COMPONENT	0x01000000
+#define ACPI_PROCESSOR_CLASS		"processor"
+#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor Driver"
+#define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
+#define ACPI_PROCESSOR_FILE_INFO	"info"
+#define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
+#define ACPI_PROCESSOR_FILE_LIMIT	"limit"
+#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
+#define ACPI_PROCESSOR_NOTIFY_POWER	0x81
+
+#define ACPI_PROCESSOR_LIMIT_USER	0
+#define ACPI_PROCESSOR_LIMIT_THERMAL	1
+
+#define ACPI_STA_PRESENT 0x00000001
+
+#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME		("acpi_processor")
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+
+static int acpi_processor_add (struct acpi_device *device);
+static int acpi_processor_start (struct acpi_device *device);
+static int acpi_processor_remove (struct acpi_device *device, int type);
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
+static void acpi_processor_notify ( acpi_handle	handle, u32 event, void *data);
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
+static int acpi_processor_handle_eject(struct acpi_processor *pr);
+
+static struct acpi_driver acpi_processor_driver = {
+	.name =		ACPI_PROCESSOR_DRIVER_NAME,
+	.class =	ACPI_PROCESSOR_CLASS,
+	.ids =		ACPI_PROCESSOR_HID,
+	.ops =		{
+				.add =		acpi_processor_add,
+				.remove =	acpi_processor_remove,
+				.start	= 	acpi_processor_start,
+			},
+};
+
+#define INSTALL_NOTIFY_HANDLER		1
+#define UNINSTALL_NOTIFY_HANDLER	2
+
+
+static struct file_operations acpi_processor_info_fops = {
+	.open 		= acpi_processor_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+struct acpi_processor	*processors[NR_CPUS];
+struct acpi_processor_errata errata;
+
+
+/* --------------------------------------------------------------------------
+                                Errata Handling
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_processor_errata_piix4 (
+	struct pci_dev		*dev)
+{
+	u8			rev = 0;
+	u8			value1 = 0;
+	u8			value2 = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_errata_piix4");
+
+	if (!dev)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * Note that 'dev' references the PIIX4 ACPI Controller.
+	 */
+
+	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+
+	switch (rev) {
+	case 0:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
+		break;
+	case 1:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
+		break;
+	case 2:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
+		break;
+	case 3:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
+		break;
+	}
+
+	switch (rev) {
+
+	case 0:		/* PIIX4 A-step */
+	case 1:		/* PIIX4 B-step */
+		/*
+		 * See specification changes #13 ("Manual Throttle Duty Cycle")
+		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
+		 * erratum #5 ("STPCLK# Deassertion Time") from the January
+		 * 2002 PIIX4 specification update.  Applies to only older
+		 * PIIX4 models.
+		 */
+		errata.piix4.throttle = 1;
+
+	case 2:		/* PIIX4E */
+	case 3:		/* PIIX4M */
+		/*
+		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
+		 * Livelock") from the January 2002 PIIX4 specification update.
+		 * Applies to all PIIX4 models.
+		 */
+
+		/*
+		 * BM-IDE
+		 * ------
+		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
+		 * Status register address.  We'll use this later to read
+		 * each IDE controller's DMA status to make sure we catch all
+		 * DMA activity.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+		           PCI_DEVICE_ID_INTEL_82371AB,
+                           PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			errata.piix4.bmisx = pci_resource_start(dev, 4);
+			pci_dev_put(dev);
+		}
+
+		/*
+		 * Type-F DMA
+		 * ----------
+		 * Find the PIIX4 ISA Controller and read the Motherboard
+		 * DMA controller's status to see if Type-F (Fast) DMA mode
+		 * is enabled (bit 7) on either channel.  Note that we'll
+		 * disable C3 support if this is enabled, as some legacy
+		 * devices won't operate well if fast DMA is disabled.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			PCI_DEVICE_ID_INTEL_82371AB_0,
+			PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			pci_read_config_byte(dev, 0x76, &value1);
+			pci_read_config_byte(dev, 0x77, &value2);
+			if ((value1 & 0x80) || (value2 & 0x80))
+				errata.piix4.fdma = 1;
+			pci_dev_put(dev);
+		}
+
+		break;
+	}
+
+	if (errata.piix4.bmisx)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Bus master activity detection (BM-IDE) erratum enabled\n"));
+	if (errata.piix4.fdma)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Type-F DMA livelock erratum (C3 disabled)\n"));
+
+	return_VALUE(0);
+}
+
+
+int
+acpi_processor_errata (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	struct pci_dev		*dev = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_errata");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * PIIX4
+	 */
+	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+		PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL);
+	if (dev) {
+		result = acpi_processor_errata_piix4(dev);
+		pci_dev_put(dev);
+	}
+
+	return_VALUE(result);
+}
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_processor_dir = NULL;
+
+static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_info_seq_show");
+
+	if (!pr)
+		goto end;
+
+	seq_printf(seq, "processor id:            %d\n"
+			"acpi id:                 %d\n"
+			"bus mastering control:   %s\n"
+			"power management:        %s\n"
+			"throttling control:      %s\n"
+			"limit interface:         %s\n",
+			pr->id,
+			pr->acpi_id,
+			pr->flags.bm_control ? "yes" : "no",
+			pr->flags.power ? "yes" : "no",
+			pr->flags.throttling ? "yes" : "no",
+			pr->flags.limit ? "yes" : "no");
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_info_seq_show,
+						PDE(inode)->data);
+}
+
+
+static int
+acpi_processor_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_add_fs");
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_processor_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+	}
+	acpi_device_dir(device)->owner = THIS_MODULE;
+
+	/* 'info' [R] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_INFO));
+	else {
+		entry->proc_fops = &acpi_processor_info_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'throttling' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_THROTTLING));
+	else {
+		entry->proc_fops = &acpi_processor_throttling_fops;
+		entry->proc_fops->write = acpi_processor_write_throttling;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'limit' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_LIMIT));
+	else {
+		entry->proc_fops = &acpi_processor_limit_fops;
+		entry->proc_fops->write = acpi_processor_write_limit;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_processor_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
+			acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+/* Use the acpiid in MADT to map cpus in case of SMP */
+#ifndef CONFIG_SMP
+#define convert_acpiid_to_cpu(acpi_id) (0xff)
+#else
+
+#ifdef CONFIG_IA64
+#define arch_acpiid_to_apicid 	ia64_acpiid_to_sapicid
+#define arch_cpu_to_apicid 	ia64_cpu_to_sapicid
+#define ARCH_BAD_APICID		(0xffff)
+#else
+#define arch_acpiid_to_apicid 	x86_acpiid_to_apicid
+#define arch_cpu_to_apicid 	x86_cpu_to_apicid
+#define ARCH_BAD_APICID		(0xff)
+#endif
+
+static u8 convert_acpiid_to_cpu(u8 acpi_id)
+{
+	u16 apic_id;
+	int i;
+
+	apic_id = arch_acpiid_to_apicid[acpi_id];
+	if (apic_id == ARCH_BAD_APICID)
+		return -1;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (arch_cpu_to_apicid[i] == apic_id)
+			return i;
+	}
+	return -1;
+}
+#endif
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_processor_get_info (
+	struct acpi_processor	*pr)
+{
+	acpi_status		status = 0;
+	union acpi_object	object = {0};
+	struct acpi_buffer	buffer = {sizeof(union acpi_object), &object};
+	u8			cpu_index;
+	static int		cpu0_initialized;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_info");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (num_online_cpus() > 1)
+		errata.smp = TRUE;
+
+	acpi_processor_errata(pr);
+
+	/*
+	 * Check to see if we have bus mastering arbitration control.  This
+	 * is required for proper C3 usage (to maintain cache coherency).
+	 */
+	if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) {
+		pr->flags.bm_control = 1;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Bus mastering arbitration control present\n"));
+	}
+	else
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"No bus mastering arbitration control\n"));
+
+	/*
+	 * Evalute the processor object.  Note that it is common on SMP to
+	 * have the first (boot) processor with a valid PBLK address while
+	 * all others have a NULL address.
+	 */
+	status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error evaluating processor object\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	/*
+	 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
+	 *	>>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
+	 */
+	pr->acpi_id = object.processor.proc_id;
+
+	cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
+
+  	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
+  	if ( !cpu0_initialized && (cpu_index == 0xff) &&
+  		       	(num_online_cpus() == 1)) {
+   		cpu_index = 0;
+   	}
+
+   	cpu0_initialized = 1;
+
+   	pr->id = cpu_index;
+
+  	/*
+  	 *  Extra Processor objects may be enumerated on MP systems with
+  	 *  less than the max # of CPUs. They should be ignored _iff
+  	 *  they are physically not present.
+  	 */
+   	if (cpu_index >=  NR_CPUS) {
+   		if (ACPI_FAILURE(acpi_processor_hotadd_init(pr->handle, &pr->id))) {
+   			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+   				"Error getting cpuindex for acpiid 0x%x\n",
+   				pr->acpi_id));
+   			return_VALUE(-ENODEV);
+   		}
+    	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
+		pr->acpi_id));
+
+	if (!object.processor.pblk_address)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
+	else if (object.processor.pblk_length != 6)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n",
+			object.processor.pblk_length));
+	else {
+		pr->throttling.address = object.processor.pblk_address;
+		pr->throttling.duty_offset = acpi_fadt.duty_offset;
+		pr->throttling.duty_width = acpi_fadt.duty_width;
+
+		pr->pblk = object.processor.pblk_address;
+
+		/*
+		 * We don't care about error returns - we just try to mark
+		 * these reserved so that nobody else is confused into thinking
+		 * that this region might be unused..
+		 *
+		 * (In particular, allocating the IO range for Cardbus)
+		 */
+		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
+	}
+
+#ifdef CONFIG_CPU_FREQ
+	acpi_processor_ppc_has_changed(pr);
+#endif
+	acpi_processor_get_throttling_info(pr);
+	acpi_processor_get_limit_info(pr);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_processor_start(
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_processor	*pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_start");
+
+	pr = acpi_driver_data(device);
+
+	result = acpi_processor_get_info(pr);
+	if (result) {
+		/* Processor is physically not present */
+		return_VALUE(0);
+	}
+
+	BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
+
+	processors[pr->id] = pr;
+
+	result = acpi_processor_add_fs(device);
+	if (result)
+		goto end;
+
+	status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
+		acpi_processor_notify, pr);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing device notify handler\n"));
+	}
+
+	acpi_processor_power_init(pr, device);
+
+	if (pr->flags.throttling) {
+		printk(KERN_INFO PREFIX "%s [%s] (supports",
+			acpi_device_name(device), acpi_device_bid(device));
+		printk(" %d throttling states", pr->throttling.state_count);
+		printk(")\n");
+	}
+
+end:
+
+	return_VALUE(result);
+}
+
+
+
+static void
+acpi_processor_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *) data;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_notify");
+
+	if (!pr)
+		return_VOID;
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	switch (event) {
+	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
+		acpi_processor_ppc_has_changed(pr);
+		acpi_bus_generate_event(device, event,
+			pr->performance_platform_limit);
+		break;
+	case ACPI_PROCESSOR_NOTIFY_POWER:
+		acpi_processor_cst_has_changed(pr);
+		acpi_bus_generate_event(device, event, 0);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+
+static int
+acpi_processor_add (
+	struct acpi_device	*device)
+{
+	struct acpi_processor	*pr = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+	if (!pr)
+		return_VALUE(-ENOMEM);
+	memset(pr, 0, sizeof(struct acpi_processor));
+
+	pr->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
+	acpi_driver_data(device) = pr;
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_processor_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_processor	*pr = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	pr = (struct acpi_processor *) acpi_driver_data(device);
+
+	if (pr->id >= NR_CPUS) {
+		kfree(pr);
+		return_VALUE(0);
+	}
+
+	if (type == ACPI_BUS_REMOVAL_EJECT) {
+		if (acpi_processor_handle_eject(pr))
+			return_VALUE(-EINVAL);
+	}
+
+	acpi_processor_power_exit(pr, device);
+
+	status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
+		acpi_processor_notify);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error removing notify handler\n"));
+	}
+
+	acpi_processor_remove_fs(device);
+
+	processors[pr->id] = NULL;
+
+	kfree(pr);
+
+	return_VALUE(0);
+}
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+/****************************************************************************
+ * 	Acpi processor hotplug support 				       	    *
+ ****************************************************************************/
+
+static int is_processor_present(acpi_handle handle);
+
+static int
+is_processor_present(
+	acpi_handle handle)
+{
+	acpi_status 		status;
+	unsigned long		sta = 0;
+
+	ACPI_FUNCTION_TRACE("is_processor_present");
+
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_PRESENT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Processor Device is not present\n"));
+		return_VALUE(0);
+	}
+	return_VALUE(1);
+}
+
+
+static
+int acpi_processor_device_add(
+	acpi_handle	handle,
+	struct acpi_device **device)
+{
+	acpi_handle		phandle;
+	struct acpi_device 	*pdev;
+	struct acpi_processor	*pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_device_add");
+
+	if (acpi_get_parent(handle, &phandle)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_get_device(phandle, &pdev)) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
+		return_VALUE(-ENODEV);
+	}
+
+	acpi_bus_scan(*device);
+
+	pr = acpi_driver_data(*device);
+	if (!pr)
+		return_VALUE(-ENODEV);
+
+	if ((pr->id >=0) && (pr->id < NR_CPUS)) {
+		kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
+	}
+	return_VALUE(0);
+}
+
+
+static void
+acpi_processor_hotplug_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_processor	*pr;
+	struct acpi_device	*device = NULL;
+	int result;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_hotplug_notify");
+
+	switch (event) {
+	case ACPI_NOTIFY_BUS_CHECK:
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		printk("Processor driver received %s event\n",
+			(event==ACPI_NOTIFY_BUS_CHECK)?
+			"ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+
+		if (!is_processor_present(handle))
+			break;
+
+		if (acpi_bus_get_device(handle, &device)) {
+			result = acpi_processor_device_add(handle, &device);
+			if (result)
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Unable to add the device\n"));
+			break;
+		}
+
+		pr = acpi_driver_data(device);
+		if (!pr) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Driver data is NULL\n"));
+			break;
+		}
+
+		if (pr->id >= 0 && (pr->id < NR_CPUS)) {
+			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+			break;
+		}
+
+		result = acpi_processor_start(device);
+		if ((!result) && ((pr->id >=0) && (pr->id < NR_CPUS))) {
+			kobject_hotplug(&device->kobj, KOBJ_ONLINE);
+		} else {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Device [%s] failed to start\n",
+				acpi_device_bid(device)));
+		}
+	break;
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"received ACPI_NOTIFY_EJECT_REQUEST\n"));
+
+		if (acpi_bus_get_device(handle, &device)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Device don't exist, dropping EJECT\n"));
+			break;
+		}
+		pr = acpi_driver_data(device);
+		if (!pr) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Driver data is NULL, dropping EJECT\n"));
+			return_VOID;
+		}
+
+		if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
+			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+static acpi_status
+processor_walk_namespace_cb(acpi_handle handle,
+	u32 lvl,
+	void *context,
+	void **rv)
+{
+	acpi_status 			status;
+	int *action = context;
+	acpi_object_type	type = 0;
+
+	status = acpi_get_type(handle, &type);
+	if (ACPI_FAILURE(status))
+		return(AE_OK);
+
+	if (type != ACPI_TYPE_PROCESSOR)
+		return(AE_OK);
+
+	switch(*action) {
+	case INSTALL_NOTIFY_HANDLER:
+		acpi_install_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			acpi_processor_hotplug_notify,
+			NULL);
+		break;
+	case UNINSTALL_NOTIFY_HANDLER:
+		acpi_remove_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY,
+			acpi_processor_hotplug_notify);
+		break;
+	default:
+		break;
+	}
+
+	return(AE_OK);
+}
+
+
+static acpi_status
+acpi_processor_hotadd_init(
+	acpi_handle		handle,
+	int			*p_cpu)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_hotadd_init");
+
+	if (!is_processor_present(handle)) {
+		return_VALUE(AE_ERROR);
+	}
+
+	if (acpi_map_lsapic(handle, p_cpu))
+		return_VALUE(AE_ERROR);
+
+	if (arch_register_cpu(*p_cpu)) {
+		acpi_unmap_lsapic(*p_cpu);
+		return_VALUE(AE_ERROR);
+	}
+
+	return_VALUE(AE_OK);
+}
+
+
+static int
+acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+	if (cpu_online(pr->id)) {
+		return(-EINVAL);
+	}
+	arch_unregister_cpu(pr->id);
+	acpi_unmap_lsapic(pr->id);
+	return(0);
+}
+#else
+static acpi_status
+acpi_processor_hotadd_init(
+	acpi_handle		handle,
+	int			*p_cpu)
+{
+	return AE_ERROR;
+}
+static int
+acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+	return(-EINVAL);
+}
+#endif
+
+
+static
+void acpi_processor_install_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+	int action = INSTALL_NOTIFY_HANDLER;
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     processor_walk_namespace_cb,
+				     &action, NULL);
+#endif
+}
+
+
+static
+void acpi_processor_uninstall_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+	int action = UNINSTALL_NOTIFY_HANDLER;
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+				     ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX,
+				     processor_walk_namespace_cb,
+				     &action, NULL);
+#endif
+}
+
+/*
+ * We keep the driver loaded even when ACPI is not running.
+ * This is needed for the powernow-k8 driver, that works even without
+ * ACPI, but needs symbols from this driver
+ */
+
+static int __init
+acpi_processor_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_init");
+
+	memset(&processors, 0, sizeof(processors));
+	memset(&errata, 0, sizeof(errata));
+
+	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+	if (!acpi_processor_dir)
+		return_VALUE(0);
+	acpi_processor_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_processor_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+		return_VALUE(0);
+	}
+
+	acpi_processor_install_hotplug_notify();
+
+	acpi_thermal_cpufreq_init();
+
+	acpi_processor_ppc_init();
+
+	return_VALUE(0);
+}
+
+
+static void __exit
+acpi_processor_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_exit");
+
+	acpi_processor_ppc_exit();
+
+	acpi_thermal_cpufreq_exit();
+
+	acpi_processor_uninstall_hotplug_notify();
+
+	acpi_bus_unregister_driver(&acpi_processor_driver);
+
+	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+
+module_init(acpi_processor_init);
+module_exit(acpi_processor_exit);
+
+EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
+
+MODULE_ALIAS("processor");
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
new file mode 100644
index 0000000..05a1781
--- /dev/null
+++ b/drivers/acpi/processor_idle.c
@@ -0,0 +1,1017 @@
+/*
+ * processor_idle - idle state submodule to the ACPI processor driver
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug support
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/moduleparam.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+
+#define ACPI_PROCESSOR_COMPONENT        0x01000000
+#define ACPI_PROCESSOR_CLASS            "processor"
+#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
+#define _COMPONENT              ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME                ("acpi_processor")
+
+#define ACPI_PROCESSOR_FILE_POWER	"power"
+
+#define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
+#define C2_OVERHEAD			4	/* 1us (3.579 ticks per us) */
+#define C3_OVERHEAD			4	/* 1us (3.579 ticks per us) */
+
+static void (*pm_idle_save)(void);
+module_param(max_cstate, uint, 0644);
+
+static unsigned int nocst = 0;
+module_param(nocst, uint, 0000);
+
+/*
+ * bm_history -- bit-mask with a bit per jiffy of bus-master activity
+ * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
+ * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms
+ * 100 HZ: 0x0000000F: 4 jiffies = 40ms
+ * reduce history for more aggressive entry into C3
+ */
+static unsigned int bm_history = (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
+module_param(bm_history, uint, 0644);
+/* --------------------------------------------------------------------------
+                                Power Management
+   -------------------------------------------------------------------------- */
+
+/*
+ * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
+ * For now disable this. Probably a bug somewhere else.
+ *
+ * To skip this limit, boot/load with a large max_cstate limit.
+ */
+static int no_c2c3(struct dmi_system_id *id)
+{
+	if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
+		return 0;
+
+	printk(KERN_NOTICE PREFIX "%s detected - C2,C3 disabled."
+		" Override with \"processor.max_cstate=%d\"\n", id->ident,
+	       ACPI_PROCESSOR_MAX_POWER + 1);
+
+	max_cstate = 1;
+
+	return 0;
+}
+
+
+
+
+static struct dmi_system_id __initdata processor_power_dmi_table[] = {
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }},
+	{ no_c2c3, "Medion 41700", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }},
+	{},
+};
+
+
+static inline u32
+ticks_elapsed (
+	u32			t1,
+	u32			t2)
+{
+	if (t2 >= t1)
+		return (t2 - t1);
+	else if (!acpi_fadt.tmr_val_ext)
+		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
+	else
+		return ((0xFFFFFFFF - t1) + t2);
+}
+
+
+static void
+acpi_processor_power_activate (
+	struct acpi_processor	*pr,
+	struct acpi_processor_cx  *new)
+{
+	struct acpi_processor_cx  *old;
+
+	if (!pr || !new)
+		return;
+
+	old = pr->power.state;
+
+	if (old)
+		old->promotion.count = 0;
+ 	new->demotion.count = 0;
+
+	/* Cleanup from old state. */
+	if (old) {
+		switch (old->type) {
+		case ACPI_STATE_C3:
+			/* Disable bus master reload */
+			if (new->type != ACPI_STATE_C3)
+				acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
+			break;
+		}
+	}
+
+	/* Prepare to use new state. */
+	switch (new->type) {
+	case ACPI_STATE_C3:
+		/* Enable bus master reload */
+		if (old->type != ACPI_STATE_C3)
+			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK);
+		break;
+	}
+
+	pr->power.state = new;
+
+	return;
+}
+
+
+static void acpi_processor_idle (void)
+{
+	struct acpi_processor	*pr = NULL;
+	struct acpi_processor_cx *cx = NULL;
+	struct acpi_processor_cx *next_state = NULL;
+	int			sleep_ticks = 0;
+	u32			t1, t2 = 0;
+
+	pr = processors[_smp_processor_id()];
+	if (!pr)
+		return;
+
+	/*
+	 * Interrupts must be disabled during bus mastering calculations and
+	 * for C2/C3 transitions.
+	 */
+	local_irq_disable();
+
+	/*
+	 * Check whether we truly need to go idle, or should
+	 * reschedule:
+	 */
+	if (unlikely(need_resched())) {
+		local_irq_enable();
+		return;
+	}
+
+	cx = pr->power.state;
+	if (!cx)
+		goto easy_out;
+
+	/*
+	 * Check BM Activity
+	 * -----------------
+	 * Check for bus mastering activity (if required), record, and check
+	 * for demotion.
+	 */
+	if (pr->flags.bm_check) {
+		u32		bm_status = 0;
+		unsigned long	diff = jiffies - pr->power.bm_check_timestamp;
+
+		if (diff > 32)
+			diff = 32;
+
+		while (diff) {
+			/* if we didn't get called, assume there was busmaster activity */
+			diff--;
+			if (diff)
+				pr->power.bm_activity |= 0x1;
+			pr->power.bm_activity <<= 1;
+		}
+
+		acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,
+			&bm_status, ACPI_MTX_DO_NOT_LOCK);
+		if (bm_status) {
+			pr->power.bm_activity++;
+			acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,
+				1, ACPI_MTX_DO_NOT_LOCK);
+		}
+		/*
+		 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
+		 * the true state of bus mastering activity; forcing us to
+		 * manually check the BMIDEA bit of each IDE channel.
+		 */
+		else if (errata.piix4.bmisx) {
+			if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
+				|| (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
+				pr->power.bm_activity++;
+		}
+
+		pr->power.bm_check_timestamp = jiffies;
+
+		/*
+		 * Apply bus mastering demotion policy.  Automatically demote
+		 * to avoid a faulty transition.  Note that the processor
+		 * won't enter a low-power state during this call (to this
+		 * funciton) but should upon the next.
+		 *
+		 * TBD: A better policy might be to fallback to the demotion
+		 *      state (use it for this quantum only) istead of
+		 *      demoting -- and rely on duration as our sole demotion
+		 *      qualification.  This may, however, introduce DMA
+		 *      issues (e.g. floppy DMA transfer overrun/underrun).
+		 */
+		if (pr->power.bm_activity & cx->demotion.threshold.bm) {
+			local_irq_enable();
+			next_state = cx->demotion.state;
+			goto end;
+		}
+	}
+
+	cx->usage++;
+
+	/*
+	 * Sleep:
+	 * ------
+	 * Invoke the current Cx state to put the processor to sleep.
+	 */
+	switch (cx->type) {
+
+	case ACPI_STATE_C1:
+		/*
+		 * Invoke C1.
+		 * Use the appropriate idle routine, the one that would
+		 * be used without acpi C-states.
+		 */
+		if (pm_idle_save)
+			pm_idle_save();
+		else
+			safe_halt();
+		/*
+                 * TBD: Can't get time duration while in C1, as resumes
+		 *      go to an ISR rather than here.  Need to instrument
+		 *      base interrupt handler.
+		 */
+		sleep_ticks = 0xFFFFFFFF;
+		break;
+
+	case ACPI_STATE_C2:
+		/* Get start time (ticks) */
+		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Invoke C2 */
+		inb(cx->address);
+		/* Dummy op - must do something useless after P_LVL2 read */
+		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Get end time (ticks) */
+		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Re-enable interrupts */
+		local_irq_enable();
+		/* Compute time (ticks) that we were actually asleep */
+		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
+		break;
+
+	case ACPI_STATE_C3:
+		/* Disable bus master arbitration */
+		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
+		/* Get start time (ticks) */
+		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Invoke C3 */
+		inb(cx->address);
+		/* Dummy op - must do something useless after P_LVL3 read */
+		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Get end time (ticks) */
+		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		/* Enable bus master arbitration */
+		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
+		/* Re-enable interrupts */
+		local_irq_enable();
+		/* Compute time (ticks) that we were actually asleep */
+		sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
+		break;
+
+	default:
+		local_irq_enable();
+		return;
+	}
+
+	next_state = pr->power.state;
+
+	/*
+	 * Promotion?
+	 * ----------
+	 * Track the number of longs (time asleep is greater than threshold)
+	 * and promote when the count threshold is reached.  Note that bus
+	 * mastering activity may prevent promotions.
+	 * Do not promote above max_cstate.
+	 */
+	if (cx->promotion.state &&
+	    ((cx->promotion.state - pr->power.states) <= max_cstate)) {
+		if (sleep_ticks > cx->promotion.threshold.ticks) {
+			cx->promotion.count++;
+ 			cx->demotion.count = 0;
+			if (cx->promotion.count >= cx->promotion.threshold.count) {
+				if (pr->flags.bm_check) {
+					if (!(pr->power.bm_activity & cx->promotion.threshold.bm)) {
+						next_state = cx->promotion.state;
+						goto end;
+					}
+				}
+				else {
+					next_state = cx->promotion.state;
+					goto end;
+				}
+			}
+		}
+	}
+
+	/*
+	 * Demotion?
+	 * ---------
+	 * Track the number of shorts (time asleep is less than time threshold)
+	 * and demote when the usage threshold is reached.
+	 */
+	if (cx->demotion.state) {
+		if (sleep_ticks < cx->demotion.threshold.ticks) {
+			cx->demotion.count++;
+			cx->promotion.count = 0;
+			if (cx->demotion.count >= cx->demotion.threshold.count) {
+				next_state = cx->demotion.state;
+				goto end;
+			}
+		}
+	}
+
+end:
+	/*
+	 * Demote if current state exceeds max_cstate
+	 */
+	if ((pr->power.state - pr->power.states) > max_cstate) {
+		if (cx->demotion.state)
+			next_state = cx->demotion.state;
+	}
+
+	/*
+	 * New Cx State?
+	 * -------------
+	 * If we're going to start using a new Cx state we must clean up
+	 * from the previous and prepare to use the new.
+	 */
+	if (next_state != pr->power.state)
+		acpi_processor_power_activate(pr, next_state);
+
+	return;
+
+ easy_out:
+	/* do C1 instead of busy loop */
+	if (pm_idle_save)
+		pm_idle_save();
+	else
+		safe_halt();
+	return;
+}
+
+
+static int
+acpi_processor_set_power_policy (
+	struct acpi_processor	*pr)
+{
+	unsigned int i;
+	unsigned int state_is_set = 0;
+	struct acpi_processor_cx *lower = NULL;
+	struct acpi_processor_cx *higher = NULL;
+	struct acpi_processor_cx *cx;
+
+ 	ACPI_FUNCTION_TRACE("acpi_processor_set_power_policy");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * This function sets the default Cx state policy (OS idle handler).
+	 * Our scheme is to promote quickly to C2 but more conservatively
+	 * to C3.  We're favoring C2  for its characteristics of low latency
+	 * (quick response), good power savings, and ability to allow bus
+	 * mastering activity.  Note that the Cx state policy is completely
+	 * customizable and can be altered dynamically.
+	 */
+
+	/* startup state */
+	for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		cx = &pr->power.states[i];
+		if (!cx->valid)
+			continue;
+
+		if (!state_is_set)
+			pr->power.state = cx;
+		state_is_set++;
+		break;
+ 	}
+
+	if (!state_is_set)
+		return_VALUE(-ENODEV);
+
+	/* demotion */
+	for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		cx = &pr->power.states[i];
+		if (!cx->valid)
+			continue;
+
+		if (lower) {
+			cx->demotion.state = lower;
+			cx->demotion.threshold.ticks = cx->latency_ticks;
+			cx->demotion.threshold.count = 1;
+			if (cx->type == ACPI_STATE_C3)
+				cx->demotion.threshold.bm = bm_history;
+		}
+
+		lower = cx;
+	}
+
+	/* promotion */
+	for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) {
+		cx = &pr->power.states[i];
+		if (!cx->valid)
+			continue;
+
+		if (higher) {
+			cx->promotion.state  = higher;
+			cx->promotion.threshold.ticks = cx->latency_ticks;
+			if (cx->type >= ACPI_STATE_C2)
+				cx->promotion.threshold.count = 4;
+			else
+				cx->promotion.threshold.count = 10;
+			if (higher->type == ACPI_STATE_C3)
+				cx->promotion.threshold.bm = bm_history;
+		}
+
+		higher = cx;
+	}
+
+ 	return_VALUE(0);
+}
+
+
+static int acpi_processor_get_power_info_fadt (struct acpi_processor *pr)
+{
+	int i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_fadt");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (!pr->pblk)
+		return_VALUE(-ENODEV);
+
+	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
+		memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+
+	/* if info is obtained from pblk/fadt, type equals state */
+	pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
+	pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
+	pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
+
+	/* the C0 state only exists as a filler in our array,
+	 * and all processors need to support C1 */
+	pr->power.states[ACPI_STATE_C0].valid = 1;
+	pr->power.states[ACPI_STATE_C1].valid = 1;
+
+	/* determine C2 and C3 address from pblk */
+	pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;
+	pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5;
+
+	/* determine latencies from FADT */
+	pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat;
+	pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "lvl2[0x%08x] lvl3[0x%08x]\n",
+			  pr->power.states[ACPI_STATE_C2].address,
+			  pr->power.states[ACPI_STATE_C3].address));
+
+	return_VALUE(0);
+}
+
+
+static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
+{
+	acpi_status		status = 0;
+	acpi_integer		count;
+	int			i;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*cst;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_cst");
+
+	if (errata.smp)
+		return_VALUE(-ENODEV);
+
+	if (nocst)
+		return_VALUE(-ENODEV);
+
+	pr->power.count = 0;
+	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
+		memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+
+	status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No _CST, giving up\n"));
+		return_VALUE(-ENODEV);
+ 	}
+
+	cst = (union acpi_object *) buffer.pointer;
+
+	/* There must be at least 2 elements */
+	if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "not enough elements in _CST\n"));
+		status = -EFAULT;
+		goto end;
+	}
+
+	count = cst->package.elements[0].integer.value;
+
+	/* Validate number of power states. */
+	if (count < 1 || count != cst->package.count - 1) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "count given by _CST is not valid\n"));
+		status = -EFAULT;
+		goto end;
+	}
+
+	/* We support up to ACPI_PROCESSOR_MAX_POWER. */
+	if (count > ACPI_PROCESSOR_MAX_POWER) {
+		printk(KERN_WARNING "Limiting number of power states to max (%d)\n", ACPI_PROCESSOR_MAX_POWER);
+		printk(KERN_WARNING "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");
+		count = ACPI_PROCESSOR_MAX_POWER;
+	}
+
+	/* Tell driver that at least _CST is supported. */
+	pr->flags.has_cst = 1;
+
+	for (i = 1; i <= count; i++) {
+		union acpi_object *element;
+		union acpi_object *obj;
+		struct acpi_power_register *reg;
+		struct acpi_processor_cx cx;
+
+		memset(&cx, 0, sizeof(cx));
+
+		element = (union acpi_object *) &(cst->package.elements[i]);
+		if (element->type != ACPI_TYPE_PACKAGE)
+			continue;
+
+		if (element->package.count != 4)
+			continue;
+
+		obj = (union acpi_object *) &(element->package.elements[0]);
+
+		if (obj->type != ACPI_TYPE_BUFFER)
+			continue;
+
+		reg = (struct acpi_power_register *) obj->buffer.pointer;
+
+		if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO &&
+			(reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
+			continue;
+
+		cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
+			0 : reg->address;
+
+		/* There should be an easy way to extract an integer... */
+		obj = (union acpi_object *) &(element->package.elements[1]);
+		if (obj->type != ACPI_TYPE_INTEGER)
+			continue;
+
+		cx.type = obj->integer.value;
+
+		if ((cx.type != ACPI_STATE_C1) &&
+		    (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
+			continue;
+
+		if ((cx.type < ACPI_STATE_C1) ||
+		    (cx.type > ACPI_STATE_C3))
+			continue;
+
+		obj = (union acpi_object *) &(element->package.elements[2]);
+		if (obj->type != ACPI_TYPE_INTEGER)
+			continue;
+
+		cx.latency = obj->integer.value;
+
+		obj = (union acpi_object *) &(element->package.elements[3]);
+		if (obj->type != ACPI_TYPE_INTEGER)
+			continue;
+
+		cx.power = obj->integer.value;
+
+		(pr->power.count)++;
+		memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx));
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", pr->power.count));
+
+	/* Validate number of power states discovered */
+	if (pr->power.count < 2)
+		status = -ENODEV;
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(status);
+}
+
+
+static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_verify_c2");
+
+	if (!cx->address)
+		return_VOID;
+
+	/*
+	 * C2 latency must be less than or equal to 100
+	 * microseconds.
+	 */
+	else if (cx->latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "latency too large [%d]\n",
+				  cx->latency));
+		return_VOID;
+	}
+
+	/* We're (currently) only supporting C2 on UP */
+	else if (errata.smp) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "C2 not supported in SMP mode\n"));
+		return_VOID;
+	}
+
+	/*
+	 * Otherwise we've met all of our C2 requirements.
+	 * Normalize the C2 latency to expidite policy
+	 */
+	cx->valid = 1;
+	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+
+	return_VOID;
+}
+
+
+static void acpi_processor_power_verify_c3(
+	struct acpi_processor *pr,
+	struct acpi_processor_cx *cx)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_verify_c3");
+
+	if (!cx->address)
+		return_VOID;
+
+	/*
+	 * C3 latency must be less than or equal to 1000
+	 * microseconds.
+	 */
+	else if (cx->latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "latency too large [%d]\n",
+				  cx->latency));
+		return_VOID;
+	}
+
+	/* bus mastering control is necessary */
+	else if (!pr->flags.bm_control) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "C3 support requires bus mastering control\n"));
+		return_VOID;
+	}
+
+	/* We're (currently) only supporting C2 on UP */
+	else if (errata.smp) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "C3 not supported in SMP mode\n"));
+		return_VOID;
+	}
+
+	/*
+	 * PIIX4 Erratum #18: We don't support C3 when Type-F (fast)
+	 * DMA transfers are used by any ISA device to avoid livelock.
+	 * Note that we could disable Type-F DMA (as recommended by
+	 * the erratum), but this is known to disrupt certain ISA
+	 * devices thus we take the conservative approach.
+	 */
+	else if (errata.piix4.fdma) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"C3 not supported on PIIX4 with Type-F DMA\n"));
+		return_VOID;
+	}
+
+	/*
+	 * Otherwise we've met all of our C3 requirements.
+	 * Normalize the C3 latency to expidite policy.  Enable
+	 * checking of bus mastering status (bm_check) so we can
+	 * use this in our C3 policy
+	 */
+	cx->valid = 1;
+	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+	pr->flags.bm_check = 1;
+
+	return_VOID;
+}
+
+
+static int acpi_processor_power_verify(struct acpi_processor *pr)
+{
+	unsigned int i;
+	unsigned int working = 0;
+
+	for (i=1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		struct acpi_processor_cx *cx = &pr->power.states[i];
+
+		switch (cx->type) {
+		case ACPI_STATE_C1:
+			cx->valid = 1;
+			break;
+
+		case ACPI_STATE_C2:
+			acpi_processor_power_verify_c2(cx);
+			break;
+
+		case ACPI_STATE_C3:
+			acpi_processor_power_verify_c3(pr, cx);
+			break;
+		}
+
+		if (cx->valid)
+			working++;
+	}
+
+	return (working);
+}
+
+static int acpi_processor_get_power_info (
+	struct acpi_processor	*pr)
+{
+	unsigned int i;
+	int result;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info");
+
+	/* NOTE: the idle thread may not be running while calling
+	 * this function */
+
+	result = acpi_processor_get_power_info_cst(pr);
+	if ((result) || (acpi_processor_power_verify(pr) < 2)) {
+		result = acpi_processor_get_power_info_fadt(pr);
+		if (result)
+			return_VALUE(result);
+
+		if (acpi_processor_power_verify(pr) < 2)
+			return_VALUE(-ENODEV);
+	}
+
+	/*
+	 * Set Default Policy
+	 * ------------------
+	 * Now that we know which states are supported, set the default
+	 * policy.  Note that this policy can be changed dynamically
+	 * (e.g. encourage deeper sleeps to conserve battery life when
+	 * not on AC).
+	 */
+	result = acpi_processor_set_power_policy(pr);
+	if (result)
+		return_VALUE(result);
+
+	/*
+	 * if one state of type C2 or C3 is available, mark this
+	 * CPU as being "idle manageable"
+	 */
+	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+		if (pr->power.states[i].valid)
+			pr->power.count = i;
+		if ((pr->power.states[i].valid) &&
+		    (pr->power.states[i].type >= ACPI_STATE_C2))
+			pr->flags.power = 1;
+	}
+
+	return_VALUE(0);
+}
+
+int acpi_processor_cst_has_changed (struct acpi_processor *pr)
+{
+ 	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_cst_has_changed");
+
+	if (!pr)
+ 		return_VALUE(-EINVAL);
+
+	if (errata.smp || nocst) {
+		return_VALUE(-ENODEV);
+	}
+
+	if (!pr->flags.power_setup_done)
+		return_VALUE(-ENODEV);
+
+	/* Fall back to the default idle loop */
+	pm_idle = pm_idle_save;
+	synchronize_kernel();
+
+	pr->flags.power = 0;
+	result = acpi_processor_get_power_info(pr);
+	if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+		pm_idle = acpi_processor_idle;
+
+	return_VALUE(result);
+}
+
+/* proc interface */
+
+static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+	unsigned int		i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_power_seq_show");
+
+	if (!pr)
+		goto end;
+
+	seq_printf(seq, "active state:            C%zd\n"
+			"max_cstate:              C%d\n"
+			"bus master activity:     %08x\n",
+			pr->power.state ? pr->power.state - pr->power.states : 0,
+			max_cstate,
+			(unsigned)pr->power.bm_activity);
+
+	seq_puts(seq, "states:\n");
+
+	for (i = 1; i <= pr->power.count; i++) {
+		seq_printf(seq, "   %cC%d:                  ",
+			(&pr->power.states[i] == pr->power.state?'*':' '), i);
+
+		if (!pr->power.states[i].valid) {
+			seq_puts(seq, "<not supported>\n");
+			continue;
+		}
+
+		switch (pr->power.states[i].type) {
+		case ACPI_STATE_C1:
+			seq_printf(seq, "type[C1] ");
+			break;
+		case ACPI_STATE_C2:
+			seq_printf(seq, "type[C2] ");
+			break;
+		case ACPI_STATE_C3:
+			seq_printf(seq, "type[C3] ");
+			break;
+		default:
+			seq_printf(seq, "type[--] ");
+			break;
+		}
+
+		if (pr->power.states[i].promotion.state)
+			seq_printf(seq, "promotion[C%zd] ",
+				(pr->power.states[i].promotion.state -
+				 pr->power.states));
+		else
+			seq_puts(seq, "promotion[--] ");
+
+		if (pr->power.states[i].demotion.state)
+			seq_printf(seq, "demotion[C%zd] ",
+				(pr->power.states[i].demotion.state -
+				 pr->power.states));
+		else
+			seq_puts(seq, "demotion[--] ");
+
+		seq_printf(seq, "latency[%03d] usage[%08d]\n",
+			pr->power.states[i].latency,
+			pr->power.states[i].usage);
+	}
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_power_seq_show,
+						PDE(inode)->data);
+}
+
+static struct file_operations acpi_processor_power_fops = {
+	.open 		= acpi_processor_power_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device)
+{
+	acpi_status		status = 0;
+	static int		first_run = 0;
+	struct proc_dir_entry	*entry = NULL;
+	unsigned int i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_power_init");
+
+	if (!first_run) {
+		dmi_check_system(processor_power_dmi_table);
+		if (max_cstate < ACPI_C_STATES_MAX)
+			printk(KERN_NOTICE "ACPI: processor limited to max C-state %d\n", max_cstate);
+		first_run++;
+	}
+
+	if (!errata.smp && (pr->id == 0) && acpi_fadt.cst_cnt && !nocst) {
+		status = acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8);
+		if (ACPI_FAILURE(status)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "Notifying BIOS of _CST ability failed\n"));
+		}
+	}
+
+	acpi_processor_get_power_info(pr);
+
+	/*
+	 * Install the idle handler if processor power management is supported.
+	 * Note that we use previously set idle handler will be used on
+	 * platforms that only support C1.
+	 */
+	if ((pr->flags.power) && (!boot_option_idle_override)) {
+		printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
+		for (i = 1; i <= pr->power.count; i++)
+			if (pr->power.states[i].valid)
+				printk(" C%d[C%d]", i, pr->power.states[i].type);
+		printk(")\n");
+
+		if (pr->id == 0) {
+			pm_idle_save = pm_idle;
+			pm_idle = acpi_processor_idle;
+		}
+	}
+
+	/* 'power' [R] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_POWER));
+	else {
+		entry->proc_fops = &acpi_processor_power_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	pr->flags.power_setup_done = 1;
+
+	return_VALUE(0);
+}
+
+int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_power_exit");
+
+	pr->flags.power_setup_done = 0;
+
+	if (acpi_device_dir(device))
+		remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,acpi_device_dir(device));
+
+	/* Unregister the idle handler when processor #0 is removed. */
+	if (pr->id == 0) {
+		pm_idle = pm_idle_save;
+
+		/*
+		 * We are about to unload the current idle thread pm callback
+		 * (pm_idle), Wait for all processors to update cached/local
+		 * copies of pm_idle before proceeding.
+		 */
+		cpu_idle_wait();
+	}
+
+	return_VALUE(0);
+}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
new file mode 100644
index 0000000..a9a1a8f
--- /dev/null
+++ b/drivers/acpi/processor_perflib.c
@@ -0,0 +1,666 @@
+/*
+ * processor_perflib.c - ACPI Processor P-States Library ($Revision: 71 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug support
+ *
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/uaccess.h>
+#endif
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+
+
+#define ACPI_PROCESSOR_COMPONENT	0x01000000
+#define ACPI_PROCESSOR_CLASS		"processor"
+#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor Driver"
+#define ACPI_PROCESSOR_FILE_PERFORMANCE	"performance"
+#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME		("acpi_processor")
+
+
+static DECLARE_MUTEX(performance_sem);
+
+/*
+ * _PPC support is implemented as a CPUfreq policy notifier:
+ * This means each time a CPUfreq driver registered also with
+ * the ACPI core is asked to change the speed policy, the maximum
+ * value is adjusted so that it is within the platform limit.
+ *
+ * Also, when a new platform limit value is detected, the CPUfreq
+ * policy is adjusted accordingly.
+ */
+
+#define PPC_REGISTERED   1
+#define PPC_IN_USE       2
+
+static int acpi_processor_ppc_status = 0;
+
+static int acpi_processor_ppc_notifier(struct notifier_block *nb,
+	unsigned long event,
+	void *data)
+{
+	struct cpufreq_policy *policy = data;
+	struct acpi_processor *pr;
+	unsigned int ppc = 0;
+
+	down(&performance_sem);
+
+	if (event != CPUFREQ_INCOMPATIBLE)
+		goto out;
+
+	pr = processors[policy->cpu];
+	if (!pr || !pr->performance)
+		goto out;
+
+	ppc = (unsigned int) pr->performance_platform_limit;
+	if (!ppc)
+		goto out;
+
+	if (ppc > pr->performance->state_count)
+		goto out;
+
+	cpufreq_verify_within_limits(policy, 0,
+		pr->performance->states[ppc].core_frequency * 1000);
+
+ out:
+	up(&performance_sem);
+
+	return 0;
+}
+
+
+static struct notifier_block acpi_ppc_notifier_block = {
+	.notifier_call = acpi_processor_ppc_notifier,
+};
+
+
+static int
+acpi_processor_get_platform_limit (
+	struct acpi_processor*	pr)
+{
+	acpi_status		status = 0;
+	unsigned long		ppc = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_platform_limit");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/*
+	 * _PPC indicates the maximum state currently supported by the platform
+	 * (e.g. 0 = states 0..n; 1 = states 1..n; etc.
+	 */
+	status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc);
+
+	if (status != AE_NOT_FOUND)
+		acpi_processor_ppc_status |= PPC_IN_USE;
+
+	if(ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pr->performance_platform_limit = (int) ppc;
+
+	return_VALUE(0);
+}
+
+
+int acpi_processor_ppc_has_changed(
+	struct acpi_processor *pr)
+{
+	int ret = acpi_processor_get_platform_limit(pr);
+	if (ret < 0)
+		return (ret);
+	else
+		return cpufreq_update_policy(pr->id);
+}
+
+
+void acpi_processor_ppc_init(void) {
+	if (!cpufreq_register_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
+		acpi_processor_ppc_status |= PPC_REGISTERED;
+	else
+		printk(KERN_DEBUG "Warning: Processor Platform Limit not supported.\n");
+}
+
+
+void acpi_processor_ppc_exit(void) {
+	if (acpi_processor_ppc_status & PPC_REGISTERED)
+		cpufreq_unregister_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
+	acpi_processor_ppc_status &= ~PPC_REGISTERED;
+}
+
+/*
+ * when registering a cpufreq driver with this ACPI processor driver, the
+ * _PCT and _PSS structures are read out and written into struct
+ * acpi_processor_performance.
+ */
+static int acpi_processor_set_pdc (struct acpi_processor *pr)
+{
+	acpi_status             status = AE_OK;
+	u32			arg0_buf[3];
+	union acpi_object	arg0 = {ACPI_TYPE_BUFFER};
+	struct acpi_object_list no_object = {1, &arg0};
+	struct acpi_object_list *pdc;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
+
+	arg0.buffer.length = 12;
+	arg0.buffer.pointer = (u8 *) arg0_buf;
+	arg0_buf[0] = ACPI_PDC_REVISION_ID;
+	arg0_buf[1] = 0;
+	arg0_buf[2] = 0;
+
+	pdc = (pr->performance->pdc) ? pr->performance->pdc : &no_object;
+
+	status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
+
+	if ((ACPI_FAILURE(status)) && (pr->performance->pdc))
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Error evaluating _PDC, using legacy perf. control...\n"));
+
+	return_VALUE(status);
+}
+
+
+static int
+acpi_processor_get_performance_control (
+	struct acpi_processor *pr)
+{
+	int			result = 0;
+	acpi_status		status = 0;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*pct = NULL;
+	union acpi_object	obj = {0};
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
+
+	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
+	if(ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pct = (union acpi_object *) buffer.pointer;
+	if (!pct || (pct->type != ACPI_TYPE_PACKAGE)
+		|| (pct->package.count != 2)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	/*
+	 * control_register
+	 */
+
+	obj = pct->package.elements[0];
+
+	if ((obj.type != ACPI_TYPE_BUFFER)
+		|| (obj.buffer.length < sizeof(struct acpi_pct_register))
+		|| (obj.buffer.pointer == NULL)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Invalid _PCT data (control_register)\n"));
+		result = -EFAULT;
+		goto end;
+	}
+	memcpy(&pr->performance->control_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
+
+
+	/*
+	 * status_register
+	 */
+
+	obj = pct->package.elements[1];
+
+	if ((obj.type != ACPI_TYPE_BUFFER)
+		|| (obj.buffer.length < sizeof(struct acpi_pct_register))
+		|| (obj.buffer.pointer == NULL)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Invalid _PCT data (status_register)\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	memcpy(&pr->performance->status_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_processor_get_performance_states (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_buffer	format = {sizeof("NNNNNN"), "NNNNNN"};
+	struct acpi_buffer	state = {0, NULL};
+	union acpi_object 	*pss = NULL;
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
+
+	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
+	if(ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pss = (union acpi_object *) buffer.pointer;
+	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n",
+		pss->package.count));
+
+	pr->performance->state_count = pss->package.count;
+	pr->performance->states = kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, GFP_KERNEL);
+	if (!pr->performance->states) {
+		result = -ENOMEM;
+		goto end;
+	}
+
+	for (i = 0; i < pr->performance->state_count; i++) {
+
+		struct acpi_processor_px *px = &(pr->performance->states[i]);
+
+		state.length = sizeof(struct acpi_processor_px);
+		state.pointer = px;
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
+
+		status = acpi_extract_package(&(pss->package.elements[i]),
+			&format, &state);
+		if (ACPI_FAILURE(status)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+			result = -EFAULT;
+			kfree(pr->performance->states);
+			goto end;
+		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
+			i,
+			(u32) px->core_frequency,
+			(u32) px->power,
+			(u32) px->transition_latency,
+			(u32) px->bus_master_latency,
+			(u32) px->control,
+			(u32) px->status));
+
+		if (!px->core_frequency) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data: freq is zero\n"));
+			result = -EFAULT;
+			kfree(pr->performance->states);
+			goto end;
+		}
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_processor_get_performance_info (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	acpi_handle		handle = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
+
+	if (!pr || !pr->performance || !pr->handle)
+		return_VALUE(-EINVAL);
+
+	acpi_processor_set_pdc(pr);
+
+	status = acpi_get_handle(pr->handle, "_PCT", &handle);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"ACPI-based processor performance control unavailable\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	result = acpi_processor_get_performance_control(pr);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_processor_get_performance_states(pr);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_processor_get_platform_limit(pr);
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(0);
+}
+
+
+int acpi_processor_notify_smm(struct module *calling_module) {
+	acpi_status		status;
+	static int		is_done = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_notify_smm");
+
+	if (!(acpi_processor_ppc_status & PPC_REGISTERED))
+		return_VALUE(-EBUSY);
+
+	if (!try_module_get(calling_module))
+		return_VALUE(-EINVAL);
+
+	/* is_done is set to negative if an error occured,
+	 * and to postitive if _no_ error occured, but SMM
+	 * was already notified. This avoids double notification
+	 * which might lead to unexpected results...
+	 */
+	if (is_done > 0) {
+		module_put(calling_module);
+		return_VALUE(0);
+	}
+	else if (is_done < 0) {
+		module_put(calling_module);
+		return_VALUE(is_done);
+	}
+
+	is_done = -EIO;
+
+	/* Can't write pstate_cnt to smi_cmd if either value is zero */
+	if ((!acpi_fadt.smi_cmd) ||
+	    (!acpi_fadt.pstate_cnt)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"No SMI port or pstate_cnt\n"));
+		module_put(calling_module);
+		return_VALUE(0);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Writing pstate_cnt [0x%x] to smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
+
+	/* FADT v1 doesn't support pstate_cnt, many BIOS vendors use
+	 * it anyway, so we need to support it... */
+	if (acpi_fadt_is_v1) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Using v1.0 FADT reserved value for pstate_cnt\n"));
+	}
+
+	status = acpi_os_write_port (acpi_fadt.smi_cmd,
+				     (u32) acpi_fadt.pstate_cnt, 8);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Failed to write pstate_cnt [0x%x] to "
+				  "smi_cmd [0x%x]\n", acpi_fadt.pstate_cnt, acpi_fadt.smi_cmd));
+		module_put(calling_module);
+		return_VALUE(status);
+	}
+
+	/* Success. If there's no _PPC, we need to fear nothing, so
+	 * we can allow the cpufreq driver to be rmmod'ed. */
+	is_done = 1;
+
+	if (!(acpi_processor_ppc_status & PPC_IN_USE))
+		module_put(calling_module);
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_processor_notify_smm);
+
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
+/* /proc/acpi/processor/../performance interface (DEPRECATED) */
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_processor_perf_fops = {
+	.open 		= acpi_processor_perf_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
+
+	if (!pr)
+		goto end;
+
+	if (!pr->performance) {
+		seq_puts(seq, "<not supported>\n");
+		goto end;
+	}
+
+	seq_printf(seq, "state count:             %d\n"
+			"active state:            P%d\n",
+			pr->performance->state_count,
+			pr->performance->state);
+
+	seq_puts(seq, "states:\n");
+	for (i = 0; i < pr->performance->state_count; i++)
+		seq_printf(seq, "   %cP%d:                  %d MHz, %d mW, %d uS\n",
+			(i == pr->performance->state?'*':' '), i,
+			(u32) pr->performance->states[i].core_frequency,
+			(u32) pr->performance->states[i].power,
+			(u32) pr->performance->states[i].transition_latency);
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_perf_seq_show,
+						PDE(inode)->data);
+}
+
+static ssize_t
+acpi_processor_write_performance (
+        struct file		*file,
+        const char		__user *buffer,
+        size_t			count,
+        loff_t			*data)
+{
+	int			result = 0;
+	struct seq_file		*m = (struct seq_file *) file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *) m->private;
+	struct acpi_processor_performance *perf;
+	char			state_string[12] = {'\0'};
+	unsigned int            new_state = 0;
+	struct cpufreq_policy   policy;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
+
+	if (!pr || (count > sizeof(state_string) - 1))
+		return_VALUE(-EINVAL);
+
+	perf = pr->performance;
+	if (!perf)
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(state_string, buffer, count))
+		return_VALUE(-EFAULT);
+
+	state_string[count] = '\0';
+	new_state = simple_strtoul(state_string, NULL, 0);
+
+	if (new_state >= perf->state_count)
+		return_VALUE(-EINVAL);
+
+	cpufreq_get_policy(&policy, pr->id);
+
+	policy.cpu = pr->id;
+	policy.min = perf->states[new_state].core_frequency * 1000;
+	policy.max = perf->states[new_state].core_frequency * 1000;
+
+	result = cpufreq_set_policy(&policy);
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(count);
+}
+
+static void
+acpi_cpufreq_add_file (
+	struct acpi_processor *pr)
+{
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* add file 'performance' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_PERFORMANCE));
+	else {
+		entry->proc_fops = &acpi_processor_perf_fops;
+		entry->proc_fops->write = acpi_processor_write_performance;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+	return_VOID;
+}
+
+static void
+acpi_cpufreq_remove_file (
+	struct acpi_processor *pr)
+{
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* remove file 'performance' */
+	remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  acpi_device_dir(device));
+
+	return_VOID;
+}
+
+#else
+static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
+static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
+#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
+
+
+int
+acpi_processor_register_performance (
+	struct acpi_processor_performance * performance,
+	unsigned int cpu)
+{
+	struct acpi_processor *pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_register_performance");
+
+	if (!(acpi_processor_ppc_status & PPC_REGISTERED))
+		return_VALUE(-EINVAL);
+
+	down(&performance_sem);
+
+	pr = processors[cpu];
+	if (!pr) {
+		up(&performance_sem);
+		return_VALUE(-ENODEV);
+	}
+
+	if (pr->performance) {
+		up(&performance_sem);
+		return_VALUE(-EBUSY);
+	}
+
+	pr->performance = performance;
+
+	if (acpi_processor_get_performance_info(pr)) {
+		pr->performance = NULL;
+		up(&performance_sem);
+		return_VALUE(-EIO);
+	}
+
+	acpi_cpufreq_add_file(pr);
+
+	up(&performance_sem);
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_processor_register_performance);
+
+
+void
+acpi_processor_unregister_performance (
+	struct acpi_processor_performance * performance,
+	unsigned int cpu)
+{
+	struct acpi_processor *pr;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_unregister_performance");
+
+	down(&performance_sem);
+
+	pr = processors[cpu];
+	if (!pr) {
+		up(&performance_sem);
+		return_VOID;
+	}
+
+	kfree(pr->performance->states);
+	pr->performance = NULL;
+
+	acpi_cpufreq_remove_file(pr);
+
+	up(&performance_sem);
+
+	return_VOID;
+}
+EXPORT_SYMBOL(acpi_processor_unregister_performance);
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
new file mode 100644
index 0000000..12bd980
--- /dev/null
+++ b/drivers/acpi/processor_thermal.c
@@ -0,0 +1,406 @@
+/*
+ * processor_thermal.c - Passive cooling submodule of the ACPI processor driver
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug support
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_PROCESSOR_COMPONENT        0x01000000
+#define ACPI_PROCESSOR_CLASS            "processor"
+#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
+#define _COMPONENT              ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME                ("acpi_processor")
+
+
+/* --------------------------------------------------------------------------
+                                 Limit Interface
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_processor_apply_limit (
+	struct acpi_processor* 	pr)
+{
+	int			result = 0;
+	u16			px = 0;
+	u16			tx = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_apply_limit");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (!pr->flags.limit)
+		return_VALUE(-ENODEV);
+
+	if (pr->flags.throttling) {
+		if (pr->limit.user.tx > tx)
+			tx = pr->limit.user.tx;
+		if (pr->limit.thermal.tx > tx)
+			tx = pr->limit.thermal.tx;
+
+		result = acpi_processor_set_throttling(pr, tx);
+		if (result)
+			goto end;
+	}
+
+	pr->limit.state.px = px;
+	pr->limit.state.tx = tx;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d] limit set to (P%d:T%d)\n",
+		pr->id,
+		pr->limit.state.px,
+		pr->limit.state.tx));
+
+end:
+	if (result)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n"));
+
+	return_VALUE(result);
+}
+
+
+#ifdef CONFIG_CPU_FREQ
+
+/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
+ * offers (in most cases) voltage scaling in addition to frequency scaling, and
+ * thus a cubic (instead of linear) reduction of energy. Also, we allow for
+ * _any_ cpufreq driver and not only the acpi-cpufreq driver.
+ */
+
+static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
+static unsigned int acpi_thermal_cpufreq_is_init = 0;
+
+
+static int cpu_has_cpufreq(unsigned int cpu)
+{
+	struct cpufreq_policy policy;
+	if (!acpi_thermal_cpufreq_is_init)
+		return -ENODEV;
+	if (!cpufreq_get_policy(&policy, cpu))
+		return -ENODEV;
+	return 0;
+}
+
+
+static int acpi_thermal_cpufreq_increase(unsigned int cpu)
+{
+	if (!cpu_has_cpufreq(cpu))
+		return -ENODEV;
+
+	if (cpufreq_thermal_reduction_pctg[cpu] < 60) {
+		cpufreq_thermal_reduction_pctg[cpu] += 20;
+		cpufreq_update_policy(cpu);
+		return 0;
+	}
+
+	return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
+{
+	if (!cpu_has_cpufreq(cpu))
+		return -ENODEV;
+
+	if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
+		cpufreq_thermal_reduction_pctg[cpu] -= 20;
+		cpufreq_update_policy(cpu);
+		return 0;
+	}
+
+	return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_notifier(
+	struct notifier_block *nb,
+	unsigned long event,
+	void *data)
+{
+	struct cpufreq_policy *policy = data;
+	unsigned long max_freq = 0;
+
+	if (event != CPUFREQ_ADJUST)
+		goto out;
+
+	max_freq = (policy->cpuinfo.max_freq * (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
+
+	cpufreq_verify_within_limits(policy, 0, max_freq);
+
+ out:
+	return 0;
+}
+
+
+static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
+	.notifier_call = acpi_thermal_cpufreq_notifier,
+};
+
+
+void acpi_thermal_cpufreq_init(void) {
+	int i;
+
+	for (i=0; i<NR_CPUS; i++)
+		cpufreq_thermal_reduction_pctg[i] = 0;
+
+	i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+	if (!i)
+		acpi_thermal_cpufreq_is_init = 1;
+}
+
+void acpi_thermal_cpufreq_exit(void) {
+	if (acpi_thermal_cpufreq_is_init)
+		cpufreq_unregister_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
+	acpi_thermal_cpufreq_is_init = 0;
+}
+
+#else /* ! CONFIG_CPU_FREQ */
+
+static int acpi_thermal_cpufreq_increase(unsigned int cpu) { return -ENODEV; }
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu) { return -ENODEV; }
+
+
+#endif
+
+
+int
+acpi_processor_set_thermal_limit (
+	acpi_handle		handle,
+	int			type)
+{
+	int			result = 0;
+	struct acpi_processor	*pr = NULL;
+	struct acpi_device	*device = NULL;
+	int			tx = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
+
+	if ((type < ACPI_PROCESSOR_LIMIT_NONE)
+		|| (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
+		return_VALUE(-EINVAL);
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result)
+		return_VALUE(result);
+
+	pr = (struct acpi_processor *) acpi_driver_data(device);
+	if (!pr)
+		return_VALUE(-ENODEV);
+
+	/* Thermal limits are always relative to the current Px/Tx state. */
+	if (pr->flags.throttling)
+		pr->limit.thermal.tx = pr->throttling.state;
+
+	/*
+	 * Our default policy is to only use throttling at the lowest
+	 * performance state.
+	 */
+
+	tx = pr->limit.thermal.tx;
+
+	switch (type) {
+
+	case ACPI_PROCESSOR_LIMIT_NONE:
+		do {
+			result = acpi_thermal_cpufreq_decrease(pr->id);
+		} while (!result);
+		tx = 0;
+		break;
+
+	case ACPI_PROCESSOR_LIMIT_INCREMENT:
+		/* if going up: P-states first, T-states later */
+
+		result = acpi_thermal_cpufreq_increase(pr->id);
+		if (!result)
+			goto end;
+		else if (result == -ERANGE)
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At maximum performance state\n"));
+
+		if (pr->flags.throttling) {
+			if (tx == (pr->throttling.state_count - 1))
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At maximum throttling state\n"));
+			else
+				tx++;
+		}
+		break;
+
+	case ACPI_PROCESSOR_LIMIT_DECREMENT:
+		/* if going down: T-states first, P-states later */
+
+		if (pr->flags.throttling) {
+			if (tx == 0)
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At minimum throttling state\n"));
+			else {
+				tx--;
+				goto end;
+			}
+		}
+
+		result = acpi_thermal_cpufreq_decrease(pr->id);
+		if (result == -ERANGE)
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"At minimum performance state\n"));
+
+		break;
+	}
+
+end:
+	if (pr->flags.throttling) {
+		pr->limit.thermal.px = 0;
+		pr->limit.thermal.tx = tx;
+
+		result = acpi_processor_apply_limit(pr);
+		if (result)
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "Unable to set thermal limit\n"));
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
+				  pr->limit.thermal.px,
+				  pr->limit.thermal.tx));
+	} else
+		result = 0;
+
+	return_VALUE(result);
+}
+
+
+int
+acpi_processor_get_limit_info (
+	struct acpi_processor	*pr)
+{
+	ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (pr->flags.throttling)
+		pr->flags.limit = 1;
+
+	return_VALUE(0);
+}
+
+
+/* /proc interface */
+
+static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_limit_seq_show");
+
+	if (!pr)
+		goto end;
+
+	if (!pr->flags.limit) {
+		seq_puts(seq, "<not supported>\n");
+		goto end;
+	}
+
+	seq_printf(seq, "active limit:            P%d:T%d\n"
+			"user limit:              P%d:T%d\n"
+			"thermal limit:           P%d:T%d\n",
+			pr->limit.state.px, pr->limit.state.tx,
+			pr->limit.user.px, pr->limit.user.tx,
+			pr->limit.thermal.px, pr->limit.thermal.tx);
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_limit_seq_show,
+						PDE(inode)->data);
+}
+
+ssize_t acpi_processor_write_limit (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*data)
+{
+	int			result = 0;
+        struct seq_file 	*m = (struct seq_file *)file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
+	char			limit_string[25] = {'\0'};
+	int			px = 0;
+	int			tx = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_write_limit");
+
+	if (!pr || (count > sizeof(limit_string) - 1)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (copy_from_user(limit_string, buffer, count)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
+		return_VALUE(-EFAULT);
+	}
+
+	limit_string[count] = '\0';
+
+	if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (pr->flags.throttling) {
+		if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n"));
+			return_VALUE(-EINVAL);
+		}
+		pr->limit.user.tx = tx;
+	}
+
+	result = acpi_processor_apply_limit(pr);
+
+	return_VALUE(count);
+}
+
+
+struct file_operations acpi_processor_limit_fops = {
+	.open 		= acpi_processor_limit_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
new file mode 100644
index 0000000..be9f569
--- /dev/null
+++ b/drivers/acpi/processor_throttling.c
@@ -0,0 +1,351 @@
+/*
+ * processor_throttling.c - Throttling submodule of the ACPI processor driver
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *  			- Added processor hotplug support
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/processor.h>
+
+#define ACPI_PROCESSOR_COMPONENT        0x01000000
+#define ACPI_PROCESSOR_CLASS            "processor"
+#define ACPI_PROCESSOR_DRIVER_NAME      "ACPI Processor Driver"
+#define _COMPONENT              ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME                ("acpi_processor")
+
+
+/* --------------------------------------------------------------------------
+                              Throttling Control
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_processor_get_throttling (
+	struct acpi_processor	*pr)
+{
+	int			state = 0;
+	u32			value = 0;
+	u32			duty_mask = 0;
+	u32			duty_value = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_throttling");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (!pr->flags.throttling)
+		return_VALUE(-ENODEV);
+
+	pr->throttling.state = 0;
+
+	duty_mask = pr->throttling.state_count - 1;
+
+	duty_mask <<= pr->throttling.duty_offset;
+
+	local_irq_disable();
+
+	value = inl(pr->throttling.address);
+
+	/*
+	 * Compute the current throttling state when throttling is enabled
+	 * (bit 4 is on).
+	 */
+	if (value & 0x10) {
+		duty_value = value & duty_mask;
+		duty_value >>= pr->throttling.duty_offset;
+
+		if (duty_value)
+			state = pr->throttling.state_count-duty_value;
+	}
+
+	pr->throttling.state = state;
+
+	local_irq_enable();
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"Throttling state is T%d (%d%% throttling applied)\n",
+		state, pr->throttling.states[state].performance));
+
+	return_VALUE(0);
+}
+
+
+int acpi_processor_set_throttling (
+	struct acpi_processor	*pr,
+	int			state)
+{
+	u32                     value = 0;
+	u32                     duty_mask = 0;
+	u32                     duty_value = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_set_throttling");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if ((state < 0) || (state > (pr->throttling.state_count - 1)))
+		return_VALUE(-EINVAL);
+
+	if (!pr->flags.throttling)
+		return_VALUE(-ENODEV);
+
+	if (state == pr->throttling.state)
+		return_VALUE(0);
+
+	/*
+	 * Calculate the duty_value and duty_mask.
+	 */
+	if (state) {
+		duty_value = pr->throttling.state_count - state;
+
+		duty_value <<= pr->throttling.duty_offset;
+
+		/* Used to clear all duty_value bits */
+		duty_mask = pr->throttling.state_count - 1;
+
+		duty_mask <<= acpi_fadt.duty_offset;
+		duty_mask = ~duty_mask;
+	}
+
+	local_irq_disable();
+
+	/*
+	 * Disable throttling by writing a 0 to bit 4.  Note that we must
+	 * turn it off before you can change the duty_value.
+	 */
+	value = inl(pr->throttling.address);
+	if (value & 0x10) {
+		value &= 0xFFFFFFEF;
+		outl(value, pr->throttling.address);
+	}
+
+	/*
+	 * Write the new duty_value and then enable throttling.  Note
+	 * that a state value of 0 leaves throttling disabled.
+	 */
+	if (state) {
+		value &= duty_mask;
+		value |= duty_value;
+		outl(value, pr->throttling.address);
+
+		value |= 0x00000010;
+		outl(value, pr->throttling.address);
+	}
+
+	pr->throttling.state = state;
+
+	local_irq_enable();
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"Throttling state set to T%d (%d%%)\n", state,
+		(pr->throttling.states[state].performance?pr->throttling.states[state].performance/10:0)));
+
+	return_VALUE(0);
+}
+
+
+int
+acpi_processor_get_throttling_info (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	int			step = 0;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_throttling_info");
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
+		pr->throttling.address,
+		pr->throttling.duty_offset,
+		pr->throttling.duty_width));
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	/* TBD: Support ACPI 2.0 objects */
+
+	if (!pr->throttling.address) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
+		return_VALUE(0);
+	}
+	else if (!pr->throttling.duty_width) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
+		return_VALUE(0);
+	}
+	/* TBD: Support duty_cycle values that span bit 4. */
+	else if ((pr->throttling.duty_offset
+		+ pr->throttling.duty_width) > 4) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "duty_cycle spans bit 4\n"));
+		return_VALUE(0);
+	}
+
+	/*
+	 * PIIX4 Errata: We don't support throttling on the original PIIX4.
+	 * This shouldn't be an issue as few (if any) mobile systems ever
+	 * used this part.
+	 */
+	if (errata.piix4.throttle) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Throttling not supported on PIIX4 A- or B-step\n"));
+		return_VALUE(0);
+	}
+
+	pr->throttling.state_count = 1 << acpi_fadt.duty_width;
+
+	/*
+	 * Compute state values. Note that throttling displays a linear power/
+	 * performance relationship (at 50% performance the CPU will consume
+	 * 50% power).  Values are in 1/10th of a percent to preserve accuracy.
+	 */
+
+	step = (1000 / pr->throttling.state_count);
+
+	for (i=0; i<pr->throttling.state_count; i++) {
+		pr->throttling.states[i].performance = step * i;
+		pr->throttling.states[i].power = step * i;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
+		pr->throttling.state_count));
+
+	pr->flags.throttling = 1;
+
+	/*
+	 * Disable throttling (if enabled).  We'll let subsequent policy (e.g.
+	 * thermal) decide to lower performance if it so chooses, but for now
+	 * we'll crank up the speed.
+	 */
+
+	result = acpi_processor_get_throttling(pr);
+	if (result)
+		goto end;
+
+	if (pr->throttling.state) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabling throttling (was T%d)\n",
+			pr->throttling.state));
+		result = acpi_processor_set_throttling(pr, 0);
+		if (result)
+			goto end;
+	}
+
+end:
+	if (result)
+		pr->flags.throttling = 0;
+
+	return_VALUE(result);
+}
+
+
+/* proc interface */
+
+static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+	int			i = 0;
+	int                     result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_throttling_seq_show");
+
+	if (!pr)
+		goto end;
+
+	if (!(pr->throttling.state_count > 0)) {
+		seq_puts(seq, "<not supported>\n");
+		goto end;
+	}
+
+	result = acpi_processor_get_throttling(pr);
+
+	if (result) {
+		seq_puts(seq, "Could not determine current throttling state.\n");
+		goto end;
+	}
+
+	seq_printf(seq, "state count:             %d\n"
+			"active state:            T%d\n",
+			pr->throttling.state_count,
+			pr->throttling.state);
+
+	seq_puts(seq, "states:\n");
+	for (i = 0; i < pr->throttling.state_count; i++)
+		seq_printf(seq, "   %cT%d:                  %02d%%\n",
+			(i == pr->throttling.state?'*':' '), i,
+			(pr->throttling.states[i].performance?pr->throttling.states[i].performance/10:0));
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_throttling_seq_show,
+						PDE(inode)->data);
+}
+
+ssize_t acpi_processor_write_throttling (
+        struct file		*file,
+        const char		__user *buffer,
+        size_t			count,
+        loff_t			*data)
+{
+	int			result = 0;
+        struct seq_file 	*m = (struct seq_file *)file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
+	char			state_string[12] = {'\0'};
+
+	ACPI_FUNCTION_TRACE("acpi_processor_write_throttling");
+
+	if (!pr || (count > sizeof(state_string) - 1))
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(state_string, buffer, count))
+		return_VALUE(-EFAULT);
+
+	state_string[count] = '\0';
+
+	result = acpi_processor_set_throttling(pr,
+		simple_strtoul(state_string, NULL, 0));
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(count);
+}
+
+struct file_operations acpi_processor_throttling_fops = {
+	.open 		= acpi_processor_throttling_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
diff --git a/drivers/acpi/resources/Makefile b/drivers/acpi/resources/Makefile
new file mode 100644
index 0000000..2130b74
--- /dev/null
+++ b/drivers/acpi/resources/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := rsaddr.o  rscreate.o  rsio.o   rslist.o    rsmisc.o   rsxface.o \
+	 rscalc.o  rsirq.o  rsmemory.o  rsutils.o
+
+obj-$(ACPI_FUTURE_USAGE) += rsdump.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
new file mode 100644
index 0000000..4788c07
--- /dev/null
+++ b/drivers/acpi/resources/rsaddr.c
@@ -0,0 +1,1225 @@
+/*******************************************************************************
+ *
+ * Module Name: rsaddr - Address resource descriptors (16/32/64)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsaddr")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_address16_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_address16_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u8                              *temp_ptr;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16);
+	u32                             index;
+	u16                             temp16;
+	u8                              temp8;
+
+
+	ACPI_FUNCTION_TRACE ("rs_address16_resource");
+
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	/* Validate minimum descriptor length */
+
+	if (temp16 < 13) {
+		return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+	}
+
+	*bytes_consumed = temp16 + 3;
+	output_struct->id = ACPI_RSTYPE_ADDRESS16;
+
+	/*
+	 * Get the Resource Type (Byte3)
+	 */
+	buffer += 2;
+	temp8 = *buffer;
+
+	/* Values 0-2 and 0xC0-0xFF are valid */
+
+	if ((temp8 > 2) && (temp8 < 0xC0)) {
+		return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+	}
+
+	output_struct->data.address16.resource_type = temp8;
+
+	/*
+	 * Get the General Flags (Byte4)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	/* Producer / Consumer */
+
+	output_struct->data.address16.producer_consumer = temp8 & 0x01;
+
+	/* Decode */
+
+	output_struct->data.address16.decode = (temp8 >> 1) & 0x01;
+
+	/* Min Address Fixed */
+
+	output_struct->data.address16.min_address_fixed = (temp8 >> 2) & 0x01;
+
+	/* Max Address Fixed */
+
+	output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01;
+
+	/*
+	 * Get the Type Specific Flags (Byte5)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	if (ACPI_MEMORY_RANGE == output_struct->data.address16.resource_type) {
+		output_struct->data.address16.attribute.memory.read_write_attribute =
+				(u16) (temp8 & 0x01);
+		output_struct->data.address16.attribute.memory.cache_attribute =
+				(u16) ((temp8 >> 1) & 0x03);
+	}
+	else {
+		if (ACPI_IO_RANGE == output_struct->data.address16.resource_type) {
+			output_struct->data.address16.attribute.io.range_attribute =
+				(u16) (temp8 & 0x03);
+			output_struct->data.address16.attribute.io.translation_attribute =
+				(u16) ((temp8 >> 4) & 0x03);
+		}
+		else {
+			/* BUS_NUMBER_RANGE == Address16.Data->resource_type */
+			/* Nothing needs to be filled in */
+		}
+	}
+
+	/*
+	 * Get Granularity (Bytes 6-7)
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.granularity, buffer);
+
+	/*
+	 * Get min_address_range (Bytes 8-9)
+	 */
+	buffer += 2;
+	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.min_address_range, buffer);
+
+	/*
+	 * Get max_address_range (Bytes 10-11)
+	 */
+	buffer += 2;
+	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.max_address_range, buffer);
+
+	/*
+	 * Get address_translation_offset (Bytes 12-13)
+	 */
+	buffer += 2;
+	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset, buffer);
+
+	/*
+	 * Get address_length (Bytes 14-15)
+	 */
+	buffer += 2;
+	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_length, buffer);
+
+	/*
+	 * Resource Source Index (if present)
+	 */
+	buffer += 2;
+
+	/*
+	 * This will leave us pointing to the Resource Source Index
+	 * If it is present, then save it off and calculate the
+	 * pointer to where the null terminated string goes:
+	 * Each Interrupt takes 32-bits + the 5 bytes of the
+	 * stream that are default.
+	 *
+	 * Note: Some resource descriptors will have an additional null, so
+	 * we add 1 to the length.
+	 */
+	if (*bytes_consumed > (16 + 1)) {
+		/* Dereference the Index */
+
+		temp8 = *buffer;
+		output_struct->data.address16.resource_source.index = (u32) temp8;
+
+		/* Point to the String */
+
+		buffer += 1;
+
+		/* Point the String pointer to the end of this structure */
+
+		output_struct->data.address16.resource_source.string_ptr =
+				(char *)((u8 * )output_struct + struct_size);
+
+		temp_ptr = (u8 *) output_struct->data.address16.resource_source.string_ptr;
+
+		/* Copy the string into the buffer */
+
+		index = 0;
+
+		while (0x00 != *buffer) {
+			*temp_ptr = *buffer;
+
+			temp_ptr += 1;
+			buffer += 1;
+			index += 1;
+		}
+
+		/*
+		 * Add the terminating null
+		 */
+		*temp_ptr = 0x00;
+
+		output_struct->data.address16.resource_source.string_length = index + 1;
+
+		/*
+		 * In order for the struct_size to fall on a 32-bit boundary,
+		 * calculate the length of the string and expand the
+		 * struct_size to the next 32-bit boundary.
+		 */
+		temp8 = (u8) (index + 1);
+		struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
+	}
+	else {
+		output_struct->data.address16.resource_source.index = 0x00;
+		output_struct->data.address16.resource_source.string_length = 0;
+		output_struct->data.address16.resource_source.string_ptr = NULL;
+	}
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_address16_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_address16_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u8                              *length_field;
+	u8                              temp8;
+	char                            *temp_pointer = NULL;
+	acpi_size                       actual_bytes;
+
+
+	ACPI_FUNCTION_TRACE ("rs_address16_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x88;
+	buffer += 1;
+
+	/*
+	 * Save a pointer to the Length field - to be filled in later
+	 */
+	length_field = buffer;
+	buffer += 2;
+
+	/*
+	 * Set the Resource Type (Memory, Io, bus_number)
+	 */
+	temp8 = (u8) (linked_list->data.address16.resource_type & 0x03);
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the general flags
+	 */
+	temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01);
+
+	temp8 |= (linked_list->data.address16.decode & 0x01) << 1;
+	temp8 |= (linked_list->data.address16.min_address_fixed & 0x01) << 2;
+	temp8 |= (linked_list->data.address16.max_address_fixed & 0x01) << 3;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the type specific flags
+	 */
+	temp8 = 0;
+
+	if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address16.attribute.memory.read_write_attribute &
+			 0x01);
+
+		temp8 |=
+			(linked_list->data.address16.attribute.memory.cache_attribute &
+			 0x03) << 1;
+	}
+	else if (ACPI_IO_RANGE == linked_list->data.address16.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address16.attribute.io.range_attribute &
+			 0x03);
+		temp8 |=
+			(linked_list->data.address16.attribute.io.translation_attribute &
+			 0x03) << 4;
+	}
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the address space granularity
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.granularity);
+	buffer += 2;
+
+	/*
+	 * Set the address range minimum
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.min_address_range);
+	buffer += 2;
+
+	/*
+	 * Set the address range maximum
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.max_address_range);
+	buffer += 2;
+
+	/*
+	 * Set the address translation offset
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_translation_offset);
+	buffer += 2;
+
+	/*
+	 * Set the address length
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_length);
+	buffer += 2;
+
+	/*
+	 * Resource Source Index and Resource Source are optional
+	 */
+	if (0 != linked_list->data.address16.resource_source.string_length) {
+		temp8 = (u8) linked_list->data.address16.resource_source.index;
+
+		*buffer = temp8;
+		buffer += 1;
+
+		temp_pointer = (char *) buffer;
+
+		/*
+		 * Copy the string
+		 */
+		ACPI_STRCPY (temp_pointer,
+				linked_list->data.address16.resource_source.string_ptr);
+
+		/*
+		 * Buffer needs to be set to the length of the sting + one for the
+		 * terminating null
+		 */
+		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address16.resource_source.string_ptr) + 1);
+	}
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	actual_bytes = ACPI_PTR_DIFF (buffer, *output_buffer);
+	*bytes_consumed = actual_bytes;
+
+	/*
+	 * Set the length field to the number of bytes consumed
+	 * minus the header size (3 bytes)
+	 */
+	actual_bytes -= 3;
+	ACPI_MOVE_SIZE_TO_16 (length_field, &actual_bytes);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_address32_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_address32_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer;
+	struct acpi_resource            *output_struct= (void *) *output_buffer;
+	u16                             temp16;
+	u8                              temp8;
+	u8                              *temp_ptr;
+	acpi_size                       struct_size;
+	u32                             index;
+
+
+	ACPI_FUNCTION_TRACE ("rs_address32_resource");
+
+
+	buffer = byte_stream_buffer;
+	struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32);
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	/* Validate minimum descriptor length */
+
+	if (temp16 < 23) {
+		return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+	}
+
+	*bytes_consumed = temp16 + 3;
+	output_struct->id = ACPI_RSTYPE_ADDRESS32;
+
+	/*
+	 * Get the Resource Type (Byte3)
+	 */
+	buffer += 2;
+	temp8 = *buffer;
+
+	/* Values 0-2 and 0xC0-0xFF are valid */
+
+	if ((temp8 > 2) && (temp8 < 0xC0)) {
+		return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+	}
+
+	output_struct->data.address32.resource_type = temp8;
+
+	/*
+	 * Get the General Flags (Byte4)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	/*
+	 * Producer / Consumer
+	 */
+	output_struct->data.address32.producer_consumer = temp8 & 0x01;
+
+	/*
+	 * Decode
+	 */
+	output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
+
+	/*
+	 * Min Address Fixed
+	 */
+	output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
+
+	/*
+	 * Max Address Fixed
+	 */
+	output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
+
+	/*
+	 * Get the Type Specific Flags (Byte5)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	if (ACPI_MEMORY_RANGE == output_struct->data.address32.resource_type) {
+		output_struct->data.address32.attribute.memory.read_write_attribute =
+				(u16) (temp8 & 0x01);
+
+		output_struct->data.address32.attribute.memory.cache_attribute =
+				(u16) ((temp8 >> 1) & 0x03);
+	}
+	else {
+		if (ACPI_IO_RANGE == output_struct->data.address32.resource_type) {
+			output_struct->data.address32.attribute.io.range_attribute =
+				(u16) (temp8 & 0x03);
+			output_struct->data.address32.attribute.io.translation_attribute =
+				(u16) ((temp8 >> 4) & 0x03);
+		}
+		else {
+			/* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */
+			/* Nothing needs to be filled in */
+		}
+	}
+
+	/*
+	 * Get Granularity (Bytes 6-9)
+	 */
+	buffer += 1;
+	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer);
+
+	/*
+	 * Get min_address_range (Bytes 10-13)
+	 */
+	buffer += 4;
+	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer);
+
+	/*
+	 * Get max_address_range (Bytes 14-17)
+	 */
+	buffer += 4;
+	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer);
+
+	/*
+	 * Get address_translation_offset (Bytes 18-21)
+	 */
+	buffer += 4;
+	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset, buffer);
+
+	/*
+	 * Get address_length (Bytes 22-25)
+	 */
+	buffer += 4;
+	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer);
+
+	/*
+	 * Resource Source Index (if present)
+	 */
+	buffer += 4;
+
+	/*
+	 * This will leave us pointing to the Resource Source Index
+	 * If it is present, then save it off and calculate the
+	 * pointer to where the null terminated string goes:
+	 *
+	 * Note: Some resource descriptors will have an additional null, so
+	 * we add 1 to the length.
+	 */
+	if (*bytes_consumed > (26 + 1)) {
+		/* Dereference the Index */
+
+		temp8 = *buffer;
+		output_struct->data.address32.resource_source.index =
+				(u32) temp8;
+
+		/* Point to the String */
+
+		buffer += 1;
+
+		/* Point the String pointer to the end of this structure */
+
+		output_struct->data.address32.resource_source.string_ptr =
+				(char *)((u8 *)output_struct + struct_size);
+
+		temp_ptr = (u8 *) output_struct->data.address32.resource_source.string_ptr;
+
+		/* Copy the string into the buffer */
+
+		index = 0;
+		while (0x00 != *buffer) {
+			*temp_ptr = *buffer;
+
+			temp_ptr += 1;
+			buffer += 1;
+			index += 1;
+		}
+
+		/*
+		 * Add the terminating null
+		 */
+		*temp_ptr = 0x00;
+		output_struct->data.address32.resource_source.string_length = index + 1;
+
+		/*
+		 * In order for the struct_size to fall on a 32-bit boundary,
+		 * calculate the length of the string and expand the
+		 * struct_size to the next 32-bit boundary.
+		 */
+		temp8 = (u8) (index + 1);
+		struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
+	}
+	else {
+		output_struct->data.address32.resource_source.index = 0x00;
+		output_struct->data.address32.resource_source.string_length = 0;
+		output_struct->data.address32.resource_source.string_ptr = NULL;
+	}
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_address32_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_address32_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer;
+	u16                             *length_field;
+	u8                              temp8;
+	char                            *temp_pointer;
+
+
+	ACPI_FUNCTION_TRACE ("rs_address32_stream");
+
+
+	buffer = *output_buffer;
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x87;
+	buffer += 1;
+
+	/*
+	 * Set a pointer to the Length field - to be filled in later
+	 */
+	length_field = ACPI_CAST_PTR (u16, buffer);
+	buffer += 2;
+
+	/*
+	 * Set the Resource Type (Memory, Io, bus_number)
+	 */
+	temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the general flags
+	 */
+	temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
+	temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
+	temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
+	temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the type specific flags
+	 */
+	temp8 = 0;
+
+	if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address32.attribute.memory.read_write_attribute &
+			0x01);
+
+		temp8 |=
+			(linked_list->data.address32.attribute.memory.cache_attribute &
+			 0x03) << 1;
+	}
+	else if (ACPI_IO_RANGE == linked_list->data.address32.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address32.attribute.io.range_attribute &
+			 0x03);
+		temp8 |=
+			(linked_list->data.address32.attribute.io.translation_attribute &
+			 0x03) << 4;
+	}
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the address space granularity
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity);
+	buffer += 4;
+
+	/*
+	 * Set the address range minimum
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range);
+	buffer += 4;
+
+	/*
+	 * Set the address range maximum
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range);
+	buffer += 4;
+
+	/*
+	 * Set the address translation offset
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset);
+	buffer += 4;
+
+	/*
+	 * Set the address length
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length);
+	buffer += 4;
+
+	/*
+	 * Resource Source Index and Resource Source are optional
+	 */
+	if (0 != linked_list->data.address32.resource_source.string_length) {
+		temp8 = (u8) linked_list->data.address32.resource_source.index;
+
+		*buffer = temp8;
+		buffer += 1;
+
+		temp_pointer = (char *) buffer;
+
+		/*
+		 * Copy the string
+		 */
+		ACPI_STRCPY (temp_pointer,
+			linked_list->data.address32.resource_source.string_ptr);
+
+		/*
+		 * Buffer needs to be set to the length of the sting + one for the
+		 *  terminating null
+		 */
+		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1);
+	}
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+
+	/*
+	 * Set the length field to the number of bytes consumed
+	 *  minus the header size (3 bytes)
+	 */
+	*length_field = (u16) (*bytes_consumed - 3);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_address64_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_address64_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16;
+	u8                              temp8;
+	u8                              resource_type;
+	u8                              *temp_ptr;
+	acpi_size                       struct_size;
+	u32                             index;
+
+
+	ACPI_FUNCTION_TRACE ("rs_address64_resource");
+
+
+	buffer = byte_stream_buffer;
+	struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
+	resource_type = *buffer;
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	/* Validate minimum descriptor length */
+
+	if (temp16 < 43) {
+		return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+	}
+
+	*bytes_consumed = temp16 + 3;
+	output_struct->id = ACPI_RSTYPE_ADDRESS64;
+
+	/*
+	 * Get the Resource Type (Byte3)
+	 */
+	buffer += 2;
+	temp8 = *buffer;
+
+	/* Values 0-2 and 0xC0-0xFF are valid */
+
+	if ((temp8 > 2) && (temp8 < 0xC0)) {
+		return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+	}
+
+	output_struct->data.address64.resource_type = temp8;
+
+	/*
+	 * Get the General Flags (Byte4)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	/*
+	 * Producer / Consumer
+	 */
+	output_struct->data.address64.producer_consumer = temp8 & 0x01;
+
+	/*
+	 * Decode
+	 */
+	output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
+
+	/*
+	 * Min Address Fixed
+	 */
+	output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
+
+	/*
+	 * Max Address Fixed
+	 */
+	output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
+
+	/*
+	 * Get the Type Specific Flags (Byte5)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	if (ACPI_MEMORY_RANGE == output_struct->data.address64.resource_type) {
+		output_struct->data.address64.attribute.memory.read_write_attribute =
+				(u16) (temp8 & 0x01);
+
+		output_struct->data.address64.attribute.memory.cache_attribute =
+				(u16) ((temp8 >> 1) & 0x03);
+	}
+	else {
+		if (ACPI_IO_RANGE == output_struct->data.address64.resource_type) {
+			output_struct->data.address64.attribute.io.range_attribute =
+				(u16) (temp8 & 0x03);
+			output_struct->data.address64.attribute.io.translation_attribute =
+				(u16) ((temp8 >> 4) & 0x03);
+		}
+		else {
+			/* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */
+			/* Nothing needs to be filled in */
+		}
+	}
+
+	if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
+		/* Move past revision_id and Reserved byte */
+
+		buffer += 2;
+	}
+
+	/*
+	 * Get Granularity (Bytes 6-13) or (Bytes 8-15)
+	 */
+	buffer += 1;
+	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
+
+	/*
+	 * Get min_address_range (Bytes 14-21) or (Bytes 16-23)
+	 */
+	buffer += 8;
+	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
+
+	/*
+	 * Get max_address_range (Bytes 22-29) or (Bytes 24-31)
+	 */
+	buffer += 8;
+	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
+
+	/*
+	 * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39)
+	 */
+	buffer += 8;
+	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer);
+
+	/*
+	 * Get address_length (Bytes 38-45) or (Bytes 40-47)
+	 */
+	buffer += 8;
+	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
+
+	output_struct->data.address64.resource_source.index = 0x00;
+	output_struct->data.address64.resource_source.string_length = 0;
+	output_struct->data.address64.resource_source.string_ptr = NULL;
+
+	if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
+		/* Get type_specific_attribute (Bytes 48-55) */
+
+		buffer += 8;
+		ACPI_MOVE_64_TO_64 (&output_struct->data.address64.type_specific_attributes, buffer);
+	}
+	else {
+		output_struct->data.address64.type_specific_attributes = 0;
+
+		/*
+		 * Resource Source Index (if present)
+		 */
+		buffer += 8;
+
+		/*
+		 * This will leave us pointing to the Resource Source Index
+		 * If it is present, then save it off and calculate the
+		 * pointer to where the null terminated string goes:
+		 * Each Interrupt takes 32-bits + the 5 bytes of the
+		 * stream that are default.
+		 *
+		 * Note: Some resource descriptors will have an additional null, so
+		 * we add 1 to the length.
+		 */
+		if (*bytes_consumed > (46 + 1)) {
+			/* Dereference the Index */
+
+			temp8 = *buffer;
+			output_struct->data.address64.resource_source.index =
+					(u32) temp8;
+
+			/* Point to the String */
+
+			buffer += 1;
+
+			/* Point the String pointer to the end of this structure */
+
+			output_struct->data.address64.resource_source.string_ptr =
+					(char *)((u8 *)output_struct + struct_size);
+
+			temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
+
+			/* Copy the string into the buffer */
+
+			index = 0;
+			while (0x00 != *buffer) {
+				*temp_ptr = *buffer;
+
+				temp_ptr += 1;
+				buffer += 1;
+				index += 1;
+			}
+
+			/*
+			 * Add the terminating null
+			 */
+			*temp_ptr = 0x00;
+			output_struct->data.address64.resource_source.string_length = index + 1;
+
+			/*
+			 * In order for the struct_size to fall on a 32-bit boundary,
+			 * calculate the length of the string and expand the
+			 * struct_size to the next 32-bit boundary.
+			 */
+			temp8 = (u8) (index + 1);
+			struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
+		}
+	}
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_address64_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_address64_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer;
+	u16                             *length_field;
+	u8                              temp8;
+	char                            *temp_pointer;
+
+
+	ACPI_FUNCTION_TRACE ("rs_address64_stream");
+
+
+	buffer = *output_buffer;
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x8A;
+	buffer += 1;
+
+	/*
+	 * Set a pointer to the Length field - to be filled in later
+	 */
+	length_field = ACPI_CAST_PTR (u16, buffer);
+	buffer += 2;
+
+	/*
+	 * Set the Resource Type (Memory, Io, bus_number)
+	 */
+	temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the general flags
+	 */
+	temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
+	temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
+	temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
+	temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the type specific flags
+	 */
+	temp8 = 0;
+
+	if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address64.attribute.memory.read_write_attribute &
+			0x01);
+
+		temp8 |=
+			(linked_list->data.address64.attribute.memory.cache_attribute &
+			 0x03) << 1;
+	}
+	else if (ACPI_IO_RANGE == linked_list->data.address64.resource_type) {
+		temp8 = (u8)
+			(linked_list->data.address64.attribute.io.range_attribute &
+			 0x03);
+		temp8 |=
+			(linked_list->data.address64.attribute.io.range_attribute &
+			 0x03) << 4;
+	}
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the address space granularity
+	 */
+	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity);
+	buffer += 8;
+
+	/*
+	 * Set the address range minimum
+	 */
+	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range);
+	buffer += 8;
+
+	/*
+	 * Set the address range maximum
+	 */
+	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range);
+	buffer += 8;
+
+	/*
+	 * Set the address translation offset
+	 */
+	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_translation_offset);
+	buffer += 8;
+
+	/*
+	 * Set the address length
+	 */
+	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length);
+	buffer += 8;
+
+	/*
+	 * Resource Source Index and Resource Source are optional
+	 */
+	if (0 != linked_list->data.address64.resource_source.string_length) {
+		temp8 = (u8) linked_list->data.address64.resource_source.index;
+
+		*buffer = temp8;
+		buffer += 1;
+
+		temp_pointer = (char *) buffer;
+
+		/*
+		 * Copy the string
+		 */
+		ACPI_STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr);
+
+		/*
+		 * Buffer needs to be set to the length of the sting + one for the
+		 * terminating null
+		 */
+		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1);
+	}
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+
+	/*
+	 * Set the length field to the number of bytes consumed
+	 * minus the header size (3 bytes)
+	 */
+	*length_field = (u16) (*bytes_consumed - 3);
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
new file mode 100644
index 0000000..8a5f0a5
--- /dev/null
+++ b/drivers/acpi/resources/rscalc.c
@@ -0,0 +1,841 @@
+/*******************************************************************************
+ *
+ * Module Name: rscalc - Calculate stream and list lengths
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rscalc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_byte_stream_length
+ *
+ * PARAMETERS:  linked_list         - Pointer to the resource linked list
+ *              size_needed         - u32 pointer of the size buffer needed
+ *                                    to properly return the parsed data
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
+ *              the size buffer needed to hold the linked list that conveys
+ *              the resource data.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_get_byte_stream_length (
+	struct acpi_resource            *linked_list,
+	acpi_size                       *size_needed)
+{
+	acpi_size                       byte_stream_size_needed = 0;
+	acpi_size                       segment_size;
+	u8                              done = FALSE;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_byte_stream_length");
+
+
+	while (!done) {
+		/*
+		 * Init the variable that will hold the size to add to the total.
+		 */
+		segment_size = 0;
+
+		switch (linked_list->id) {
+		case ACPI_RSTYPE_IRQ:
+			/*
+			 * IRQ Resource
+			 * For an IRQ Resource, Byte 3, although optional, will always be
+			 * created - it holds IRQ information.
+			 */
+			segment_size = 4;
+			break;
+
+		case ACPI_RSTYPE_DMA:
+			/*
+			 * DMA Resource
+			 * For this resource the size is static
+			 */
+			segment_size = 3;
+			break;
+
+		case ACPI_RSTYPE_START_DPF:
+			/*
+			 * Start Dependent Functions Resource
+			 * For a start_dependent_functions Resource, Byte 1, although
+			 * optional, will always be created.
+			 */
+			segment_size = 2;
+			break;
+
+		case ACPI_RSTYPE_END_DPF:
+			/*
+			 * End Dependent Functions Resource
+			 * For this resource the size is static
+			 */
+			segment_size = 1;
+			break;
+
+		case ACPI_RSTYPE_IO:
+			/*
+			 * IO Port Resource
+			 * For this resource the size is static
+			 */
+			segment_size = 8;
+			break;
+
+		case ACPI_RSTYPE_FIXED_IO:
+			/*
+			 * Fixed IO Port Resource
+			 * For this resource the size is static
+			 */
+			segment_size = 4;
+			break;
+
+		case ACPI_RSTYPE_VENDOR:
+			/*
+			 * Vendor Defined Resource
+			 * For a Vendor Specific resource, if the Length is between 1 and 7
+			 * it will be created as a Small Resource data type, otherwise it
+			 * is a Large Resource data type.
+			 */
+			if (linked_list->data.vendor_specific.length > 7) {
+				segment_size = 3;
+			}
+			else {
+				segment_size = 1;
+			}
+			segment_size += linked_list->data.vendor_specific.length;
+			break;
+
+		case ACPI_RSTYPE_END_TAG:
+			/*
+			 * End Tag
+			 * For this resource the size is static
+			 */
+			segment_size = 2;
+			done = TRUE;
+			break;
+
+		case ACPI_RSTYPE_MEM24:
+			/*
+			 * 24-Bit Memory Resource
+			 * For this resource the size is static
+			 */
+			segment_size = 12;
+			break;
+
+		case ACPI_RSTYPE_MEM32:
+			/*
+			 * 32-Bit Memory Range Resource
+			 * For this resource the size is static
+			 */
+			segment_size = 20;
+			break;
+
+		case ACPI_RSTYPE_FIXED_MEM32:
+			/*
+			 * 32-Bit Fixed Memory Resource
+			 * For this resource the size is static
+			 */
+			segment_size = 12;
+			break;
+
+		case ACPI_RSTYPE_ADDRESS16:
+			/*
+			 * 16-Bit Address Resource
+			 * The base size of this byte stream is 16. If a Resource Source
+			 * string is not NULL, add 1 for the Index + the length of the null
+			 * terminated string Resource Source + 1 for the null.
+			 */
+			segment_size = 16;
+
+			if (linked_list->data.address16.resource_source.string_ptr) {
+				segment_size += linked_list->data.address16.resource_source.string_length;
+				segment_size++;
+			}
+			break;
+
+		case ACPI_RSTYPE_ADDRESS32:
+			/*
+			 * 32-Bit Address Resource
+			 * The base size of this byte stream is 26. If a Resource
+			 * Source string is not NULL, add 1 for the Index + the
+			 * length of the null terminated string Resource Source +
+			 * 1 for the null.
+			 */
+			segment_size = 26;
+
+			if (linked_list->data.address32.resource_source.string_ptr) {
+				segment_size += linked_list->data.address32.resource_source.string_length;
+				segment_size++;
+			}
+			break;
+
+		case ACPI_RSTYPE_ADDRESS64:
+			/*
+			 * 64-Bit Address Resource
+			 * The base size of this byte stream is 46. If a resource_source
+			 * string is not NULL, add 1 for the Index + the length of the null
+			 * terminated string Resource Source + 1 for the null.
+			 */
+			segment_size = 46;
+
+			if (linked_list->data.address64.resource_source.string_ptr) {
+				segment_size += linked_list->data.address64.resource_source.string_length;
+				segment_size++;
+			}
+			break;
+
+		case ACPI_RSTYPE_EXT_IRQ:
+			/*
+			 * Extended IRQ Resource
+			 * The base size of this byte stream is 9. This is for an Interrupt
+			 * table length of 1.  For each additional interrupt, add 4.
+			 * If a Resource Source string is not NULL, add 1 for the
+			 * Index + the length of the null terminated string
+			 * Resource Source + 1 for the null.
+			 */
+			segment_size = 9 +
+				(((acpi_size) linked_list->data.extended_irq.number_of_interrupts - 1) * 4);
+
+			if (linked_list->data.extended_irq.resource_source.string_ptr) {
+				segment_size += linked_list->data.extended_irq.resource_source.string_length;
+				segment_size++;
+			}
+			break;
+
+		default:
+			/*
+			 * If we get here, everything is out of sync, exit with error
+			 */
+			return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+
+		} /* switch (linked_list->Id) */
+
+		/*
+		 * Update the total
+		 */
+		byte_stream_size_needed += segment_size;
+
+		/*
+		 * Point to the next object
+		 */
+		linked_list = ACPI_PTR_ADD (struct acpi_resource,
+				  linked_list, linked_list->length);
+	}
+
+	/*
+	 * This is the data the caller needs
+	 */
+	*size_needed = byte_stream_size_needed;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_list_length
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
+ *              byte_stream_buffer_length - Size of byte_stream_buffer
+ *              size_needed             - u32 pointer of the size buffer
+ *                                        needed to properly return the
+ *                                        parsed data
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
+ *              the size buffer needed to hold the linked list that conveys
+ *              the resource data.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_get_list_length (
+	u8                              *byte_stream_buffer,
+	u32                             byte_stream_buffer_length,
+	acpi_size                       *size_needed)
+{
+	u32                             buffer_size = 0;
+	u32                             bytes_parsed = 0;
+	u8                              number_of_interrupts = 0;
+	u8                              number_of_channels = 0;
+	u8                              resource_type;
+	u32                             structure_size;
+	u32                             bytes_consumed;
+	u8                              *buffer;
+	u8                              temp8;
+	u16                             temp16;
+	u8                              index;
+	u8                              additional_bytes;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_list_length");
+
+
+	while (bytes_parsed < byte_stream_buffer_length) {
+		/*
+		 * The next byte in the stream is the resource type
+		 */
+		resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
+
+		switch (resource_type) {
+		case ACPI_RDESC_TYPE_MEMORY_24:
+			/*
+			 * 24-Bit Memory Resource
+			 */
+			bytes_consumed = 12;
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24);
+			break;
+
+
+		case ACPI_RDESC_TYPE_LARGE_VENDOR:
+			/*
+			 * Vendor Defined Resource
+			 */
+			buffer = byte_stream_buffer;
+			++buffer;
+
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+			bytes_consumed = temp16 + 3;
+
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp16 = (u16) ACPI_ROUND_UP_to_32_bITS (temp16);
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
+					   (temp16 * sizeof (u8));
+			break;
+
+
+		case ACPI_RDESC_TYPE_MEMORY_32:
+			/*
+			 * 32-Bit Memory Range Resource
+			 */
+			bytes_consumed = 20;
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32);
+			break;
+
+
+		case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
+			/*
+			 * 32-Bit Fixed Memory Resource
+			 */
+			bytes_consumed = 12;
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32);
+			break;
+
+
+		case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
+			/*
+			 * 64-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
+
+			++buffer;
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+			bytes_consumed = temp16 + 3;
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
+			break;
+
+
+		case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
+			/*
+			 * 64-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
+
+			++buffer;
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+			bytes_consumed = temp16 + 3;
+
+			/*
+			 * Resource Source Index and Resource Source are optional elements.
+			 * Check the length of the Bytestream.  If it is greater than 43,
+			 * that means that an Index exists and is followed by a null
+			 * terminated string.  Therefore, set the temp variable to the
+			 * length minus the minimum byte stream length plus the byte for
+			 * the Index to determine the size of the NULL terminated string.
+			 */
+			if (43 < temp16) {
+				temp8 = (u8) (temp16 - 44);
+			}
+			else {
+				temp8 = 0;
+			}
+
+			/*
+			 * Ensure a 64-bit boundary for the structure
+			 */
+			temp8 = (u8) ACPI_ROUND_UP_to_64_bITS (temp8);
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64) +
+					   (temp8 * sizeof (u8));
+			break;
+
+
+		case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
+			/*
+			 * 32-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
+
+			++buffer;
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+			bytes_consumed = temp16 + 3;
+
+			/*
+			 * Resource Source Index and Resource Source are optional elements.
+			 * Check the length of the Bytestream.  If it is greater than 23,
+			 * that means that an Index exists and is followed by a null
+			 * terminated string.  Therefore, set the temp variable to the
+			 * length minus the minimum byte stream length plus the byte for
+			 * the Index to determine the size of the NULL terminated string.
+			 */
+			if (23 < temp16) {
+				temp8 = (u8) (temp16 - 24);
+			}
+			else {
+				temp8 = 0;
+			}
+
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32) +
+					   (temp8 * sizeof (u8));
+			break;
+
+
+		case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
+			/*
+			 * 16-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
+
+			++buffer;
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+			bytes_consumed = temp16 + 3;
+
+			/*
+			 * Resource Source Index and Resource Source are optional elements.
+			 * Check the length of the Bytestream.  If it is greater than 13,
+			 * that means that an Index exists and is followed by a null
+			 * terminated string.  Therefore, set the temp variable to the
+			 * length minus the minimum byte stream length plus the byte for
+			 * the Index to determine the size of the NULL terminated string.
+			 */
+			if (13 < temp16) {
+				temp8 = (u8) (temp16 - 14);
+			}
+			else {
+				temp8 = 0;
+			}
+
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16) +
+					   (temp8 * sizeof (u8));
+			break;
+
+
+		case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
+			/*
+			 * Extended IRQ
+			 */
+			buffer = byte_stream_buffer;
+
+			++buffer;
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+			bytes_consumed = temp16 + 3;
+
+			/*
+			 * Point past the length field and the Interrupt vector flags to
+			 * save off the Interrupt table length to the Temp8 variable.
+			 */
+			buffer += 3;
+			temp8 = *buffer;
+
+			/*
+			 * To compensate for multiple interrupt numbers, add 4 bytes for
+			 * each additional interrupts greater than 1
+			 */
+			additional_bytes = (u8) ((temp8 - 1) * 4);
+
+			/*
+			 * Resource Source Index and Resource Source are optional elements.
+			 * Check the length of the Bytestream.  If it is greater than 9,
+			 * that means that an Index exists and is followed by a null
+			 * terminated string.  Therefore, set the temp variable to the
+			 * length minus the minimum byte stream length plus the byte for
+			 * the Index to determine the size of the NULL terminated string.
+			 */
+			if (9 + additional_bytes < temp16) {
+				temp8 = (u8) (temp16 - (9 + additional_bytes));
+			}
+			else {
+				temp8 = 0;
+			}
+
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq) +
+					   (additional_bytes * sizeof (u8)) +
+					   (temp8 * sizeof (u8));
+			break;
+
+
+		case ACPI_RDESC_TYPE_IRQ_FORMAT:
+			/*
+			 * IRQ Resource.
+			 * Determine if it there are two or three trailing bytes
+			 */
+			buffer = byte_stream_buffer;
+			temp8 = *buffer;
+
+			if(temp8 & 0x01) {
+				bytes_consumed = 4;
+			}
+			else {
+				bytes_consumed = 3;
+			}
+
+			/* Point past the descriptor */
+
+			++buffer;
+
+			/*
+			 * Look at the number of bits set
+			 */
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+			for (index = 0; index < 16; index++) {
+				if (temp16 & 0x1) {
+					++number_of_interrupts;
+				}
+
+				temp16 >>= 1;
+			}
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io) +
+					   (number_of_interrupts * sizeof (u32));
+			break;
+
+
+		case ACPI_RDESC_TYPE_DMA_FORMAT:
+			/*
+			 * DMA Resource
+			 */
+			buffer = byte_stream_buffer;
+			bytes_consumed = 3;
+
+			/* Point past the descriptor */
+
+			++buffer;
+
+			/*
+			 * Look at the number of bits set
+			 */
+			temp8 = *buffer;
+
+			for(index = 0; index < 8; index++) {
+				if(temp8 & 0x1) {
+					++number_of_channels;
+				}
+
+				temp8 >>= 1;
+			}
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma) +
+					   (number_of_channels * sizeof (u32));
+			break;
+
+
+		case ACPI_RDESC_TYPE_START_DEPENDENT:
+			/*
+			 * Start Dependent Functions Resource
+			 * Determine if it there are two or three trailing bytes
+			 */
+			buffer = byte_stream_buffer;
+			temp8 = *buffer;
+
+			if(temp8 & 0x01) {
+				bytes_consumed = 2;
+			}
+			else {
+				bytes_consumed = 1;
+			}
+
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf);
+			break;
+
+
+		case ACPI_RDESC_TYPE_END_DEPENDENT:
+			/*
+			 * End Dependent Functions Resource
+			 */
+			bytes_consumed = 1;
+			structure_size = ACPI_RESOURCE_LENGTH;
+			break;
+
+
+		case ACPI_RDESC_TYPE_IO_PORT:
+			/*
+			 * IO Port Resource
+			 */
+			bytes_consumed = 8;
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io);
+			break;
+
+
+		case ACPI_RDESC_TYPE_FIXED_IO_PORT:
+			/*
+			 * Fixed IO Port Resource
+			 */
+			bytes_consumed = 4;
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io);
+			break;
+
+
+		case ACPI_RDESC_TYPE_SMALL_VENDOR:
+			/*
+			 * Vendor Specific Resource
+			 */
+			buffer = byte_stream_buffer;
+
+			temp8 = *buffer;
+			temp8 = (u8) (temp8 & 0x7);
+			bytes_consumed = temp8 + 1;
+
+			/*
+			 * Ensure a 32-bit boundary for the structure
+			 */
+			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
+					   (temp8 * sizeof (u8));
+			break;
+
+
+		case ACPI_RDESC_TYPE_END_TAG:
+			/*
+			 * End Tag
+			 */
+			bytes_consumed = 2;
+			structure_size = ACPI_RESOURCE_LENGTH;
+			byte_stream_buffer_length = bytes_parsed;
+			break;
+
+
+		default:
+			/*
+			 * If we get here, everything is out of sync,
+			 * exit with an error
+			 */
+			return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+		}
+
+		/*
+		 * Update the return value and counter
+		 */
+		buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+		bytes_parsed += bytes_consumed;
+
+		/*
+		 * Set the byte stream to point to the next resource
+		 */
+		byte_stream_buffer += bytes_consumed;
+	}
+
+	/*
+	 * This is the data the caller needs
+	 */
+	*size_needed = buffer_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_pci_routing_table_length
+ *
+ * PARAMETERS:  package_object          - Pointer to the package object
+ *              buffer_size_needed      - u32 pointer of the size buffer
+ *                                        needed to properly return the
+ *                                        parsed data
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Given a package representing a PCI routing table, this
+ *              calculates the size of the corresponding linked list of
+ *              descriptions.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_get_pci_routing_table_length (
+	union acpi_operand_object       *package_object,
+	acpi_size                       *buffer_size_needed)
+{
+	u32                             number_of_elements;
+	acpi_size                       temp_size_needed = 0;
+	union acpi_operand_object       **top_object_list;
+	u32                             index;
+	union acpi_operand_object       *package_element;
+	union acpi_operand_object       **sub_object_list;
+	u8                              name_found;
+	u32                             table_index;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_pci_routing_table_length");
+
+
+	number_of_elements = package_object->package.count;
+
+	/*
+	 * Calculate the size of the return buffer.
+	 * The base size is the number of elements * the sizes of the
+	 * structures.  Additional space for the strings is added below.
+	 * The minus one is to subtract the size of the u8 Source[1]
+	 * member because it is added below.
+	 *
+	 * But each PRT_ENTRY structure has a pointer to a string and
+	 * the size of that string must be found.
+	 */
+	top_object_list = package_object->package.elements;
+
+	for (index = 0; index < number_of_elements; index++) {
+		/*
+		 * Dereference the sub-package
+		 */
+		package_element = *top_object_list;
+
+		/*
+		 * The sub_object_list will now point to an array of the
+		 * four IRQ elements: Address, Pin, Source and source_index
+		 */
+		sub_object_list = package_element->package.elements;
+
+		/*
+		 * Scan the irq_table_elements for the Source Name String
+		 */
+		name_found = FALSE;
+
+		for (table_index = 0; table_index < 4 && !name_found; table_index++) {
+			if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*sub_object_list)) ||
+				((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*sub_object_list)) &&
+					((*sub_object_list)->reference.opcode == AML_INT_NAMEPATH_OP))) {
+				name_found = TRUE;
+			}
+			else {
+				/*
+				 * Look at the next element
+				 */
+				sub_object_list++;
+			}
+		}
+
+		temp_size_needed += (sizeof (struct acpi_pci_routing_table) - 4);
+
+		/*
+		 * Was a String type found?
+		 */
+		if (name_found) {
+			if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) {
+				/*
+				 * The length String.Length field does not include the
+				 * terminating NULL, add 1
+				 */
+				temp_size_needed += ((acpi_size) (*sub_object_list)->string.length + 1);
+			}
+			else {
+				temp_size_needed += acpi_ns_get_pathname_length (
+						   (*sub_object_list)->reference.node);
+			}
+		}
+		else {
+			/*
+			 * If no name was found, then this is a NULL, which is
+			 * translated as a u32 zero.
+			 */
+			temp_size_needed += sizeof (u32);
+		}
+
+		/* Round up the size since each element must be aligned */
+
+		temp_size_needed = ACPI_ROUND_UP_to_64_bITS (temp_size_needed);
+
+		/*
+		 * Point to the next union acpi_operand_object
+		 */
+		top_object_list++;
+	}
+
+	/*
+	 * Adding an extra element to the end of the list, essentially a NULL terminator
+	 */
+	*buffer_size_needed = temp_size_needed + sizeof (struct acpi_pci_routing_table);
+	return_ACPI_STATUS (AE_OK);
+}
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
new file mode 100644
index 0000000..a3a0cbf
--- /dev/null
+++ b/drivers/acpi/resources/rscreate.c
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ *
+ * Module Name: rscreate - Create resource lists/tables
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rscreate")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_create_resource_list
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
+ *              output_buffer           - Pointer to the user's buffer
+ *
+ * RETURN:      Status  - AE_OK if okay, else a valid acpi_status code
+ *              If output_buffer is not large enough, output_buffer_length
+ *              indicates how large output_buffer should be, else it
+ *              indicates how may u8 elements of output_buffer are valid.
+ *
+ * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method
+ *              execution and parses the stream to create a linked list
+ *              of device resources.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_create_resource_list (
+	union acpi_operand_object       *byte_stream_buffer,
+	struct acpi_buffer              *output_buffer)
+{
+
+	acpi_status                     status;
+	u8                              *byte_stream_start;
+	acpi_size                       list_size_needed = 0;
+	u32                             byte_stream_buffer_length;
+
+
+	ACPI_FUNCTION_TRACE ("rs_create_resource_list");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_buffer = %p\n",
+		byte_stream_buffer));
+
+	/*
+	 * Params already validated, so we don't re-validate here
+	 */
+	byte_stream_buffer_length = byte_stream_buffer->buffer.length;
+	byte_stream_start = byte_stream_buffer->buffer.pointer;
+
+	/*
+	 * Pass the byte_stream_buffer into a module that can calculate
+	 * the buffer size needed for the linked list
+	 */
+	status = acpi_rs_get_list_length (byte_stream_start, byte_stream_buffer_length,
+			 &list_size_needed);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n",
+		status, (u32) list_size_needed));
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (output_buffer, list_size_needed);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Do the conversion */
+
+	status = acpi_rs_byte_stream_to_list (byte_stream_start, byte_stream_buffer_length,
+			  output_buffer->pointer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
+			output_buffer->pointer, (u32) output_buffer->length));
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_create_pci_routing_table
+ *
+ * PARAMETERS:  package_object          - Pointer to an union acpi_operand_object
+ *                                        package
+ *              output_buffer           - Pointer to the user's buffer
+ *
+ * RETURN:      Status  AE_OK if okay, else a valid acpi_status code.
+ *              If the output_buffer is too small, the error will be
+ *              AE_BUFFER_OVERFLOW and output_buffer->Length will point
+ *              to the size buffer needed.
+ *
+ * DESCRIPTION: Takes the union acpi_operand_object    package and creates a
+ *              linked list of PCI interrupt descriptions
+ *
+ * NOTE: It is the caller's responsibility to ensure that the start of the
+ * output buffer is aligned properly (if necessary).
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_create_pci_routing_table (
+	union acpi_operand_object       *package_object,
+	struct acpi_buffer              *output_buffer)
+{
+	u8                              *buffer;
+	union acpi_operand_object       **top_object_list;
+	union acpi_operand_object       **sub_object_list;
+	union acpi_operand_object       *obj_desc;
+	acpi_size                       buffer_size_needed = 0;
+	u32                             number_of_elements;
+	u32                             index;
+	struct acpi_pci_routing_table   *user_prt;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+	struct acpi_buffer              path_buffer;
+
+
+	ACPI_FUNCTION_TRACE ("rs_create_pci_routing_table");
+
+
+	/* Params already validated, so we don't re-validate here */
+
+	/*
+	 * Get the required buffer length
+	 */
+	status = acpi_rs_get_pci_routing_table_length (package_object,
+			 &buffer_size_needed);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "buffer_size_needed = %X\n",
+		(u32) buffer_size_needed));
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (output_buffer, buffer_size_needed);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Loop through the ACPI_INTERNAL_OBJECTS - Each object
+	 * should be a package that in turn contains an
+	 * acpi_integer Address, a u8 Pin, a Name and a u8 source_index.
+	 */
+	top_object_list  = package_object->package.elements;
+	number_of_elements = package_object->package.count;
+	buffer           = output_buffer->pointer;
+	user_prt         = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+
+	for (index = 0; index < number_of_elements; index++) {
+		/*
+		 * Point user_prt past this current structure
+		 *
+		 * NOTE: On the first iteration, user_prt->Length will
+		 * be zero because we cleared the return buffer earlier
+		 */
+		buffer += user_prt->length;
+		user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+
+		/*
+		 * Fill in the Length field with the information we have at this point.
+		 * The minus four is to subtract the size of the u8 Source[4] member
+		 * because it is added below.
+		 */
+		user_prt->length = (sizeof (struct acpi_pci_routing_table) - 4);
+
+		/*
+		 * Each element of the top-level package must also be a package
+		 */
+		if (ACPI_GET_OBJECT_TYPE (*top_object_list) != ACPI_TYPE_PACKAGE) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"(PRT[%X]) Need sub-package, found %s\n",
+				index, acpi_ut_get_object_type_name (*top_object_list)));
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
+		/* Each sub-package must be of length 4 */
+
+		if ((*top_object_list)->package.count != 4) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"(PRT[%X]) Need package of length 4, found length %d\n",
+				index, (*top_object_list)->package.count));
+			return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT);
+		}
+
+		/*
+		 * Dereference the sub-package.
+		 * The sub_object_list will now point to an array of the four IRQ
+		 * elements: [Address, Pin, Source, source_index]
+		 */
+		sub_object_list = (*top_object_list)->package.elements;
+
+		/*
+		 * 1) First subobject: Dereference the PRT.Address
+		 */
+		obj_desc = sub_object_list[0];
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+			user_prt->address = obj_desc->integer.value;
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"(PRT[%X].Address) Need Integer, found %s\n",
+				index, acpi_ut_get_object_type_name (obj_desc)));
+			return_ACPI_STATUS (AE_BAD_DATA);
+		}
+
+		/*
+		 * 2) Second subobject: Dereference the PRT.Pin
+		 */
+		obj_desc = sub_object_list[1];
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+			user_prt->pin = (u32) obj_desc->integer.value;
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"(PRT[%X].Pin) Need Integer, found %s\n",
+				index, acpi_ut_get_object_type_name (obj_desc)));
+			return_ACPI_STATUS (AE_BAD_DATA);
+		}
+
+		/*
+		 * 3) Third subobject: Dereference the PRT.source_name
+		 */
+		obj_desc = sub_object_list[2];
+		switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+		case ACPI_TYPE_LOCAL_REFERENCE:
+
+			if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"(PRT[%X].Source) Need name, found reference op %X\n",
+					index, obj_desc->reference.opcode));
+				return_ACPI_STATUS (AE_BAD_DATA);
+			}
+
+			node = obj_desc->reference.node;
+
+			/* Use *remaining* length of the buffer as max for pathname */
+
+			path_buffer.length = output_buffer->length -
+					   (u32) ((u8 *) user_prt->source -
+					   (u8 *) output_buffer->pointer);
+			path_buffer.pointer = user_prt->source;
+
+			status = acpi_ns_handle_to_pathname ((acpi_handle) node, &path_buffer);
+
+			user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1; /* include null terminator */
+			break;
+
+
+		case ACPI_TYPE_STRING:
+
+			ACPI_STRCPY (user_prt->source, obj_desc->string.pointer);
+
+			/* Add to the Length field the length of the string (add 1 for terminator) */
+
+			user_prt->length += obj_desc->string.length + 1;
+			break;
+
+
+		case ACPI_TYPE_INTEGER:
+			/*
+			 * If this is a number, then the Source Name is NULL, since the
+			 * entire buffer was zeroed out, we can leave this alone.
+			 *
+			 * Add to the Length field the length of the u32 NULL
+			 */
+			user_prt->length += sizeof (u32);
+			break;
+
+
+		default:
+
+		   ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			   "(PRT[%X].Source) Need Ref/String/Integer, found %s\n",
+				index, acpi_ut_get_object_type_name (obj_desc)));
+		   return_ACPI_STATUS (AE_BAD_DATA);
+		}
+
+		/* Now align the current length */
+
+		user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length);
+
+		/*
+		 * 4) Fourth subobject: Dereference the PRT.source_index
+		 */
+		obj_desc = sub_object_list[3];
+		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+			user_prt->source_index = (u32) obj_desc->integer.value;
+		}
+		else {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"(PRT[%X].source_index) Need Integer, found %s\n",
+				index, acpi_ut_get_object_type_name (obj_desc)));
+			return_ACPI_STATUS (AE_BAD_DATA);
+		}
+
+		/* Point to the next union acpi_operand_object in the top level package */
+
+		top_object_list++;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
+			output_buffer->pointer, (u32) output_buffer->length));
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_create_byte_stream
+ *
+ * PARAMETERS:  linked_list_buffer      - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's buffer
+ *
+ * RETURN:      Status  AE_OK if okay, else a valid acpi_status code.
+ *              If the output_buffer is too small, the error will be
+ *              AE_BUFFER_OVERFLOW and output_buffer->Length will point
+ *              to the size buffer needed.
+ *
+ * DESCRIPTION: Takes the linked list of device resources and
+ *              creates a bytestream to be used as input for the
+ *              _SRS control method.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_create_byte_stream (
+	struct acpi_resource            *linked_list_buffer,
+	struct acpi_buffer              *output_buffer)
+{
+	acpi_status                     status;
+	acpi_size                       byte_stream_size_needed = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_create_byte_stream");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "linked_list_buffer = %p\n",
+		linked_list_buffer));
+
+	/*
+	 * Params already validated, so we don't re-validate here
+	 *
+	 * Pass the linked_list_buffer into a module that calculates
+	 * the buffer size needed for the byte stream.
+	 */
+	status = acpi_rs_get_byte_stream_length (linked_list_buffer,
+			 &byte_stream_size_needed);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n",
+		(u32) byte_stream_size_needed, acpi_format_exception (status)));
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (output_buffer, byte_stream_size_needed);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Do the conversion */
+
+	status = acpi_rs_list_to_byte_stream (linked_list_buffer, byte_stream_size_needed,
+			  output_buffer->pointer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n",
+			output_buffer->pointer, (u32) output_buffer->length));
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
new file mode 100644
index 0000000..eef1b1f
--- /dev/null
+++ b/drivers/acpi/resources/rsdump.c
@@ -0,0 +1,1150 @@
+/*******************************************************************************
+ *
+ * Module Name: rsdump - Functions to display the resource structures.
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsdump")
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_irq
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_irq (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_irq        *irq_data = (struct acpi_resource_irq *) data;
+	u8                              index = 0;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("IRQ Resource\n");
+
+	acpi_os_printf ("  %s Triggered\n",
+			 ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge");
+
+	acpi_os_printf ("  Active %s\n",
+			 ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High");
+
+	acpi_os_printf ("  %s\n",
+			 ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive");
+
+	acpi_os_printf ("  %X Interrupts ( ", irq_data->number_of_interrupts);
+
+	for (index = 0; index < irq_data->number_of_interrupts; index++) {
+		acpi_os_printf ("%X ", irq_data->interrupts[index]);
+	}
+
+	acpi_os_printf (")\n");
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_dma
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_dma (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_dma        *dma_data = (struct acpi_resource_dma *) data;
+	u8                              index = 0;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("DMA Resource\n");
+
+	switch (dma_data->type) {
+	case ACPI_COMPATIBILITY:
+		acpi_os_printf ("  Compatibility mode\n");
+		break;
+
+	case ACPI_TYPE_A:
+		acpi_os_printf ("  Type A\n");
+		break;
+
+	case ACPI_TYPE_B:
+		acpi_os_printf ("  Type B\n");
+		break;
+
+	case ACPI_TYPE_F:
+		acpi_os_printf ("  Type F\n");
+		break;
+
+	default:
+		acpi_os_printf ("  Invalid DMA type\n");
+		break;
+	}
+
+	acpi_os_printf ("  %sBus Master\n",
+			 ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
+
+
+	switch (dma_data->transfer) {
+	case ACPI_TRANSFER_8:
+		acpi_os_printf ("  8-bit only transfer\n");
+		break;
+
+	case ACPI_TRANSFER_8_16:
+		acpi_os_printf ("  8 and 16-bit transfer\n");
+		break;
+
+	case ACPI_TRANSFER_16:
+		acpi_os_printf ("  16 bit only transfer\n");
+		break;
+
+	default:
+		acpi_os_printf ("  Invalid transfer preference\n");
+		break;
+	}
+
+	acpi_os_printf ("  Number of Channels: %X ( ", dma_data->number_of_channels);
+
+	for (index = 0; index < dma_data->number_of_channels; index++) {
+		acpi_os_printf ("%X ", dma_data->channels[index]);
+	}
+
+	acpi_os_printf (")\n");
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_start_depend_fns
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_start_depend_fns (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_start_dpf *sdf_data = (struct acpi_resource_start_dpf *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("Start Dependent Functions Resource\n");
+
+	switch (sdf_data->compatibility_priority) {
+	case ACPI_GOOD_CONFIGURATION:
+		acpi_os_printf ("  Good configuration\n");
+		break;
+
+	case ACPI_ACCEPTABLE_CONFIGURATION:
+		acpi_os_printf ("  Acceptable configuration\n");
+		break;
+
+	case ACPI_SUB_OPTIMAL_CONFIGURATION:
+		acpi_os_printf ("  Sub-optimal configuration\n");
+		break;
+
+	default:
+		acpi_os_printf ("  Invalid compatibility priority\n");
+		break;
+	}
+
+	switch(sdf_data->performance_robustness) {
+	case ACPI_GOOD_CONFIGURATION:
+		acpi_os_printf ("  Good configuration\n");
+		break;
+
+	case ACPI_ACCEPTABLE_CONFIGURATION:
+		acpi_os_printf ("  Acceptable configuration\n");
+		break;
+
+	case ACPI_SUB_OPTIMAL_CONFIGURATION:
+		acpi_os_printf ("  Sub-optimal configuration\n");
+		break;
+
+	default:
+		acpi_os_printf ("  Invalid performance "
+				  "robustness preference\n");
+		break;
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_io
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_io (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_io         *io_data = (struct acpi_resource_io *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("Io Resource\n");
+
+	acpi_os_printf ("  %d bit decode\n",
+			 ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
+
+	acpi_os_printf ("  Range minimum base: %08X\n",
+			 io_data->min_base_address);
+
+	acpi_os_printf ("  Range maximum base: %08X\n",
+			 io_data->max_base_address);
+
+	acpi_os_printf ("  Alignment: %08X\n",
+			 io_data->alignment);
+
+	acpi_os_printf ("  Range Length: %08X\n",
+			 io_data->range_length);
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_fixed_io
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_fixed_io (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_fixed_io   *fixed_io_data = (struct acpi_resource_fixed_io *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("Fixed Io Resource\n");
+	acpi_os_printf ("  Range base address: %08X",
+			 fixed_io_data->base_address);
+
+	acpi_os_printf ("  Range length: %08X",
+			 fixed_io_data->range_length);
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_vendor_specific
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_vendor_specific (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_vendor     *vendor_data = (struct acpi_resource_vendor *) data;
+	u16                             index = 0;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("Vendor Specific Resource\n");
+
+	acpi_os_printf ("  Length: %08X\n", vendor_data->length);
+
+	for (index = 0; index < vendor_data->length; index++) {
+		acpi_os_printf ("  Byte %X: %08X\n",
+				 index, vendor_data->reserved[index]);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_memory24
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_memory24 (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_mem24      *memory24_data = (struct acpi_resource_mem24 *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("24-Bit Memory Range Resource\n");
+
+	acpi_os_printf ("  Read%s\n",
+			 ACPI_READ_WRITE_MEMORY ==
+			 memory24_data->read_write_attribute ?
+			 "/Write" : " only");
+
+	acpi_os_printf ("  Range minimum base: %08X\n",
+			 memory24_data->min_base_address);
+
+	acpi_os_printf ("  Range maximum base: %08X\n",
+			 memory24_data->max_base_address);
+
+	acpi_os_printf ("  Alignment: %08X\n",
+			 memory24_data->alignment);
+
+	acpi_os_printf ("  Range length: %08X\n",
+			 memory24_data->range_length);
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_memory32
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_memory32 (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_mem32      *memory32_data = (struct acpi_resource_mem32 *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("32-Bit Memory Range Resource\n");
+
+	acpi_os_printf ("  Read%s\n",
+			 ACPI_READ_WRITE_MEMORY ==
+			 memory32_data->read_write_attribute ?
+			 "/Write" : " only");
+
+	acpi_os_printf ("  Range minimum base: %08X\n",
+			 memory32_data->min_base_address);
+
+	acpi_os_printf ("  Range maximum base: %08X\n",
+			 memory32_data->max_base_address);
+
+	acpi_os_printf ("  Alignment: %08X\n",
+			 memory32_data->alignment);
+
+	acpi_os_printf ("  Range length: %08X\n",
+			 memory32_data->range_length);
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_fixed_memory32
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_fixed_memory32 (
+	union acpi_resource_data            *data)
+{
+	struct acpi_resource_fixed_mem32    *fixed_memory32_data = (struct acpi_resource_fixed_mem32 *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("32-Bit Fixed Location Memory Range Resource\n");
+
+	acpi_os_printf ("  Read%s\n",
+			 ACPI_READ_WRITE_MEMORY ==
+			 fixed_memory32_data->read_write_attribute ?
+			 "/Write" : " Only");
+
+	acpi_os_printf ("  Range base address: %08X\n",
+			 fixed_memory32_data->range_base_address);
+
+	acpi_os_printf ("  Range length: %08X\n",
+			 fixed_memory32_data->range_length);
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_address16
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_address16 (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_address16 *address16_data = (struct acpi_resource_address16 *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("16-Bit Address Space Resource\n");
+	acpi_os_printf ("  Resource Type: ");
+
+	switch (address16_data->resource_type) {
+	case ACPI_MEMORY_RANGE:
+
+		acpi_os_printf ("Memory Range\n");
+
+		switch (address16_data->attribute.memory.cache_attribute) {
+		case ACPI_NON_CACHEABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Noncacheable memory\n");
+			break;
+
+		case ACPI_CACHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Cacheable memory\n");
+			break;
+
+		case ACPI_WRITE_COMBINING_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Write-combining memory\n");
+			break;
+
+		case ACPI_PREFETCHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Prefetchable memory\n");
+			break;
+
+		default:
+			acpi_os_printf ("  Type Specific: "
+					  "Invalid cache attribute\n");
+			break;
+		}
+
+		acpi_os_printf ("  Type Specific: Read%s\n",
+			ACPI_READ_WRITE_MEMORY ==
+			address16_data->attribute.memory.read_write_attribute ?
+			"/Write" : " Only");
+		break;
+
+	case ACPI_IO_RANGE:
+
+		acpi_os_printf ("I/O Range\n");
+
+		switch (address16_data->attribute.io.range_attribute) {
+		case ACPI_NON_ISA_ONLY_RANGES:
+			acpi_os_printf ("  Type Specific: "
+					  "Non-ISA Io Addresses\n");
+			break;
+
+		case ACPI_ISA_ONLY_RANGES:
+			acpi_os_printf ("  Type Specific: "
+					  "ISA Io Addresses\n");
+			break;
+
+		case ACPI_ENTIRE_RANGE:
+			acpi_os_printf ("  Type Specific: "
+					  "ISA and non-ISA Io Addresses\n");
+			break;
+
+		default:
+			acpi_os_printf ("  Type Specific: "
+					  "Invalid range attribute\n");
+			break;
+		}
+
+		acpi_os_printf ("  Type Specific: %s Translation\n",
+			ACPI_SPARSE_TRANSLATION ==
+			address16_data->attribute.io.translation_attribute ?
+			"Sparse" : "Dense");
+		break;
+
+	case ACPI_BUS_NUMBER_RANGE:
+
+		acpi_os_printf ("Bus Number Range\n");
+		break;
+
+	default:
+
+		acpi_os_printf ("0x%2.2X\n", address16_data->resource_type);
+		break;
+	}
+
+	acpi_os_printf ("  Resource %s\n",
+			ACPI_CONSUMER == address16_data->producer_consumer ?
+			"Consumer" : "Producer");
+
+	acpi_os_printf ("  %s decode\n",
+			 ACPI_SUB_DECODE == address16_data->decode ?
+			 "Subtractive" : "Positive");
+
+	acpi_os_printf ("  Min address is %s fixed\n",
+			 ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
+			 "" : "not");
+
+	acpi_os_printf ("  Max address is %s fixed\n",
+			 ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
+			 "" : "not");
+
+	acpi_os_printf ("  Granularity: %08X\n",
+			 address16_data->granularity);
+
+	acpi_os_printf ("  Address range min: %08X\n",
+			 address16_data->min_address_range);
+
+	acpi_os_printf ("  Address range max: %08X\n",
+			 address16_data->max_address_range);
+
+	acpi_os_printf ("  Address translation offset: %08X\n",
+			 address16_data->address_translation_offset);
+
+	acpi_os_printf ("  Address Length: %08X\n",
+			 address16_data->address_length);
+
+	if (0xFF != address16_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X\n",
+				 address16_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s\n",
+				 address16_data->resource_source.string_ptr);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_address32
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_address32 (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_address32 *address32_data = (struct acpi_resource_address32 *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("32-Bit Address Space Resource\n");
+
+	switch (address32_data->resource_type) {
+	case ACPI_MEMORY_RANGE:
+
+		acpi_os_printf ("  Resource Type: Memory Range\n");
+
+		switch (address32_data->attribute.memory.cache_attribute) {
+		case ACPI_NON_CACHEABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Noncacheable memory\n");
+			break;
+
+		case ACPI_CACHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Cacheable memory\n");
+			break;
+
+		case ACPI_WRITE_COMBINING_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Write-combining memory\n");
+			break;
+
+		case ACPI_PREFETCHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Prefetchable memory\n");
+			break;
+
+		default:
+			acpi_os_printf ("  Type Specific: "
+					  "Invalid cache attribute\n");
+			break;
+		}
+
+		acpi_os_printf ("  Type Specific: Read%s\n",
+			ACPI_READ_WRITE_MEMORY ==
+			address32_data->attribute.memory.read_write_attribute ?
+			"/Write" : " Only");
+		break;
+
+	case ACPI_IO_RANGE:
+
+		acpi_os_printf ("  Resource Type: Io Range\n");
+
+		switch (address32_data->attribute.io.range_attribute) {
+		case ACPI_NON_ISA_ONLY_RANGES:
+			acpi_os_printf ("  Type Specific: "
+					  "Non-ISA Io Addresses\n");
+			break;
+
+		case ACPI_ISA_ONLY_RANGES:
+			acpi_os_printf ("  Type Specific: "
+					  "ISA Io Addresses\n");
+			break;
+
+		case ACPI_ENTIRE_RANGE:
+			acpi_os_printf ("  Type Specific: "
+					  "ISA and non-ISA Io Addresses\n");
+			break;
+
+		default:
+			acpi_os_printf ("  Type Specific: "
+					  "Invalid Range attribute");
+			break;
+		}
+
+		acpi_os_printf ("  Type Specific: %s Translation\n",
+			ACPI_SPARSE_TRANSLATION ==
+			address32_data->attribute.io.translation_attribute ?
+			"Sparse" : "Dense");
+		break;
+
+	case ACPI_BUS_NUMBER_RANGE:
+
+		acpi_os_printf ("  Resource Type: Bus Number Range\n");
+		break;
+
+	default:
+
+		acpi_os_printf ("  Resource Type: 0x%2.2X\n", address32_data->resource_type);
+		break;
+	}
+
+	acpi_os_printf ("  Resource %s\n",
+			 ACPI_CONSUMER == address32_data->producer_consumer ?
+			 "Consumer" : "Producer");
+
+	acpi_os_printf ("  %s decode\n",
+			 ACPI_SUB_DECODE == address32_data->decode ?
+			 "Subtractive" : "Positive");
+
+	acpi_os_printf ("  Min address is %s fixed\n",
+			 ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
+			 "" : "not ");
+
+	acpi_os_printf ("  Max address is %s fixed\n",
+			 ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
+			 "" : "not ");
+
+	acpi_os_printf ("  Granularity: %08X\n",
+			 address32_data->granularity);
+
+	acpi_os_printf ("  Address range min: %08X\n",
+			 address32_data->min_address_range);
+
+	acpi_os_printf ("  Address range max: %08X\n",
+			 address32_data->max_address_range);
+
+	acpi_os_printf ("  Address translation offset: %08X\n",
+			 address32_data->address_translation_offset);
+
+	acpi_os_printf ("  Address Length: %08X\n",
+			 address32_data->address_length);
+
+	if(0xFF != address32_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X\n",
+				 address32_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s\n",
+				 address32_data->resource_source.string_ptr);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_address64
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_address64 (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_address64 *address64_data = (struct acpi_resource_address64 *) data;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("64-Bit Address Space Resource\n");
+
+	switch (address64_data->resource_type) {
+	case ACPI_MEMORY_RANGE:
+
+		acpi_os_printf ("  Resource Type: Memory Range\n");
+
+		switch (address64_data->attribute.memory.cache_attribute) {
+		case ACPI_NON_CACHEABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Noncacheable memory\n");
+			break;
+
+		case ACPI_CACHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Cacheable memory\n");
+			break;
+
+		case ACPI_WRITE_COMBINING_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Write-combining memory\n");
+			break;
+
+		case ACPI_PREFETCHABLE_MEMORY:
+			acpi_os_printf ("  Type Specific: "
+					  "Prefetchable memory\n");
+			break;
+
+		default:
+			acpi_os_printf ("  Type Specific: "
+					  "Invalid cache attribute\n");
+			break;
+		}
+
+		acpi_os_printf ("  Type Specific: Read%s\n",
+			ACPI_READ_WRITE_MEMORY ==
+			address64_data->attribute.memory.read_write_attribute ?
+			"/Write" : " Only");
+		break;
+
+	case ACPI_IO_RANGE:
+
+		acpi_os_printf ("  Resource Type: Io Range\n");
+
+		switch (address64_data->attribute.io.range_attribute) {
+		case ACPI_NON_ISA_ONLY_RANGES:
+			acpi_os_printf ("  Type Specific: "
+					  "Non-ISA Io Addresses\n");
+			break;
+
+		case ACPI_ISA_ONLY_RANGES:
+			acpi_os_printf ("  Type Specific: "
+					  "ISA Io Addresses\n");
+			break;
+
+		case ACPI_ENTIRE_RANGE:
+			acpi_os_printf ("  Type Specific: "
+					  "ISA and non-ISA Io Addresses\n");
+			break;
+
+		default:
+			acpi_os_printf ("  Type Specific: "
+					  "Invalid Range attribute");
+			break;
+		}
+
+		acpi_os_printf ("  Type Specific: %s Translation\n",
+			ACPI_SPARSE_TRANSLATION ==
+			address64_data->attribute.io.translation_attribute ?
+			"Sparse" : "Dense");
+		break;
+
+	case ACPI_BUS_NUMBER_RANGE:
+
+		acpi_os_printf ("  Resource Type: Bus Number Range\n");
+		break;
+
+	default:
+
+		acpi_os_printf ("  Resource Type: 0x%2.2X\n", address64_data->resource_type);
+		break;
+	}
+
+	acpi_os_printf ("  Resource %s\n",
+			 ACPI_CONSUMER == address64_data->producer_consumer ?
+			 "Consumer" : "Producer");
+
+	acpi_os_printf ("  %s decode\n",
+			 ACPI_SUB_DECODE == address64_data->decode ?
+			 "Subtractive" : "Positive");
+
+	acpi_os_printf ("  Min address is %s fixed\n",
+			 ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
+			 "" : "not ");
+
+	acpi_os_printf ("  Max address is %s fixed\n",
+			 ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
+			 "" : "not ");
+
+	acpi_os_printf ("  Granularity: %8.8X%8.8X\n",
+			 ACPI_FORMAT_UINT64 (address64_data->granularity));
+
+	acpi_os_printf ("  Address range min: %8.8X%8.8X\n",
+			 ACPI_FORMAT_UINT64 (address64_data->min_address_range));
+
+	acpi_os_printf ("  Address range max: %8.8X%8.8X\n",
+			 ACPI_FORMAT_UINT64 (address64_data->max_address_range));
+
+	acpi_os_printf ("  Address translation offset: %8.8X%8.8X\n",
+			 ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
+
+	acpi_os_printf ("  Address Length: %8.8X%8.8X\n",
+			 ACPI_FORMAT_UINT64 (address64_data->address_length));
+
+	acpi_os_printf ("  Type Specific Attributes: %8.8X%8.8X\n",
+			 ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
+
+	if (0xFF != address64_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X\n",
+				 address64_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s\n",
+				 address64_data->resource_source.string_ptr);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_extended_irq
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Prints out the various members of the Data structure type.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_extended_irq (
+	union acpi_resource_data        *data)
+{
+	struct acpi_resource_ext_irq    *ext_irq_data = (struct acpi_resource_ext_irq *) data;
+	u8                              index = 0;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	acpi_os_printf ("Extended IRQ Resource\n");
+
+	acpi_os_printf ("  Resource %s\n",
+			 ACPI_CONSUMER == ext_irq_data->producer_consumer ?
+			 "Consumer" : "Producer");
+
+	acpi_os_printf ("  %s\n",
+			 ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
+			 "Level" : "Edge");
+
+	acpi_os_printf ("  Active %s\n",
+			 ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
+			 "low" : "high");
+
+	acpi_os_printf ("  %s\n",
+			 ACPI_SHARED == ext_irq_data->shared_exclusive ?
+			 "Shared" : "Exclusive");
+
+	acpi_os_printf ("  Interrupts : %X ( ",
+			 ext_irq_data->number_of_interrupts);
+
+	for (index = 0; index < ext_irq_data->number_of_interrupts; index++) {
+		acpi_os_printf ("%X ", ext_irq_data->interrupts[index]);
+	}
+
+	acpi_os_printf (")\n");
+
+	if(0xFF != ext_irq_data->resource_source.index) {
+		acpi_os_printf ("  Resource Source Index: %X",
+				 ext_irq_data->resource_source.index);
+		acpi_os_printf ("  Resource Source: %s",
+				 ext_irq_data->resource_source.string_ptr);
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_resource_list
+ *
+ * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dispatches the structure to the correct dump routine.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_resource_list (
+	struct acpi_resource        *resource)
+{
+	u8                          count = 0;
+	u8                          done = FALSE;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) {
+		while (!done) {
+			acpi_os_printf ("Resource structure %X.\n", count++);
+
+			switch (resource->id) {
+			case ACPI_RSTYPE_IRQ:
+				acpi_rs_dump_irq (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_DMA:
+				acpi_rs_dump_dma (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_START_DPF:
+				acpi_rs_dump_start_depend_fns (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_END_DPF:
+				acpi_os_printf ("end_dependent_functions Resource\n");
+				/* acpi_rs_dump_end_dependent_functions (Resource->Data);*/
+				break;
+
+			case ACPI_RSTYPE_IO:
+				acpi_rs_dump_io (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_FIXED_IO:
+				acpi_rs_dump_fixed_io (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_VENDOR:
+				acpi_rs_dump_vendor_specific (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_END_TAG:
+				/*rs_dump_end_tag (Resource->Data);*/
+				acpi_os_printf ("end_tag Resource\n");
+				done = TRUE;
+				break;
+
+			case ACPI_RSTYPE_MEM24:
+				acpi_rs_dump_memory24 (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_MEM32:
+				acpi_rs_dump_memory32 (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_FIXED_MEM32:
+				acpi_rs_dump_fixed_memory32 (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_ADDRESS16:
+				acpi_rs_dump_address16 (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_ADDRESS32:
+				acpi_rs_dump_address32 (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_ADDRESS64:
+				acpi_rs_dump_address64 (&resource->data);
+				break;
+
+			case ACPI_RSTYPE_EXT_IRQ:
+				acpi_rs_dump_extended_irq (&resource->data);
+				break;
+
+			default:
+				acpi_os_printf ("Invalid resource type\n");
+				break;
+
+			}
+
+			resource = ACPI_PTR_ADD (struct acpi_resource, resource, resource->length);
+		}
+	}
+
+	return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dump_irq_list
+ *
+ * PARAMETERS:  Data            - pointer to the routing table to dump.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dispatches the structures to the correct dump routine.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_dump_irq_list (
+	u8                              *route_table)
+{
+	u8                              *buffer = route_table;
+	u8                              count = 0;
+	u8                              done = FALSE;
+	struct acpi_pci_routing_table   *prt_element;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) {
+		prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+
+		while (!done) {
+			acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);
+
+			acpi_os_printf ("  Address: %8.8X%8.8X\n",
+					 ACPI_FORMAT_UINT64 (prt_element->address));
+
+			acpi_os_printf ("  Pin: %X\n", prt_element->pin);
+
+			acpi_os_printf ("  Source: %s\n", prt_element->source);
+
+			acpi_os_printf ("  source_index: %X\n",
+					 prt_element->source_index);
+
+			buffer += prt_element->length;
+
+			prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
+
+			if(0 == prt_element->length) {
+				done = TRUE;
+			}
+		}
+	}
+
+	return;
+}
+
+#endif
+
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
new file mode 100644
index 0000000..972c746
--- /dev/null
+++ b/drivers/acpi/resources/rsio.c
@@ -0,0 +1,545 @@
+/*******************************************************************************
+ *
+ * Module Name: rsio - IO and DMA resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsio")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_io_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_io_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io);
+
+
+	ACPI_FUNCTION_TRACE ("rs_io_resource");
+
+
+	/*
+	 * The number of bytes consumed are Constant
+	 */
+	*bytes_consumed = 8;
+
+	output_struct->id = ACPI_RSTYPE_IO;
+
+	/*
+	 * Check Decode
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	output_struct->data.io.io_decode = temp8 & 0x01;
+
+	/*
+	 * Check min_base Address
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	output_struct->data.io.min_base_address = temp16;
+
+	/*
+	 * Check max_base Address
+	 */
+	buffer += 2;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	output_struct->data.io.max_base_address = temp16;
+
+	/*
+	 * Check Base alignment
+	 */
+	buffer += 2;
+	temp8 = *buffer;
+
+	output_struct->data.io.alignment = temp8;
+
+	/*
+	 * Check range_length
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	output_struct->data.io.range_length = temp8;
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_fixed_io_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_fixed_io_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io);
+
+
+	ACPI_FUNCTION_TRACE ("rs_fixed_io_resource");
+
+
+	/*
+	 * The number of bytes consumed are Constant
+	 */
+	*bytes_consumed = 4;
+
+	output_struct->id = ACPI_RSTYPE_FIXED_IO;
+
+	/*
+	 * Check Range Base Address
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	output_struct->data.fixed_io.base_address = temp16;
+
+	/*
+	 * Check range_length
+	 */
+	buffer += 2;
+	temp8 = *buffer;
+
+	output_struct->data.fixed_io.range_length = temp8;
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_io_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_io_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_io_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x47;
+	buffer += 1;
+
+	/*
+	 * Io Information Byte
+	 */
+	temp8 = (u8) (linked_list->data.io.io_decode & 0x01);
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the Range minimum base address
+	 */
+	temp16 = (u16) linked_list->data.io.min_base_address;
+
+	ACPI_MOVE_16_TO_16 (buffer, &temp16);
+	buffer += 2;
+
+	/*
+	 * Set the Range maximum base address
+	 */
+	temp16 = (u16) linked_list->data.io.max_base_address;
+
+	ACPI_MOVE_16_TO_16 (buffer, &temp16);
+	buffer += 2;
+
+	/*
+	 * Set the base alignment
+	 */
+	temp8 = (u8) linked_list->data.io.alignment;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the range length
+	 */
+	temp8 = (u8) linked_list->data.io.range_length;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_fixed_io_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_fixed_io_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_fixed_io_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x4B;
+
+	buffer += 1;
+
+	/*
+	 * Set the Range base address
+	 */
+	temp16 = (u16) linked_list->data.fixed_io.base_address;
+
+	ACPI_MOVE_16_TO_16 (buffer, &temp16);
+	buffer += 2;
+
+	/*
+	 * Set the range length
+	 */
+	temp8 = (u8) linked_list->data.fixed_io.range_length;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dma_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_dma_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u8                              temp8 = 0;
+	u8                              index;
+	u8                              i;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma);
+
+
+	ACPI_FUNCTION_TRACE ("rs_dma_resource");
+
+
+	/*
+	 * The number of bytes consumed are Constant
+	 */
+	*bytes_consumed = 3;
+	output_struct->id = ACPI_RSTYPE_DMA;
+
+	/*
+	 * Point to the 8-bits of Byte 1
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	/* Decode the DMA channel bits */
+
+	for (i = 0, index = 0; index < 8; index++) {
+		if ((temp8 >> index) & 0x01) {
+			output_struct->data.dma.channels[i] = index;
+			i++;
+		}
+	}
+
+	/* Zero DMA channels is valid */
+
+	output_struct->data.dma.number_of_channels = i;
+	if (i > 0) {
+		/*
+		 * Calculate the structure size based upon the number of interrupts
+		 */
+		struct_size += ((acpi_size) i - 1) * 4;
+	}
+
+	/*
+	 * Point to Byte 2
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	/*
+	 * Check for transfer preference (Bits[1:0])
+	 */
+	output_struct->data.dma.transfer = temp8 & 0x03;
+
+	if (0x03 == output_struct->data.dma.transfer) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n"));
+		return_ACPI_STATUS (AE_BAD_DATA);
+	}
+
+	/*
+	 * Get bus master preference (Bit[2])
+	 */
+	output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01;
+
+	/*
+	 * Get channel speed support (Bits[6:5])
+	 */
+	output_struct->data.dma.type = (temp8 >> 5) & 0x03;
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_dma_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_dma_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	u8                              index;
+
+
+	ACPI_FUNCTION_TRACE ("rs_dma_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x2A;
+	buffer += 1;
+	temp8 = 0;
+
+	/*
+	 * Loop through all of the Channels and set the mask bits
+	 */
+	for (index = 0;
+		 index < linked_list->data.dma.number_of_channels;
+		 index++) {
+		temp16 = (u16) linked_list->data.dma.channels[index];
+		temp8 |= 0x1 << temp16;
+	}
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the DMA Info
+	 */
+	temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5);
+	temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2);
+	temp8 |= (linked_list->data.dma.transfer & 0x03);
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
new file mode 100644
index 0000000..fd07a87
--- /dev/null
+++ b/drivers/acpi/resources/rsirq.c
@@ -0,0 +1,592 @@
+/*******************************************************************************
+ *
+ * Module Name: rsirq - IRQ resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsirq")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_irq_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_irq_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	u8                              index;
+	u8                              i;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_irq);
+
+
+	ACPI_FUNCTION_TRACE ("rs_irq_resource");
+
+
+	/*
+	 * The number of bytes consumed are contained in the descriptor
+	 *  (Bits:0-1)
+	 */
+	temp8 = *buffer;
+	*bytes_consumed = (temp8 & 0x03) + 1;
+	output_struct->id = ACPI_RSTYPE_IRQ;
+
+	/*
+	 * Point to the 16-bits of Bytes 1 and 2
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	output_struct->data.irq.number_of_interrupts = 0;
+
+	/* Decode the IRQ bits */
+
+	for (i = 0, index = 0; index < 16; index++) {
+		if ((temp16 >> index) & 0x01) {
+			output_struct->data.irq.interrupts[i] = index;
+			i++;
+		}
+	}
+
+	/* Zero interrupts is valid */
+
+	output_struct->data.irq.number_of_interrupts = i;
+	if (i > 0) {
+		/*
+		 * Calculate the structure size based upon the number of interrupts
+		 */
+		struct_size += ((acpi_size) i - 1) * 4;
+	}
+
+	/*
+	 * Point to Byte 3 if it is used
+	 */
+	if (4 == *bytes_consumed) {
+		buffer += 2;
+		temp8 = *buffer;
+
+		/*
+		 * Check for HE, LL interrupts
+		 */
+		switch (temp8 & 0x09) {
+		case 0x01: /* HE */
+			output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
+			output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
+			break;
+
+		case 0x08: /* LL */
+			output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
+			output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW;
+			break;
+
+		default:
+			/*
+			 * Only _LL and _HE polarity/trigger interrupts
+			 * are allowed (ACPI spec, section "IRQ Format")
+			 * so 0x00 and 0x09 are illegal.
+			 */
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Invalid interrupt polarity/trigger in resource list, %X\n", temp8));
+			return_ACPI_STATUS (AE_BAD_DATA);
+		}
+
+		/*
+		 * Check for sharable
+		 */
+		output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01;
+	}
+	else {
+		/*
+		 * Assume Edge Sensitive, Active High, Non-Sharable
+		 * per ACPI Specification
+		 */
+		output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
+		output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
+		output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+	}
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_irq_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_irq_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	u8                              index;
+	u8                              IRqinfo_byte_needed;
+
+
+	ACPI_FUNCTION_TRACE ("rs_irq_stream");
+
+
+	/*
+	 * The descriptor field is set based upon whether a third byte is
+	 * needed to contain the IRQ Information.
+	 */
+	if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level &&
+		ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low &&
+		ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) {
+		*buffer = 0x22;
+		IRqinfo_byte_needed = FALSE;
+	}
+	else {
+		*buffer = 0x23;
+		IRqinfo_byte_needed = TRUE;
+	}
+
+	buffer += 1;
+	temp16 = 0;
+
+	/*
+	 * Loop through all of the interrupts and set the mask bits
+	 */
+	for(index = 0;
+		index < linked_list->data.irq.number_of_interrupts;
+		index++) {
+		temp8 = (u8) linked_list->data.irq.interrupts[index];
+		temp16 |= 0x1 << temp8;
+	}
+
+	ACPI_MOVE_16_TO_16 (buffer, &temp16);
+	buffer += 2;
+
+	/*
+	 * Set the IRQ Info byte if needed.
+	 */
+	if (IRqinfo_byte_needed) {
+		temp8 = 0;
+		temp8 = (u8) ((linked_list->data.irq.shared_exclusive &
+				 0x01) << 4);
+
+		if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level &&
+			ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) {
+			temp8 |= 0x08;
+		}
+		else {
+			temp8 |= 0x01;
+		}
+
+		*buffer = temp8;
+		buffer += 1;
+	}
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_extended_irq_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_extended_irq_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	u8                              *temp_ptr;
+	u8                              index;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq);
+
+
+	ACPI_FUNCTION_TRACE ("rs_extended_irq_resource");
+
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	/* Validate minimum descriptor length */
+
+	if (temp16 < 6) {
+		return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+	}
+
+	*bytes_consumed = temp16 + 3;
+	output_struct->id = ACPI_RSTYPE_EXT_IRQ;
+
+	/*
+	 * Point to the Byte3
+	 */
+	buffer += 2;
+	temp8 = *buffer;
+
+	output_struct->data.extended_irq.producer_consumer = temp8 & 0x01;
+
+	/*
+	 * Check for Interrupt Mode
+	 *
+	 * The definition of an Extended IRQ changed between ACPI spec v1.0b
+	 * and ACPI spec 2.0 (section 6.4.3.6 in both).
+	 *
+	 * - Edge/Level are defined opposite in the table vs the headers
+	 */
+	output_struct->data.extended_irq.edge_level =
+			   (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+
+	/*
+	 * Check Interrupt Polarity
+	 */
+	output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1;
+
+	/*
+	 * Check for sharable
+	 */
+	output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01;
+
+	/*
+	 * Point to Byte4 (IRQ Table length)
+	 */
+	buffer += 1;
+	temp8 = *buffer;
+
+	/* Must have at least one IRQ */
+
+	if (temp8 < 1) {
+		return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
+	}
+
+	output_struct->data.extended_irq.number_of_interrupts = temp8;
+
+	/*
+	 * Add any additional structure size to properly calculate
+	 * the next pointer at the end of this function
+	 */
+	struct_size += (temp8 - 1) * 4;
+
+	/*
+	 * Point to Byte5 (First IRQ Number)
+	 */
+	buffer += 1;
+
+	/*
+	 * Cycle through every IRQ in the table
+	 */
+	for (index = 0; index < temp8; index++) {
+		ACPI_MOVE_32_TO_32 (
+			&output_struct->data.extended_irq.interrupts[index], buffer);
+
+		/* Point to the next IRQ */
+
+		buffer += 4;
+	}
+
+	/*
+	 * This will leave us pointing to the Resource Source Index
+	 * If it is present, then save it off and calculate the
+	 * pointer to where the null terminated string goes:
+	 * Each Interrupt takes 32-bits + the 5 bytes of the
+	 * stream that are default.
+	 *
+	 * Note: Some resource descriptors will have an additional null, so
+	 * we add 1 to the length.
+	 */
+	if (*bytes_consumed >
+		((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + (5 + 1)) {
+		/* Dereference the Index */
+
+		temp8 = *buffer;
+		output_struct->data.extended_irq.resource_source.index = (u32) temp8;
+
+		/* Point to the String */
+
+		buffer += 1;
+
+		/*
+		 * Point the String pointer to the end of this structure.
+		 */
+		output_struct->data.extended_irq.resource_source.string_ptr =
+				(char *)((char *) output_struct + struct_size);
+
+		temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr;
+
+		/* Copy the string into the buffer */
+
+		index = 0;
+		while (0x00 != *buffer) {
+			*temp_ptr = *buffer;
+
+			temp_ptr += 1;
+			buffer += 1;
+			index += 1;
+		}
+
+		/*
+		 * Add the terminating null
+		 */
+		*temp_ptr = 0x00;
+		output_struct->data.extended_irq.resource_source.string_length = index + 1;
+
+		/*
+		 * In order for the struct_size to fall on a 32-bit boundary,
+		 * calculate the length of the string and expand the
+		 * struct_size to the next 32-bit boundary.
+		 */
+		temp8 = (u8) (index + 1);
+		struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
+	}
+	else {
+		output_struct->data.extended_irq.resource_source.index = 0x00;
+		output_struct->data.extended_irq.resource_source.string_length = 0;
+		output_struct->data.extended_irq.resource_source.string_ptr = NULL;
+	}
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_extended_irq_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_extended_irq_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             *length_field;
+	u8                              temp8 = 0;
+	u8                              index;
+	char                            *temp_pointer = NULL;
+
+
+	ACPI_FUNCTION_TRACE ("rs_extended_irq_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x89;
+	buffer += 1;
+
+	/*
+	 * Set a pointer to the Length field - to be filled in later
+	 */
+	length_field = ACPI_CAST_PTR (u16, buffer);
+	buffer += 2;
+
+	/*
+	 * Set the Interrupt vector flags
+	 */
+	temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01);
+	temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
+
+	/*
+	 * Set the Interrupt Mode
+	 *
+	 * The definition of an Extended IRQ changed between ACPI spec v1.0b
+	 * and ACPI spec 2.0 (section 6.4.3.6 in both).  This code does not
+	 * implement the more restrictive definition of 1.0b
+	 *
+	 * - Edge/Level are defined opposite in the table vs the headers
+	 */
+	if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) {
+		temp8 |= 0x2;
+	}
+
+	/*
+	 * Set the Interrupt Polarity
+	 */
+	temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2);
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the Interrupt table length
+	 */
+	temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	for (index = 0; index < linked_list->data.extended_irq.number_of_interrupts;
+		 index++) {
+		ACPI_MOVE_32_TO_32 (buffer,
+				  &linked_list->data.extended_irq.interrupts[index]);
+		buffer += 4;
+	}
+
+	/*
+	 * Resource Source Index and Resource Source are optional
+	 */
+	if (0 != linked_list->data.extended_irq.resource_source.string_length) {
+		*buffer = (u8) linked_list->data.extended_irq.resource_source.index;
+		buffer += 1;
+
+		temp_pointer = (char *) buffer;
+
+		/*
+		 * Copy the string
+		 */
+		ACPI_STRCPY (temp_pointer,
+			linked_list->data.extended_irq.resource_source.string_ptr);
+
+		/*
+		 * Buffer needs to be set to the length of the sting + one for the
+		 * terminating null
+		 */
+		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1);
+	}
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+
+	/*
+	 * Set the length field to the number of bytes consumed
+	 * minus the header size (3 bytes)
+	 */
+	*length_field = (u16) (*bytes_consumed - 3);
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
new file mode 100644
index 0000000..e49c1e0
--- /dev/null
+++ b/drivers/acpi/resources/rslist.c
@@ -0,0 +1,518 @@
+/*******************************************************************************
+ *
+ * Module Name: rslist - Linked list utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rslist")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_resource_type
+ *
+ * PARAMETERS:  resource_start_byte     - Byte 0 of a resource descriptor
+ *
+ * RETURN:      The Resource Type (Name) with no extraneous bits
+ *
+ * DESCRIPTION: Extract the Resource Type/Name from the first byte of
+ *              a resource descriptor.
+ *
+ ******************************************************************************/
+
+u8
+acpi_rs_get_resource_type (
+	u8                              resource_start_byte)
+{
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/*
+	 * Determine if this is a small or large resource
+	 */
+	switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) {
+	case ACPI_RDESC_TYPE_SMALL:
+
+		/*
+		 * Small Resource Type -- Only bits 6:3 are valid
+		 */
+		return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK));
+
+
+	case ACPI_RDESC_TYPE_LARGE:
+
+		/*
+		 * Large Resource Type -- All bits are valid
+		 */
+		return (resource_start_byte);
+
+
+	default:
+		/* No other types of resource descriptor */
+		break;
+	}
+
+	return (0xFF);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_byte_stream_to_list
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
+ *              byte_stream_buffer_length - Length of byte_stream_buffer
+ *              output_buffer           - Pointer to the buffer that will
+ *                                        contain the output structures
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Takes the resource byte stream and parses it, creating a
+ *              linked list of resources in the caller's output buffer
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_byte_stream_to_list (
+	u8                              *byte_stream_buffer,
+	u32                             byte_stream_buffer_length,
+	u8                              *output_buffer)
+{
+	acpi_status                     status;
+	acpi_size                       bytes_parsed = 0;
+	u8                              resource_type = 0;
+	acpi_size                       bytes_consumed = 0;
+	u8                              *buffer = output_buffer;
+	acpi_size                       structure_size = 0;
+	u8                              end_tag_processed = FALSE;
+	struct acpi_resource            *resource;
+
+	ACPI_FUNCTION_TRACE ("rs_byte_stream_to_list");
+
+
+	while (bytes_parsed < byte_stream_buffer_length &&
+			!end_tag_processed) {
+		/*
+		 * The next byte in the stream is the resource type
+		 */
+		resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
+
+		switch (resource_type) {
+		case ACPI_RDESC_TYPE_MEMORY_24:
+			/*
+			 * 24-Bit Memory Resource
+			 */
+			status = acpi_rs_memory24_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_LARGE_VENDOR:
+			/*
+			 * Vendor Defined Resource
+			 */
+			status = acpi_rs_vendor_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_MEMORY_32:
+			/*
+			 * 32-Bit Memory Range Resource
+			 */
+			status = acpi_rs_memory32_range_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
+			/*
+			 * 32-Bit Fixed Memory Resource
+			 */
+			status = acpi_rs_fixed_memory32_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
+		case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
+			/*
+			 * 64-Bit Address Resource
+			 */
+			status = acpi_rs_address64_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
+			/*
+			 * 32-Bit Address Resource
+			 */
+			status = acpi_rs_address32_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
+			/*
+			 * 16-Bit Address Resource
+			 */
+			status = acpi_rs_address16_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
+			/*
+			 * Extended IRQ
+			 */
+			status = acpi_rs_extended_irq_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_IRQ_FORMAT:
+			/*
+			 * IRQ Resource
+			 */
+			status = acpi_rs_irq_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_DMA_FORMAT:
+			/*
+			 * DMA Resource
+			 */
+			status = acpi_rs_dma_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_START_DEPENDENT:
+			/*
+			 * Start Dependent Functions Resource
+			 */
+			status = acpi_rs_start_depend_fns_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_END_DEPENDENT:
+			/*
+			 * End Dependent Functions Resource
+			 */
+			status = acpi_rs_end_depend_fns_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_IO_PORT:
+			/*
+			 * IO Port Resource
+			 */
+			status = acpi_rs_io_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_FIXED_IO_PORT:
+			/*
+			 * Fixed IO Port Resource
+			 */
+			status = acpi_rs_fixed_io_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_SMALL_VENDOR:
+			/*
+			 * Vendor Specific Resource
+			 */
+			status = acpi_rs_vendor_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		case ACPI_RDESC_TYPE_END_TAG:
+			/*
+			 * End Tag
+			 */
+			end_tag_processed = TRUE;
+			status = acpi_rs_end_tag_resource (byte_stream_buffer,
+					 &bytes_consumed, &buffer, &structure_size);
+			break;
+
+
+		default:
+			/*
+			 * Invalid/Unknown resource type
+			 */
+			status = AE_AML_INVALID_RESOURCE_TYPE;
+			break;
+		}
+
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/*
+		 * Update the return value and counter
+		 */
+		bytes_parsed += bytes_consumed;
+
+		/*
+		 * Set the byte stream to point to the next resource
+		 */
+		byte_stream_buffer += bytes_consumed;
+
+		/*
+		 * Set the Buffer to the next structure
+		 */
+		resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
+		resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
+		buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+
+	} /*  end while */
+
+	/*
+	 * Check the reason for exiting the while loop
+	 */
+	if (!end_tag_processed) {
+		return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_list_to_byte_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              byte_steam_size_needed  - Calculated size of the byte stream
+ *                                        needed from calling
+ *                                        acpi_rs_get_byte_stream_length()
+ *                                        The size of the output_buffer is
+ *                                        guaranteed to be >=
+ *                                        byte_stream_size_needed
+ *              output_buffer           - Pointer to the buffer that will
+ *                                        contain the byte stream
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Takes the resource linked list and parses it, creating a
+ *              byte stream of resources in the caller's output buffer
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_list_to_byte_stream (
+	struct acpi_resource            *linked_list,
+	acpi_size                       byte_stream_size_needed,
+	u8                              *output_buffer)
+{
+	acpi_status                     status;
+	u8                              *buffer = output_buffer;
+	acpi_size                       bytes_consumed = 0;
+	u8                              done = FALSE;
+
+
+	ACPI_FUNCTION_TRACE ("rs_list_to_byte_stream");
+
+
+	while (!done) {
+		switch (linked_list->id) {
+		case ACPI_RSTYPE_IRQ:
+			/*
+			 * IRQ Resource
+			 */
+			status = acpi_rs_irq_stream (linked_list, &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_DMA:
+			/*
+			 * DMA Resource
+			 */
+			status = acpi_rs_dma_stream (linked_list, &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_START_DPF:
+			/*
+			 * Start Dependent Functions Resource
+			 */
+			status = acpi_rs_start_depend_fns_stream (linked_list,
+					  &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_END_DPF:
+			/*
+			 * End Dependent Functions Resource
+			 */
+			status = acpi_rs_end_depend_fns_stream (linked_list,
+					  &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_IO:
+			/*
+			 * IO Port Resource
+			 */
+			status = acpi_rs_io_stream (linked_list, &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_FIXED_IO:
+			/*
+			 * Fixed IO Port Resource
+			 */
+			status = acpi_rs_fixed_io_stream (linked_list, &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_VENDOR:
+			/*
+			 * Vendor Defined Resource
+			 */
+			status = acpi_rs_vendor_stream (linked_list, &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_END_TAG:
+			/*
+			 * End Tag
+			 */
+			status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed);
+
+			/*
+			 * An End Tag indicates the end of the Resource Template
+			 */
+			done = TRUE;
+			break;
+
+		case ACPI_RSTYPE_MEM24:
+			/*
+			 * 24-Bit Memory Resource
+			 */
+			status = acpi_rs_memory24_stream (linked_list, &buffer, &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_MEM32:
+			/*
+			 * 32-Bit Memory Range Resource
+			 */
+			status = acpi_rs_memory32_range_stream (linked_list, &buffer,
+					 &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_FIXED_MEM32:
+			/*
+			 * 32-Bit Fixed Memory Resource
+			 */
+			status = acpi_rs_fixed_memory32_stream (linked_list, &buffer,
+					 &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_ADDRESS16:
+			/*
+			 * 16-Bit Address Descriptor Resource
+			 */
+			status = acpi_rs_address16_stream (linked_list, &buffer,
+					 &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_ADDRESS32:
+			/*
+			 * 32-Bit Address Descriptor Resource
+			 */
+			status = acpi_rs_address32_stream (linked_list, &buffer,
+					 &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_ADDRESS64:
+			/*
+			 * 64-Bit Address Descriptor Resource
+			 */
+			status = acpi_rs_address64_stream (linked_list, &buffer,
+					 &bytes_consumed);
+			break;
+
+		case ACPI_RSTYPE_EXT_IRQ:
+			/*
+			 * Extended IRQ Resource
+			 */
+			status = acpi_rs_extended_irq_stream (linked_list, &buffer,
+					 &bytes_consumed);
+			break;
+
+		default:
+			/*
+			 * If we get here, everything is out of sync,
+			 *  so exit with an error
+			 */
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n",
+				linked_list->id));
+			status = AE_BAD_DATA;
+			break;
+
+		} /* switch (linked_list->Id) */
+
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		/*
+		 * Set the Buffer to point to the open byte
+		 */
+		buffer += bytes_consumed;
+
+		/*
+		 * Point to the next object
+		 */
+		linked_list = ACPI_PTR_ADD (struct acpi_resource,
+				  linked_list, linked_list->length);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
new file mode 100644
index 0000000..7c935ae
--- /dev/null
+++ b/drivers/acpi/resources/rsmemory.c
@@ -0,0 +1,566 @@
+/*******************************************************************************
+ *
+ * Module Name: rsmem24 - Memory resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsmemory")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_memory24_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_memory24_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24);
+
+
+	ACPI_FUNCTION_TRACE ("rs_memory24_resource");
+
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+	buffer += 2;
+	*bytes_consumed = (acpi_size) temp16 + 3;
+	output_struct->id = ACPI_RSTYPE_MEM24;
+
+	/*
+	 * Check Byte 3 the Read/Write bit
+	 */
+	temp8 = *buffer;
+	buffer += 1;
+	output_struct->data.memory24.read_write_attribute = temp8 & 0x01;
+
+	/*
+	 * Get min_base_address (Bytes 4-5)
+	 */
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+	buffer += 2;
+	output_struct->data.memory24.min_base_address = temp16;
+
+	/*
+	 * Get max_base_address (Bytes 6-7)
+	 */
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+	buffer += 2;
+	output_struct->data.memory24.max_base_address = temp16;
+
+	/*
+	 * Get Alignment (Bytes 8-9)
+	 */
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+	buffer += 2;
+	output_struct->data.memory24.alignment = temp16;
+
+	/*
+	 * Get range_length (Bytes 10-11)
+	 */
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+	output_struct->data.memory24.range_length = temp16;
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_memory24_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_memory24_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_memory24_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x81;
+	buffer += 1;
+
+	/*
+	 * The length field is static
+	 */
+	temp16 = 0x09;
+	ACPI_MOVE_16_TO_16 (buffer, &temp16);
+	buffer += 2;
+
+	/*
+	 * Set the Information Byte
+	 */
+	temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01);
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the Range minimum base address
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.min_base_address);
+	buffer += 2;
+
+	/*
+	 * Set the Range maximum base address
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.max_base_address);
+	buffer += 2;
+
+	/*
+	 * Set the base alignment
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.alignment);
+	buffer += 2;
+
+	/*
+	 * Set the range length
+	 */
+	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.range_length);
+	buffer += 2;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_memory32_range_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_memory32_range_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32);
+
+
+	ACPI_FUNCTION_TRACE ("rs_memory32_range_resource");
+
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+	buffer += 2;
+	*bytes_consumed = (acpi_size) temp16 + 3;
+
+	output_struct->id = ACPI_RSTYPE_MEM32;
+
+	/*
+	 *  Point to the place in the output buffer where the data portion will
+	 *  begin.
+	 *  1. Set the RESOURCE_DATA * Data to point to its own address, then
+	 *  2. Set the pointer to the next address.
+	 *
+	 *  NOTE: output_struct->Data is cast to u8, otherwise, this addition adds
+	 *  4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8)
+	 */
+
+	/*
+	 * Check Byte 3 the Read/Write bit
+	 */
+	temp8 = *buffer;
+	buffer += 1;
+
+	output_struct->data.memory32.read_write_attribute = temp8 & 0x01;
+
+	/*
+	 * Get min_base_address (Bytes 4-7)
+	 */
+	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.min_base_address, buffer);
+	buffer += 4;
+
+	/*
+	 * Get max_base_address (Bytes 8-11)
+	 */
+	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.max_base_address, buffer);
+	buffer += 4;
+
+	/*
+	 * Get Alignment (Bytes 12-15)
+	 */
+	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.alignment, buffer);
+	buffer += 4;
+
+	/*
+	 * Get range_length (Bytes 16-19)
+	 */
+	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.range_length, buffer);
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_fixed_memory32_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_fixed_memory32_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32);
+
+
+	ACPI_FUNCTION_TRACE ("rs_fixed_memory32_resource");
+
+
+	/*
+	 * Point past the Descriptor to get the number of bytes consumed
+	 */
+	buffer += 1;
+	ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+	buffer += 2;
+	*bytes_consumed = (acpi_size) temp16 + 3;
+
+	output_struct->id = ACPI_RSTYPE_FIXED_MEM32;
+
+	/*
+	 * Check Byte 3 the Read/Write bit
+	 */
+	temp8 = *buffer;
+	buffer += 1;
+	output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01;
+
+	/*
+	 * Get range_base_address (Bytes 4-7)
+	 */
+	ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address, buffer);
+	buffer += 4;
+
+	/*
+	 * Get range_length (Bytes 8-11)
+	 */
+	ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_length, buffer);
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_memory32_range_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_memory32_range_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_memory32_range_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x85;
+	buffer += 1;
+
+	/*
+	 * The length field is static
+	 */
+	temp16 = 0x11;
+
+	ACPI_MOVE_16_TO_16 (buffer, &temp16);
+	buffer += 2;
+
+	/*
+	 * Set the Information Byte
+	 */
+	temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01);
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the Range minimum base address
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.min_base_address);
+	buffer += 4;
+
+	/*
+	 * Set the Range maximum base address
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.max_base_address);
+	buffer += 4;
+
+	/*
+	 * Set the base alignment
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.alignment);
+	buffer += 4;
+
+	/*
+	 * Set the range length
+	 */
+	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.range_length);
+	buffer += 4;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_fixed_memory32_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_fixed_memory32_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_fixed_memory32_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x86;
+	buffer += 1;
+
+	/*
+	 * The length field is static
+	 */
+	temp16 = 0x09;
+
+	ACPI_MOVE_16_TO_16 (buffer, &temp16);
+	buffer += 2;
+
+	/*
+	 * Set the Information Byte
+	 */
+	temp8 = (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01);
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Set the Range base address
+	 */
+	ACPI_MOVE_32_TO_32 (buffer,
+			 &linked_list->data.fixed_memory32.range_base_address);
+	buffer += 4;
+
+	/*
+	 * Set the range length
+	 */
+	ACPI_MOVE_32_TO_32 (buffer,
+			 &linked_list->data.fixed_memory32.range_length);
+	buffer += 4;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
new file mode 100644
index 0000000..d16be44
--- /dev/null
+++ b/drivers/acpi/resources/rsmisc.c
@@ -0,0 +1,597 @@
+/*******************************************************************************
+ *
+ * Module Name: rsmisc - Miscellaneous resource descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_end_tag_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_end_tag_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	acpi_size                       struct_size = ACPI_RESOURCE_LENGTH;
+
+
+	ACPI_FUNCTION_TRACE ("rs_end_tag_resource");
+
+
+	/*
+	 * The number of bytes consumed is static
+	 */
+	*bytes_consumed = 2;
+
+	/*
+	 *  Fill out the structure
+	 */
+	output_struct->id = ACPI_RSTYPE_END_TAG;
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = 0;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_end_tag_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_end_tag_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u8                              temp8 = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_end_tag_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x79;
+	buffer += 1;
+
+	/*
+	 * Set the Checksum - zero means that the resource data is treated as if
+	 * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
+	 */
+	temp8 = 0;
+
+	*buffer = temp8;
+	buffer += 1;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_vendor_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_vendor_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	u8                              index;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor);
+
+
+	ACPI_FUNCTION_TRACE ("rs_vendor_resource");
+
+
+	/*
+	 * Dereference the Descriptor to find if this is a large or small item.
+	 */
+	temp8 = *buffer;
+
+	if (temp8 & 0x80) {
+		/*
+		 * Large Item, point to the length field
+		 */
+		buffer += 1;
+
+		/* Dereference */
+
+		ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+		/* Calculate bytes consumed */
+
+		*bytes_consumed = (acpi_size) temp16 + 3;
+
+		/* Point to the first vendor byte */
+
+		buffer += 2;
+	}
+	else {
+		/*
+		 * Small Item, dereference the size
+		 */
+		temp16 = (u8)(*buffer & 0x07);
+
+		/* Calculate bytes consumed */
+
+		*bytes_consumed = (acpi_size) temp16 + 1;
+
+		/* Point to the first vendor byte */
+
+		buffer += 1;
+	}
+
+	output_struct->id = ACPI_RSTYPE_VENDOR;
+	output_struct->data.vendor_specific.length = temp16;
+
+	for (index = 0; index < temp16; index++) {
+		output_struct->data.vendor_specific.reserved[index] = *buffer;
+		buffer += 1;
+	}
+
+	/*
+	 * In order for the struct_size to fall on a 32-bit boundary,
+	 * calculate the length of the vendor string and expand the
+	 * struct_size to the next 32-bit boundary.
+	 */
+	struct_size += ACPI_ROUND_UP_to_32_bITS (temp16);
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_vendor_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_vendor_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u16                             temp16 = 0;
+	u8                              temp8 = 0;
+	u8                              index;
+
+
+	ACPI_FUNCTION_TRACE ("rs_vendor_stream");
+
+
+	/*
+	 * Dereference the length to find if this is a large or small item.
+	 */
+	if(linked_list->data.vendor_specific.length > 7) {
+		/*
+		 * Large Item, Set the descriptor field and length bytes
+		 */
+		*buffer = 0x84;
+		buffer += 1;
+
+		temp16 = (u16) linked_list->data.vendor_specific.length;
+
+		ACPI_MOVE_16_TO_16 (buffer, &temp16);
+		buffer += 2;
+	}
+	else {
+		/*
+		 * Small Item, Set the descriptor field
+		 */
+		temp8 = 0x70;
+		temp8 |= (u8) linked_list->data.vendor_specific.length;
+
+		*buffer = temp8;
+		buffer += 1;
+	}
+
+	/*
+	 * Loop through all of the Vendor Specific fields
+	 */
+	for (index = 0; index < linked_list->data.vendor_specific.length; index++) {
+		temp8 = linked_list->data.vendor_specific.reserved[index];
+
+		*buffer = temp8;
+		buffer += 1;
+	}
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_start_depend_fns_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_start_depend_fns_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	u8                              temp8 = 0;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf);
+
+
+	ACPI_FUNCTION_TRACE ("rs_start_depend_fns_resource");
+
+
+	/*
+	 * The number of bytes consumed are contained in the descriptor (Bits:0-1)
+	 */
+	temp8 = *buffer;
+
+	*bytes_consumed = (temp8 & 0x01) + 1;
+
+	output_struct->id = ACPI_RSTYPE_START_DPF;
+
+	/*
+	 * Point to Byte 1 if it is used
+	 */
+	if (2 == *bytes_consumed) {
+		buffer += 1;
+		temp8 = *buffer;
+
+		/*
+		 * Check Compatibility priority
+		 */
+		output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03;
+
+		if (3 == output_struct->data.start_dpf.compatibility_priority) {
+			return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
+		}
+
+		/*
+		 * Check Performance/Robustness preference
+		 */
+		output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03;
+
+		if (3 == output_struct->data.start_dpf.performance_robustness) {
+			return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
+		}
+	}
+	else {
+		output_struct->data.start_dpf.compatibility_priority =
+				ACPI_ACCEPTABLE_CONFIGURATION;
+
+		output_struct->data.start_dpf.performance_robustness =
+				ACPI_ACCEPTABLE_CONFIGURATION;
+	}
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_end_depend_fns_resource
+ *
+ * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
+ *                                        stream
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        consumed the byte_stream_buffer is
+ *                                        returned
+ *              output_buffer           - Pointer to the return data buffer
+ *              structure_size          - Pointer to where the number of bytes
+ *                                        in the return data struct is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the resource byte stream and fill out the appropriate
+ *              structure pointed to by the output_buffer. Return the
+ *              number of bytes consumed from the byte stream.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_end_depend_fns_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size)
+{
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	acpi_size                       struct_size = ACPI_RESOURCE_LENGTH;
+
+
+	ACPI_FUNCTION_TRACE ("rs_end_depend_fns_resource");
+
+
+	/*
+	 * The number of bytes consumed is static
+	 */
+	*bytes_consumed = 1;
+
+	/*
+	 *  Fill out the structure
+	 */
+	output_struct->id = ACPI_RSTYPE_END_DPF;
+
+	/*
+	 * Set the Length parameter
+	 */
+	output_struct->length = (u32) struct_size;
+
+	/*
+	 * Return the final size of the structure
+	 */
+	*structure_size = struct_size;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_start_depend_fns_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - u32 pointer that is filled with
+ *                                        the number of bytes of the
+ *                                        output_buffer used
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_start_depend_fns_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+	u8                              temp8 = 0;
+
+
+	ACPI_FUNCTION_TRACE ("rs_start_depend_fns_stream");
+
+
+	/*
+	 * The descriptor field is set based upon whether a byte is needed
+	 * to contain Priority data.
+	 */
+	if (ACPI_ACCEPTABLE_CONFIGURATION ==
+			linked_list->data.start_dpf.compatibility_priority &&
+		ACPI_ACCEPTABLE_CONFIGURATION ==
+			linked_list->data.start_dpf.performance_robustness) {
+		*buffer = 0x30;
+	}
+	else {
+		*buffer = 0x31;
+		buffer += 1;
+
+		/*
+		 * Set the Priority Byte Definition
+		 */
+		temp8 = 0;
+		temp8 = (u8) ((linked_list->data.start_dpf.performance_robustness &
+				   0x03) << 2);
+		temp8 |= (linked_list->data.start_dpf.compatibility_priority &
+				   0x03);
+		*buffer = temp8;
+	}
+
+	buffer += 1;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_end_depend_fns_stream
+ *
+ * PARAMETERS:  linked_list             - Pointer to the resource linked list
+ *              output_buffer           - Pointer to the user's return buffer
+ *              bytes_consumed          - Pointer to where the number of bytes
+ *                                        used in the output_buffer is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Take the linked list resource structure and fills in the
+ *              the appropriate bytes in a byte stream
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_end_depend_fns_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed)
+{
+	u8                              *buffer = *output_buffer;
+
+
+	ACPI_FUNCTION_TRACE ("rs_end_depend_fns_stream");
+
+
+	/*
+	 * The descriptor field is static
+	 */
+	*buffer = 0x38;
+	buffer += 1;
+
+	/*
+	 * Return the number of bytes consumed in this operation
+	 */
+	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
new file mode 100644
index 0000000..ee9ce13
--- /dev/null
+++ b/drivers/acpi/resources/rsutils.c
@@ -0,0 +1,356 @@
+/*******************************************************************************
+ *
+ * Module Name: rsutils - Utilities for the resource manager
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acresrc.h>
+
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_prt_method_data
+ *
+ * PARAMETERS:  Handle          - a handle to the containing object
+ *              ret_buffer      - a pointer to a buffer structure for the
+ *                                  results
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the _PRT value of an object
+ *              contained in an object specified by the handle passed in
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_get_prt_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *ret_buffer)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_prt_method_data");
+
+
+	/* Parameters guaranteed valid by caller */
+
+	/*
+	 * Execute the method, no parameters
+	 */
+	status = acpi_ut_evaluate_object (handle, "_PRT", ACPI_BTYPE_PACKAGE, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Create a resource linked list from the byte stream buffer that comes
+	 * back from the _CRS method execution.
+	 */
+	status = acpi_rs_create_pci_routing_table (obj_desc, ret_buffer);
+
+	/* On exit, we must delete the object returned by evaluate_object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_crs_method_data
+ *
+ * PARAMETERS:  Handle          - a handle to the containing object
+ *              ret_buffer      - a pointer to a buffer structure for the
+ *                                  results
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the _CRS value of an object
+ *              contained in an object specified by the handle passed in
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_get_crs_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *ret_buffer)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_crs_method_data");
+
+
+	/* Parameters guaranteed valid by caller */
+
+	/*
+	 * Execute the method, no parameters
+	 */
+	status = acpi_ut_evaluate_object (handle, "_CRS", ACPI_BTYPE_BUFFER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Make the call to create a resource linked list from the
+	 * byte stream buffer that comes back from the _CRS method
+	 * execution.
+	 */
+	status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
+
+	/* on exit, we must delete the object returned by evaluate_object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_prs_method_data
+ *
+ * PARAMETERS:  Handle          - a handle to the containing object
+ *              ret_buffer      - a pointer to a buffer structure for the
+ *                                  results
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the _PRS value of an object
+ *              contained in an object specified by the handle passed in
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_rs_get_prs_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *ret_buffer)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_prs_method_data");
+
+
+	/* Parameters guaranteed valid by caller */
+
+	/*
+	 * Execute the method, no parameters
+	 */
+	status = acpi_ut_evaluate_object (handle, "_PRS", ACPI_BTYPE_BUFFER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Make the call to create a resource linked list from the
+	 * byte stream buffer that comes back from the _CRS method
+	 * execution.
+	 */
+	status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
+
+	/* on exit, we must delete the object returned by evaluate_object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_method_data
+ *
+ * PARAMETERS:  Handle          - a handle to the containing object
+ *              ret_buffer      - a pointer to a buffer structure for the
+ *                                  results
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
+ *              object contained in an object specified by the handle passed in
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_get_method_data (
+	acpi_handle                     handle,
+	char                            *path,
+	struct acpi_buffer              *ret_buffer)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_method_data");
+
+
+	/* Parameters guaranteed valid by caller */
+
+	/*
+	 * Execute the method, no parameters
+	 */
+	status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Make the call to create a resource linked list from the
+	 * byte stream buffer that comes back from the method
+	 * execution.
+	 */
+	status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
+
+	/* On exit, we must delete the object returned by evaluate_object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_set_srs_method_data
+ *
+ * PARAMETERS:  Handle          - a handle to the containing object
+ *              in_buffer       - a pointer to a buffer structure of the
+ *                                  parameter
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to set the _SRS of an object contained
+ *              in an object specified by the handle passed in
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_set_srs_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *in_buffer)
+{
+	struct acpi_parameter_info      info;
+	union acpi_operand_object       *params[2];
+	acpi_status                     status;
+	struct acpi_buffer              buffer;
+
+
+	ACPI_FUNCTION_TRACE ("rs_set_srs_method_data");
+
+
+	/* Parameters guaranteed valid by caller */
+
+	/*
+	 * The in_buffer parameter will point to a linked list of
+	 * resource parameters.  It needs to be formatted into a
+	 * byte stream to be sent in as an input parameter to _SRS
+	 *
+	 * Convert the linked list into a byte stream
+	 */
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_rs_create_byte_stream (in_buffer->pointer, &buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Init the param object
+	 */
+	params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+	if (!params[0]) {
+		acpi_os_free (buffer.pointer);
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * Set up the parameter object
+	 */
+	params[0]->buffer.length  = (u32) buffer.length;
+	params[0]->buffer.pointer = buffer.pointer;
+	params[0]->common.flags   = AOPOBJ_DATA_VALID;
+	params[1] = NULL;
+
+	info.node = handle;
+	info.parameters = params;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
+	/*
+	 * Execute the method, no return value
+	 */
+	status = acpi_ns_evaluate_relative ("_SRS", &info);
+	if (ACPI_SUCCESS (status)) {
+		/* Delete any return object (especially if implicit_return is enabled) */
+
+		if (info.return_object) {
+			acpi_ut_remove_reference (info.return_object);
+		}
+	}
+
+	/*
+	 * Clean up and return the status from acpi_ns_evaluate_relative
+	 */
+	acpi_ut_remove_reference (params[0]);
+	return_ACPI_STATUS (status);
+}
+
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
new file mode 100644
index 0000000..a9cdcbe
--- /dev/null
+++ b/drivers/acpi/resources/rsxface.c
@@ -0,0 +1,437 @@
+/*******************************************************************************
+ *
+ * Module Name: rsxface - Public interfaces to the resource manager
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+	 ACPI_MODULE_NAME    ("rsxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_irq_routing_table
+ *
+ * PARAMETERS:  device_handle   - a handle to the Bus device we are querying
+ *              ret_buffer      - a pointer to a buffer to receive the
+ *                                current resources for the device
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the IRQ routing table for a
+ *              specific bus.  The caller must first acquire a handle for the
+ *              desired bus.  The routine table is placed in the buffer pointed
+ *              to by the ret_buffer variable parameter.
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the value of ret_buffer is undefined.
+ *
+ *              This function attempts to execute the _PRT method contained in
+ *              the object indicated by the passed device_handle.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_irq_routing_table (
+	acpi_handle                     device_handle,
+	struct acpi_buffer              *ret_buffer)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_irq_routing_table ");
+
+
+	/*
+	 * Must have a valid handle and buffer, So we have to have a handle
+	 * and a return buffer structure, and if there is a non-zero buffer length
+	 * we also need a valid pointer in the buffer. If it's a zero buffer length,
+	 * we'll be returning the needed buffer size, so keep going.
+	 */
+	if (!device_handle) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_validate_buffer (ret_buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_rs_get_prt_method_data (device_handle, ret_buffer);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_current_resources
+ *
+ * PARAMETERS:  device_handle   - a handle to the device object for the
+ *                                device we are querying
+ *              ret_buffer      - a pointer to a buffer to receive the
+ *                                current resources for the device
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the current resources for a
+ *              specific device.  The caller must first acquire a handle for
+ *              the desired device.  The resource data is placed in the buffer
+ *              pointed to by the ret_buffer variable parameter.
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the value of ret_buffer is undefined.
+ *
+ *              This function attempts to execute the _CRS method contained in
+ *              the object indicated by the passed device_handle.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_current_resources (
+	acpi_handle                     device_handle,
+	struct acpi_buffer              *ret_buffer)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_current_resources");
+
+
+	/*
+	 * Must have a valid handle and buffer, So we have to have a handle
+	 * and a return buffer structure, and if there is a non-zero buffer length
+	 * we also need a valid pointer in the buffer. If it's a zero buffer length,
+	 * we'll be returning the needed buffer size, so keep going.
+	 */
+	if (!device_handle) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_validate_buffer (ret_buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_rs_get_crs_method_data (device_handle, ret_buffer);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_get_current_resources);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_possible_resources
+ *
+ * PARAMETERS:  device_handle   - a handle to the device object for the
+ *                                device we are querying
+ *              ret_buffer      - a pointer to a buffer to receive the
+ *                                resources for the device
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get a list of the possible resources
+ *              for a specific device.  The caller must first acquire a handle
+ *              for the desired device.  The resource data is placed in the
+ *              buffer pointed to by the ret_buffer variable.
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the value of ret_buffer is undefined.
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_get_possible_resources (
+	acpi_handle                     device_handle,
+	struct acpi_buffer              *ret_buffer)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_possible_resources");
+
+
+	/*
+	 * Must have a valid handle and buffer, So we have to have a handle
+	 * and a return buffer structure, and if there is a non-zero buffer length
+	 * we also need a valid pointer in the buffer. If it's a zero buffer length,
+	 * we'll be returning the needed buffer size, so keep going.
+	 */
+	if (!device_handle) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_validate_buffer (ret_buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_rs_get_prs_method_data (device_handle, ret_buffer);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_get_possible_resources);
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_walk_resources
+ *
+ * PARAMETERS:  device_handle   - a handle to the device object for the
+ *                                device we are querying
+ *              Path            - method name of the resources we want
+ *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
+ *              user_function   - called for each resource
+ *              Context         - passed to user_function
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieves the current or possible resource list for the
+ *              specified device.  The user_function is called once for
+ *              each resource in the list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_walk_resources (
+	acpi_handle                             device_handle,
+	char                                    *path,
+	ACPI_WALK_RESOURCE_CALLBACK     user_function,
+	void                                    *context)
+{
+	acpi_status                         status;
+	struct acpi_buffer                  buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_resource                *resource;
+	struct acpi_resource                *buffer_end;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_walk_resources");
+
+
+	if (!device_handle ||
+		(ACPI_STRNCMP (path, METHOD_NAME__CRS, sizeof (METHOD_NAME__CRS)) &&
+		 ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_rs_get_method_data (device_handle, path, &buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Setup pointers */
+
+	resource  = (struct acpi_resource *) buffer.pointer;
+	buffer_end = ACPI_CAST_PTR (struct acpi_resource,
+			  ((u8 *) buffer.pointer + buffer.length));
+
+	/* Walk the resource list */
+
+	for (;;) {
+		if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
+			break;
+		}
+
+		status = user_function (resource, context);
+
+		switch (status) {
+		case AE_OK:
+		case AE_CTRL_DEPTH:
+
+			/* Just keep going */
+
+			status = AE_OK;
+			break;
+
+		case AE_CTRL_TERMINATE:
+
+			/* Exit now, with OK stats */
+
+			status = AE_OK;
+			goto cleanup;
+
+		default:
+
+			/* All others are valid exceptions */
+
+			goto cleanup;
+		}
+
+		/* Get the next resource descriptor */
+
+		resource = ACPI_NEXT_RESOURCE (resource);
+
+		/* Check for end-of-buffer */
+
+		if (resource >= buffer_end) {
+			goto cleanup;
+		}
+	}
+
+cleanup:
+
+	acpi_os_free (buffer.pointer);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_walk_resources);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_set_current_resources
+ *
+ * PARAMETERS:  device_handle   - a handle to the device object for the
+ *                                device we are changing the resources of
+ *              in_buffer       - a pointer to a buffer containing the
+ *                                resources to be set for the device
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to set the current resources for a
+ *              specific device.  The caller must first acquire a handle for
+ *              the desired device.  The resource data is passed to the routine
+ *              the buffer pointed to by the in_buffer variable.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_set_current_resources (
+	acpi_handle                     device_handle,
+	struct acpi_buffer              *in_buffer)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_set_current_resources");
+
+
+	/*
+	 * Must have a valid handle and buffer
+	 */
+	if ((!device_handle)      ||
+		(!in_buffer)          ||
+		(!in_buffer->pointer) ||
+		(!in_buffer->length)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_set_current_resources);
+
+
+#define ACPI_COPY_FIELD(out, in, field)  ((out)->field = (in)->field)
+#define ACPI_COPY_ADDRESS(out, in)                      \
+	ACPI_COPY_FIELD(out, in, resource_type);             \
+	ACPI_COPY_FIELD(out, in, producer_consumer);         \
+	ACPI_COPY_FIELD(out, in, decode);                    \
+	ACPI_COPY_FIELD(out, in, min_address_fixed);         \
+	ACPI_COPY_FIELD(out, in, max_address_fixed);         \
+	ACPI_COPY_FIELD(out, in, attribute);                 \
+	ACPI_COPY_FIELD(out, in, granularity);               \
+	ACPI_COPY_FIELD(out, in, min_address_range);         \
+	ACPI_COPY_FIELD(out, in, max_address_range);         \
+	ACPI_COPY_FIELD(out, in, address_translation_offset); \
+	ACPI_COPY_FIELD(out, in, address_length);            \
+	ACPI_COPY_FIELD(out, in, resource_source);
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_resource_to_address64
+ *
+ * PARAMETERS:  resource                - Pointer to a resource
+ *              out                     - Pointer to the users's return
+ *                                        buffer (a struct
+ *                                        struct acpi_resource_address64)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: If the resource is an address16, address32, or address64,
+ *              copy it to the address64 return buffer.  This saves the
+ *              caller from having to duplicate code for different-sized
+ *              addresses.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_resource_to_address64 (
+	struct acpi_resource                *resource,
+	struct acpi_resource_address64      *out)
+{
+	struct acpi_resource_address16      *address16;
+	struct acpi_resource_address32      *address32;
+
+
+	switch (resource->id) {
+	case ACPI_RSTYPE_ADDRESS16:
+
+		address16 = (struct acpi_resource_address16 *) &resource->data;
+		ACPI_COPY_ADDRESS(out, address16);
+		break;
+
+
+	case ACPI_RSTYPE_ADDRESS32:
+
+		address32 = (struct acpi_resource_address32 *) &resource->data;
+		ACPI_COPY_ADDRESS(out, address32);
+		break;
+
+
+	case ACPI_RSTYPE_ADDRESS64:
+
+		/* Simple copy for 64 bit source */
+
+		ACPI_MEMCPY (out, &resource->data, sizeof (struct acpi_resource_address64));
+		break;
+
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+	return (AE_OK);
+}
+EXPORT_SYMBOL(acpi_resource_to_address64);
+
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
new file mode 100644
index 0000000..e7ca066
--- /dev/null
+++ b/drivers/acpi/scan.c
@@ -0,0 +1,1379 @@
+/*
+ * scan.c - support for transforming the ACPI namespace into individual objects
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+#include <acpi/acpi_drivers.h>
+#include <acpi/acinterp.h>	/* for acpi_ex_eisa_id_to_string() */
+
+
+#define _COMPONENT		ACPI_BUS_COMPONENT
+ACPI_MODULE_NAME		("scan")
+
+#define STRUCT_TO_INT(s)	(*((int*)&s))
+
+extern struct acpi_device		*acpi_root;
+
+
+#define ACPI_BUS_CLASS			"system_bus"
+#define ACPI_BUS_HID			"ACPI_BUS"
+#define ACPI_BUS_DRIVER_NAME		"ACPI Bus Driver"
+#define ACPI_BUS_DEVICE_NAME		"System Bus"
+
+static LIST_HEAD(acpi_device_list);
+DEFINE_SPINLOCK(acpi_device_lock);
+LIST_HEAD(acpi_wakeup_device_list);
+
+static int
+acpi_bus_trim(struct acpi_device	*start,
+		int rmdevice);
+
+static void acpi_device_release(struct kobject * kobj)
+{
+	struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
+	if (dev->pnp.cid_list)
+		kfree(dev->pnp.cid_list);
+	kfree(dev);
+}
+
+struct acpi_device_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct acpi_device *, char *);
+	ssize_t (*store)(struct acpi_device *, const char *, size_t);
+};
+
+typedef void acpi_device_sysfs_files(struct kobject *,
+				const struct attribute *);
+
+static void setup_sys_fs_device_files(struct acpi_device *dev,
+		acpi_device_sysfs_files *func);
+
+#define create_sysfs_device_files(dev)	\
+	setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file)
+#define remove_sysfs_device_files(dev)	\
+	setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file)
+
+
+#define to_acpi_device(n) container_of(n, struct acpi_device, kobj)
+#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr);
+
+static ssize_t acpi_device_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	struct acpi_device *device = to_acpi_device(kobj);
+	struct acpi_device_attribute *attribute = to_handle_attr(attr);
+	return attribute->show ? attribute->show(device, buf) : 0;
+}
+static ssize_t acpi_device_attr_store(struct kobject *kobj,
+		struct attribute *attr, const char *buf, size_t len)
+{
+	struct acpi_device *device = to_acpi_device(kobj);
+	struct acpi_device_attribute *attribute = to_handle_attr(attr);
+	return attribute->store ? attribute->store(device, buf, len) : len;
+}
+
+static struct sysfs_ops acpi_device_sysfs_ops = {
+	.show	= acpi_device_attr_show,
+	.store	= acpi_device_attr_store,
+};
+
+static struct kobj_type ktype_acpi_ns = {
+	.sysfs_ops	= &acpi_device_sysfs_ops,
+	.release	= acpi_device_release,
+};
+
+static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
+			     char **envp, int num_envp, char *buffer,
+			     int buffer_size)
+{
+	struct acpi_device *dev = to_acpi_device(kobj);
+	int i = 0;
+	int len = 0;
+
+	if (!dev->driver)
+		return 0;
+
+	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
+				"PHYSDEVDRIVER=%s", dev->driver->name))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+static struct kset_hotplug_ops namespace_hotplug_ops = {
+	.hotplug = &namespace_hotplug,
+};
+
+static struct kset acpi_namespace_kset = {
+	.kobj		= { 
+		.name = "namespace",
+	},
+	.subsys = &acpi_subsys,
+	.ktype	= &ktype_acpi_ns,
+	.hotplug_ops = &namespace_hotplug_ops,
+};
+
+
+static void acpi_device_register(struct acpi_device * device, struct acpi_device * parent)
+{
+	/*
+	 * Linkage
+	 * -------
+	 * Link this device to its parent and siblings.
+	 */
+	INIT_LIST_HEAD(&device->children);
+	INIT_LIST_HEAD(&device->node);
+	INIT_LIST_HEAD(&device->g_list);
+	INIT_LIST_HEAD(&device->wakeup_list);
+
+	spin_lock(&acpi_device_lock);
+	if (device->parent) {
+		list_add_tail(&device->node, &device->parent->children);
+		list_add_tail(&device->g_list,&device->parent->g_list);
+	} else
+		list_add_tail(&device->g_list,&acpi_device_list);
+	if (device->wakeup.flags.valid)
+		list_add_tail(&device->wakeup_list,&acpi_wakeup_device_list);
+	spin_unlock(&acpi_device_lock);
+
+	strlcpy(device->kobj.name,device->pnp.bus_id,KOBJ_NAME_LEN);
+	if (parent)
+		device->kobj.parent = &parent->kobj;
+	device->kobj.ktype = &ktype_acpi_ns;
+	device->kobj.kset = &acpi_namespace_kset;
+	kobject_register(&device->kobj);
+	create_sysfs_device_files(device);
+}
+
+static int
+acpi_device_unregister (
+	struct acpi_device	*device, 
+	int			type)
+{
+	spin_lock(&acpi_device_lock);
+	if (device->parent) {
+		list_del(&device->node);
+		list_del(&device->g_list);
+	} else
+		list_del(&device->g_list);
+
+	list_del(&device->wakeup_list);
+
+	spin_unlock(&acpi_device_lock);
+
+	acpi_detach_data(device->handle, acpi_bus_data_handler);
+	remove_sysfs_device_files(device);
+	kobject_unregister(&device->kobj);
+	return 0;
+}
+
+void
+acpi_bus_data_handler (
+	acpi_handle		handle,
+	u32			function,
+	void			*context)
+{
+	ACPI_FUNCTION_TRACE("acpi_bus_data_handler");
+
+	/* TBD */
+
+	return_VOID;
+}
+
+static int
+acpi_bus_get_power_flags (
+	struct acpi_device	*device)
+{
+	acpi_status             status = 0;
+	acpi_handle		handle = NULL;
+	u32                     i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_get_power_flags");
+
+	/*
+	 * Power Management Flags
+	 */
+	status = acpi_get_handle(device->handle, "_PSC", &handle);
+	if (ACPI_SUCCESS(status))
+		device->power.flags.explicit_get = 1;
+	status = acpi_get_handle(device->handle, "_IRC", &handle);
+	if (ACPI_SUCCESS(status))
+		device->power.flags.inrush_current = 1;
+
+	/*
+	 * Enumerate supported power management states
+	 */
+	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
+		struct acpi_device_power_state *ps = &device->power.states[i];
+		char		object_name[5] = {'_','P','R','0'+i,'\0'};
+
+		/* Evaluate "_PRx" to se if power resources are referenced */
+		acpi_evaluate_reference(device->handle, object_name, NULL,
+			&ps->resources);
+		if (ps->resources.count) {
+			device->power.flags.power_resources = 1;
+			ps->flags.valid = 1;
+		}
+
+		/* Evaluate "_PSx" to see if we can do explicit sets */
+		object_name[2] = 'S';
+		status = acpi_get_handle(device->handle, object_name, &handle);
+		if (ACPI_SUCCESS(status)) {
+			ps->flags.explicit_set = 1;
+			ps->flags.valid = 1;
+		}
+
+		/* State is valid if we have some power control */
+		if (ps->resources.count || ps->flags.explicit_set)
+			ps->flags.valid = 1;
+
+		ps->power = -1;		/* Unknown - driver assigned */
+		ps->latency = -1;	/* Unknown - driver assigned */
+	}
+
+	/* Set defaults for D0 and D3 states (always valid) */
+	device->power.states[ACPI_STATE_D0].flags.valid = 1;
+	device->power.states[ACPI_STATE_D0].power = 100;
+	device->power.states[ACPI_STATE_D3].flags.valid = 1;
+	device->power.states[ACPI_STATE_D3].power = 0;
+
+	/* TBD: System wake support and resource requirements. */
+
+	device->power.state = ACPI_STATE_UNKNOWN;
+
+	return_VALUE(0);
+}
+
+int
+acpi_match_ids (
+	struct acpi_device	*device,
+	char			*ids)
+{
+	int error = 0;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+
+	if (device->flags.hardware_id)
+		if (strstr(ids, device->pnp.hardware_id))
+			goto Done;
+
+	if (device->flags.compatible_ids) {
+		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
+		int i;
+
+		/* compare multiple _CID entries against driver ids */
+		for (i = 0; i < cid_list->count; i++)
+		{
+			if (strstr(ids, cid_list->id[i].value))
+				goto Done;
+		}
+	}
+	error = -ENOENT;
+
+ Done:
+	if (buffer.pointer)
+		acpi_os_free(buffer.pointer);
+	return error;
+}
+
+static acpi_status
+acpi_bus_extract_wakeup_device_power_package (
+	struct acpi_device	*device,
+	union acpi_object	*package)
+{
+	int 	 i = 0;
+	union acpi_object	*element = NULL;
+
+	if (!device || !package || (package->package.count < 2))
+		return AE_BAD_PARAMETER;
+
+	element = &(package->package.elements[0]);
+	if (!element)
+		return AE_BAD_PARAMETER;
+	if (element->type == ACPI_TYPE_PACKAGE) {
+		if ((element->package.count < 2) ||
+			(element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) ||
+			(element->package.elements[1].type != ACPI_TYPE_INTEGER))
+			return AE_BAD_DATA;
+		device->wakeup.gpe_device = element->package.elements[0].reference.handle;
+		device->wakeup.gpe_number = (u32)element->package.elements[1].integer.value;
+	}else if (element->type == ACPI_TYPE_INTEGER) {
+		device->wakeup.gpe_number = element->integer.value;
+	}else
+		return AE_BAD_DATA;
+
+	element = &(package->package.elements[1]);
+	if (element->type != ACPI_TYPE_INTEGER) {
+		return AE_BAD_DATA;
+	}
+	device->wakeup.sleep_state = element->integer.value;
+
+	if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
+		return AE_NO_MEMORY;
+	}
+	device->wakeup.resources.count = package->package.count - 2;
+	for (i=0; i < device->wakeup.resources.count; i++) {
+		element = &(package->package.elements[i + 2]);
+		if (element->type != ACPI_TYPE_ANY ) {
+			return AE_BAD_DATA;
+		}
+
+		device->wakeup.resources.handles[i] = element->reference.handle;
+	}
+
+	return AE_OK;
+}
+
+static int
+acpi_bus_get_wakeup_device_flags (
+	struct acpi_device	*device)
+{
+	acpi_status	status = 0;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*package = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags");
+
+	/* _PRW */
+	status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRW\n"));
+		goto end;
+	}
+
+	package = (union acpi_object *) buffer.pointer;
+	status = acpi_bus_extract_wakeup_device_power_package(device, package);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _PRW package\n"));
+		goto end;
+	}
+
+	acpi_os_free(buffer.pointer);
+
+	device->wakeup.flags.valid = 1;
+	/* Power button, Lid switch always enable wakeup*/
+	if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
+		device->wakeup.flags.run_wake = 1;
+
+end:
+	if (ACPI_FAILURE(status))
+		device->flags.wake_capable = 0;
+	return_VALUE(0);
+}
+
+/* --------------------------------------------------------------------------
+		ACPI hotplug sysfs device file support
+   -------------------------------------------------------------------------- */
+static ssize_t acpi_eject_store(struct acpi_device *device, 
+		const char *buf, size_t count);
+
+#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
+static struct acpi_device_attribute acpi_device_attr_##_name = \
+		__ATTR(_name, _mode, _show, _store)
+
+ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
+
+/**
+ * setup_sys_fs_device_files - sets up the device files under device namespace
+ * @@dev:	acpi_device object
+ * @@func:	function pointer to create or destroy the device file
+ */
+static void
+setup_sys_fs_device_files (
+	struct acpi_device *dev,
+	acpi_device_sysfs_files *func)
+{
+	acpi_status		status;
+	acpi_handle		temp = NULL;
+
+	/*
+	 * If device has _EJ0, 'eject' file is created that is used to trigger
+	 * hot-removal function from userland.
+	 */
+	status = acpi_get_handle(dev->handle, "_EJ0", &temp);
+	if (ACPI_SUCCESS(status))
+		(*(func))(&dev->kobj,&acpi_device_attr_eject.attr);
+}
+
+static int
+acpi_eject_operation(acpi_handle handle, int lockable)
+{
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	acpi_status status = AE_OK;
+
+	/*
+	 * TBD: evaluate _PS3?
+	 */
+
+	if (lockable) {
+		arg_list.count = 1;
+		arg_list.pointer = &arg;
+		arg.type = ACPI_TYPE_INTEGER;
+		arg.integer.value = 0;
+		acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
+	}
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = 1;
+
+	/*
+	 * TBD: _EJD support.
+	 */
+
+	status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
+	if (ACPI_FAILURE(status)) {
+		return(-ENODEV);
+	}
+
+	return(0);
+}
+
+
+static ssize_t
+acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
+{
+	int	result;
+	int	ret = count;
+	int	islockable;
+	acpi_status	status;
+	acpi_handle	handle;
+	acpi_object_type	type = 0;
+
+	if ((!count) || (buf[0] != '1')) {
+		return -EINVAL;
+	}
+
+#ifndef FORCE_EJECT
+	if (device->driver == NULL) {
+		ret = -ENODEV;
+		goto err;
+	}
+#endif
+	status = acpi_get_type(device->handle, &type);
+	if (ACPI_FAILURE(status) || (!device->flags.ejectable) ) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	islockable = device->flags.lockable;
+	handle = device->handle;
+
+	if (type == ACPI_TYPE_PROCESSOR)
+		result = acpi_bus_trim(device, 0);
+	else
+		result = acpi_bus_trim(device, 1);
+
+	if (!result)
+		result = acpi_eject_operation(handle, islockable);
+
+	if (result) {
+		ret = -EBUSY;
+	}
+err:
+	return ret;
+}
+
+
+/* --------------------------------------------------------------------------
+                              Performance Management
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_bus_get_perf_flags (
+	struct acpi_device	*device)
+{
+	device->performance.state = ACPI_STATE_UNKNOWN;
+	return 0;
+}
+
+/* --------------------------------------------------------------------------
+                                 Driver Management
+   -------------------------------------------------------------------------- */
+
+static LIST_HEAD(acpi_bus_drivers);
+static DECLARE_MUTEX(acpi_bus_drivers_lock);
+
+
+/**
+ * acpi_bus_match 
+ * --------------
+ * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
+ * matches the specified driver's criteria.
+ */
+static int
+acpi_bus_match (
+	struct acpi_device	*device,
+	struct acpi_driver	*driver)
+{
+	if (driver && driver->ops.match)
+		return driver->ops.match(device, driver);
+	return acpi_match_ids(device, driver->ids);
+}
+
+
+/**
+ * acpi_bus_driver_init 
+ * --------------------
+ * Used to initialize a device via its device driver.  Called whenever a 
+ * driver is bound to a device.  Invokes the driver's add() and start() ops.
+ */
+static int
+acpi_bus_driver_init (
+	struct acpi_device	*device, 
+	struct acpi_driver	*driver)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_driver_init");
+
+	if (!device || !driver)
+		return_VALUE(-EINVAL);
+
+	if (!driver->ops.add)
+		return_VALUE(-ENOSYS);
+
+	result = driver->ops.add(device);
+	if (result) {
+		device->driver = NULL;
+		acpi_driver_data(device) = NULL;
+		return_VALUE(result);
+	}
+
+	device->driver = driver;
+
+	/*
+	 * TBD - Configuration Management: Assign resources to device based
+	 * upon possible configuration and currently allocated resources.
+	 */
+
+	if (driver->ops.start) {
+		result = driver->ops.start(device);
+		if (result && driver->ops.remove)
+			driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
+		return_VALUE(result);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
+
+	if (driver->ops.scan) {
+		driver->ops.scan(device);
+	}
+
+	return_VALUE(0);
+}
+
+static int acpi_driver_attach(struct acpi_driver * drv)
+{
+	struct list_head * node, * next;
+	int count = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_driver_attach");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_device_list) {
+		struct acpi_device * dev = container_of(node, struct acpi_device, g_list);
+
+		if (dev->driver || !dev->status.present)
+			continue;
+		spin_unlock(&acpi_device_lock);
+
+		if (!acpi_bus_match(dev, drv)) {
+			if (!acpi_bus_driver_init(dev, drv)) {
+				atomic_inc(&drv->references);
+				count++;
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
+						  drv->name, dev->pnp.bus_id));
+			}
+		}
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+	return_VALUE(count);
+}
+
+static int acpi_driver_detach(struct acpi_driver * drv)
+{
+	struct list_head * node, * next;
+
+	ACPI_FUNCTION_TRACE("acpi_driver_detach");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node,next,&acpi_device_list) {
+		struct acpi_device * dev = container_of(node,struct acpi_device,g_list);
+
+		if (dev->driver == drv) {
+			spin_unlock(&acpi_device_lock);
+			if (drv->ops.remove)
+				drv->ops.remove(dev,ACPI_BUS_REMOVAL_NORMAL);
+			spin_lock(&acpi_device_lock);
+			dev->driver = NULL;
+			dev->driver_data = NULL;
+			atomic_dec(&drv->references);
+		}
+	}
+	spin_unlock(&acpi_device_lock);
+	return_VALUE(0);
+}
+
+/**
+ * acpi_bus_register_driver 
+ * ------------------------ 
+ * Registers a driver with the ACPI bus.  Searches the namespace for all
+ * devices that match the driver's criteria and binds.  Returns the
+ * number of devices that were claimed by the driver, or a negative
+ * error status for failure.
+ */
+int
+acpi_bus_register_driver (
+	struct acpi_driver	*driver)
+{
+	int count;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_register_driver");
+
+	if (acpi_disabled)
+		return_VALUE(-ENODEV);
+
+	if (!driver)
+		return_VALUE(-EINVAL);
+
+	spin_lock(&acpi_device_lock);
+	list_add_tail(&driver->node, &acpi_bus_drivers);
+	spin_unlock(&acpi_device_lock);
+	count = acpi_driver_attach(driver);
+
+	return_VALUE(count);
+}
+EXPORT_SYMBOL(acpi_bus_register_driver);
+
+
+/**
+ * acpi_bus_unregister_driver 
+ * --------------------------
+ * Unregisters a driver with the ACPI bus.  Searches the namespace for all
+ * devices that match the driver's criteria and unbinds.
+ */
+int
+acpi_bus_unregister_driver (
+	struct acpi_driver	*driver)
+{
+	int error = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_unregister_driver");
+
+	if (driver) {
+		acpi_driver_detach(driver);
+
+		if (!atomic_read(&driver->references)) {
+			spin_lock(&acpi_device_lock);
+			list_del_init(&driver->node);
+			spin_unlock(&acpi_device_lock);
+		} 
+	} else 
+		error = -EINVAL;
+	return_VALUE(error);
+}
+EXPORT_SYMBOL(acpi_bus_unregister_driver);
+
+/**
+ * acpi_bus_find_driver 
+ * --------------------
+ * Parses the list of registered drivers looking for a driver applicable for
+ * the specified device.
+ */
+static int
+acpi_bus_find_driver (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	struct list_head	* node, *next;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_find_driver");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node,next,&acpi_bus_drivers) {
+		struct acpi_driver * driver = container_of(node,struct acpi_driver,node);
+
+		atomic_inc(&driver->references);
+		spin_unlock(&acpi_device_lock);
+		if (!acpi_bus_match(device, driver)) {
+			result = acpi_bus_driver_init(device, driver);
+			if (!result)
+				goto Done;
+		}
+		atomic_dec(&driver->references);
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+
+ Done:
+	return_VALUE(result);
+}
+
+
+/* --------------------------------------------------------------------------
+                                 Device Enumeration
+   -------------------------------------------------------------------------- */
+
+static int 
+acpi_bus_get_flags (
+	struct acpi_device	*device)
+{
+	acpi_status		status = AE_OK;
+	acpi_handle		temp = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_get_flags");
+
+	/* Presence of _STA indicates 'dynamic_status' */
+	status = acpi_get_handle(device->handle, "_STA", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.dynamic_status = 1;
+
+	/* Presence of _CID indicates 'compatible_ids' */
+	status = acpi_get_handle(device->handle, "_CID", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.compatible_ids = 1;
+
+	/* Presence of _RMV indicates 'removable' */
+	status = acpi_get_handle(device->handle, "_RMV", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.removable = 1;
+
+	/* Presence of _EJD|_EJ0 indicates 'ejectable' */
+	status = acpi_get_handle(device->handle, "_EJD", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.ejectable = 1;
+	else {
+		status = acpi_get_handle(device->handle, "_EJ0", &temp);
+		if (ACPI_SUCCESS(status))
+			device->flags.ejectable = 1;
+	}
+
+	/* Presence of _LCK indicates 'lockable' */
+	status = acpi_get_handle(device->handle, "_LCK", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.lockable = 1;
+
+	/* Presence of _PS0|_PR0 indicates 'power manageable' */
+	status = acpi_get_handle(device->handle, "_PS0", &temp);
+	if (ACPI_FAILURE(status))
+		status = acpi_get_handle(device->handle, "_PR0", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.power_manageable = 1;
+
+	/* Presence of _PRW indicates wake capable */
+	status = acpi_get_handle(device->handle, "_PRW", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.wake_capable = 1;
+
+	/* TBD: Peformance management */
+
+	return_VALUE(0);
+}
+
+static void acpi_device_get_busid(struct acpi_device * device, acpi_handle handle, int type)
+{
+	char			bus_id[5] = {'?',0};
+	struct acpi_buffer	buffer = {sizeof(bus_id), bus_id};
+	int			i = 0;
+
+	/*
+	 * Bus ID
+	 * ------
+	 * The device's Bus ID is simply the object name.
+	 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
+	 */
+	switch (type) {
+	case ACPI_BUS_TYPE_SYSTEM:
+		strcpy(device->pnp.bus_id, "ACPI");
+		break;
+	case ACPI_BUS_TYPE_POWER_BUTTON:
+		strcpy(device->pnp.bus_id, "PWRF");
+		break;
+	case ACPI_BUS_TYPE_SLEEP_BUTTON:
+		strcpy(device->pnp.bus_id, "SLPF");
+		break;
+	default:
+		acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
+		/* Clean up trailing underscores (if any) */
+		for (i = 3; i > 1; i--) {
+			if (bus_id[i] == '_')
+				bus_id[i] = '\0';
+			else
+				break;
+		}
+		strcpy(device->pnp.bus_id, bus_id);
+		break;
+	}
+}
+
+static void acpi_device_set_id(struct acpi_device * device, struct acpi_device * parent,
+			       acpi_handle handle, int type)
+{
+	struct acpi_device_info	*info;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	char			*hid = NULL;
+	char			*uid = NULL;
+	struct acpi_compatible_id_list *cid_list = NULL;
+	acpi_status		status;
+
+	switch (type) {
+	case ACPI_BUS_TYPE_DEVICE:
+		status = acpi_get_object_info(handle, &buffer);
+		if (ACPI_FAILURE(status)) {
+			printk("%s: Error reading device info\n",__FUNCTION__);
+			return;
+		}
+
+		info = buffer.pointer;
+		if (info->valid & ACPI_VALID_HID)
+			hid = info->hardware_id.value;
+		if (info->valid & ACPI_VALID_UID)
+			uid = info->unique_id.value;
+		if (info->valid & ACPI_VALID_CID)
+			cid_list = &info->compatibility_id;
+		if (info->valid & ACPI_VALID_ADR) {
+			device->pnp.bus_address = info->address;
+			device->flags.bus_address = 1;
+		}
+		break;
+	case ACPI_BUS_TYPE_POWER:
+		hid = ACPI_POWER_HID;
+		break;
+	case ACPI_BUS_TYPE_PROCESSOR:
+		hid = ACPI_PROCESSOR_HID;
+		break;
+	case ACPI_BUS_TYPE_SYSTEM:
+		hid = ACPI_SYSTEM_HID;
+		break;
+	case ACPI_BUS_TYPE_THERMAL:
+		hid = ACPI_THERMAL_HID;
+		break;
+	case ACPI_BUS_TYPE_POWER_BUTTON:
+		hid = ACPI_BUTTON_HID_POWERF;
+		break;
+	case ACPI_BUS_TYPE_SLEEP_BUTTON:
+		hid = ACPI_BUTTON_HID_SLEEPF;
+		break;
+	}
+
+	/* 
+	 * \_SB
+	 * ----
+	 * Fix for the system root bus device -- the only root-level device.
+	 */
+	if ((parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
+		hid = ACPI_BUS_HID;
+		strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
+		strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
+	}
+
+	if (hid) {
+		strcpy(device->pnp.hardware_id, hid);
+		device->flags.hardware_id = 1;
+	}
+	if (uid) {
+		strcpy(device->pnp.unique_id, uid);
+		device->flags.unique_id = 1;
+	}
+	if (cid_list) {
+		device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL);
+		if (device->pnp.cid_list)
+			memcpy(device->pnp.cid_list, cid_list, cid_list->size);
+		else
+			printk(KERN_ERR "Memory allocation error\n");
+	}
+
+	acpi_os_free(buffer.pointer);
+}
+
+static int acpi_device_set_context(struct acpi_device * device, int type)
+{
+	acpi_status status = AE_OK;
+	int result = 0;
+	/*
+	 * Context
+	 * -------
+	 * Attach this 'struct acpi_device' to the ACPI object.  This makes
+	 * resolutions from handle->device very efficient.  Note that we need
+	 * to be careful with fixed-feature devices as they all attach to the
+	 * root object.
+	 */
+	if (type != ACPI_BUS_TYPE_POWER_BUTTON && 
+	    type != ACPI_BUS_TYPE_SLEEP_BUTTON) {
+		status = acpi_attach_data(device->handle,
+			acpi_bus_data_handler, device);
+
+		if (ACPI_FAILURE(status)) {
+			printk("Error attaching device data\n");
+			result = -ENODEV;
+		}
+	}
+	return result;
+}
+
+static void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
+{
+#ifdef CONFIG_ACPI_DEBUG_OUTPUT
+	char		*type_string = NULL;
+	char		name[80] = {'?','\0'};
+	struct acpi_buffer	buffer = {sizeof(name), name};
+
+	switch (type) {
+	case ACPI_BUS_TYPE_DEVICE:
+		type_string = "Device";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+		break;
+	case ACPI_BUS_TYPE_POWER:
+		type_string = "Power Resource";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+		break;
+	case ACPI_BUS_TYPE_PROCESSOR:
+		type_string = "Processor";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+		break;
+	case ACPI_BUS_TYPE_SYSTEM:
+		type_string = "System";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+		break;
+	case ACPI_BUS_TYPE_THERMAL:
+		type_string = "Thermal Zone";
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+		break;
+	case ACPI_BUS_TYPE_POWER_BUTTON:
+		type_string = "Power Button";
+		sprintf(name, "PWRB");
+		break;
+	case ACPI_BUS_TYPE_SLEEP_BUTTON:
+		type_string = "Sleep Button";
+		sprintf(name, "SLPB");
+		break;
+	}
+
+	printk(KERN_DEBUG "Found %s %s [%p]\n", type_string, name, handle);
+#endif /*CONFIG_ACPI_DEBUG_OUTPUT*/
+}
+
+
+static int
+acpi_bus_remove (
+	struct acpi_device *dev,
+	int rmdevice)
+{
+	int 			result = 0;
+	struct acpi_driver	*driver;
+	
+	ACPI_FUNCTION_TRACE("acpi_bus_remove");
+
+	if (!dev)
+		return_VALUE(-EINVAL);
+
+	driver = dev->driver;
+
+	if ((driver) && (driver->ops.remove)) {
+
+		if (driver->ops.stop) {
+			result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
+			if (result)
+				return_VALUE(result);
+		}
+
+		result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
+		if (result) {
+			return_VALUE(result);
+		}
+
+		atomic_dec(&dev->driver->references);
+		dev->driver = NULL;
+		acpi_driver_data(dev) = NULL;
+	}
+
+	if (!rmdevice)
+		return_VALUE(0);
+
+	if (dev->flags.bus_address) {
+		if ((dev->parent) && (dev->parent->ops.unbind))
+			dev->parent->ops.unbind(dev);
+	}
+	
+	acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
+
+	return_VALUE(0);
+}
+
+
+int
+acpi_bus_add (
+	struct acpi_device	**child,
+	struct acpi_device	*parent,
+	acpi_handle		handle,
+	int			type)
+{
+	int			result = 0;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_add");
+
+	if (!child)
+		return_VALUE(-EINVAL);
+
+	device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL);
+	if (!device) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n"));
+		return_VALUE(-ENOMEM);
+	}
+	memset(device, 0, sizeof(struct acpi_device));
+
+	device->handle = handle;
+	device->parent = parent;
+
+	acpi_device_get_busid(device,handle,type);
+
+	/*
+	 * Flags
+	 * -----
+	 * Get prior to calling acpi_bus_get_status() so we know whether
+	 * or not _STA is present.  Note that we only look for object
+	 * handles -- cannot evaluate objects until we know the device is
+	 * present and properly initialized.
+	 */
+	result = acpi_bus_get_flags(device);
+	if (result)
+		goto end;
+
+	/*
+	 * Status
+	 * ------
+	 * See if the device is present.  We always assume that non-Device()
+	 * objects (e.g. thermal zones, power resources, processors, etc.) are
+	 * present, functioning, etc. (at least when parent object is present).
+	 * Note that _STA has a different meaning for some objects (e.g.
+	 * power resources) so we need to be careful how we use it.
+	 */
+	switch (type) {
+	case ACPI_BUS_TYPE_DEVICE:
+		result = acpi_bus_get_status(device);
+		if (ACPI_FAILURE(result) || !device->status.present) {
+			result = -ENOENT;
+			goto end;
+		}
+		break;
+	default:
+		STRUCT_TO_INT(device->status) = 0x0F;
+		break;
+	}
+
+	/*
+	 * Initialize Device
+	 * -----------------
+	 * TBD: Synch with Core's enumeration/initialization process.
+	 */
+
+	/*
+	 * Hardware ID, Unique ID, & Bus Address
+	 * -------------------------------------
+	 */
+	acpi_device_set_id(device,parent,handle,type);
+
+	/*
+	 * Power Management
+	 * ----------------
+	 */
+	if (device->flags.power_manageable) {
+		result = acpi_bus_get_power_flags(device);
+		if (result)
+			goto end;
+	}
+
+ 	/*
+	 * Wakeup device management
+	 *-----------------------
+	 */
+	if (device->flags.wake_capable) {
+		result = acpi_bus_get_wakeup_device_flags(device);
+		if (result)
+			goto end;
+	}
+
+	/*
+	 * Performance Management
+	 * ----------------------
+	 */
+	if (device->flags.performance_manageable) {
+		result = acpi_bus_get_perf_flags(device);
+		if (result)
+			goto end;
+	}
+
+	if ((result = acpi_device_set_context(device,type)))
+		goto end;
+
+	acpi_device_get_debug_info(device,handle,type);
+
+	acpi_device_register(device,parent);
+
+	/*
+	 * Bind _ADR-Based Devices
+	 * -----------------------
+	 * If there's a a bus address (_ADR) then we utilize the parent's 
+	 * 'bind' function (if exists) to bind the ACPI- and natively-
+	 * enumerated device representations.
+	 */
+	if (device->flags.bus_address) {
+		if (device->parent && device->parent->ops.bind)
+			device->parent->ops.bind(device);
+	}
+
+	/*
+	 * Locate & Attach Driver
+	 * ----------------------
+	 * If there's a hardware id (_HID) or compatible ids (_CID) we check
+	 * to see if there's a driver installed for this kind of device.  Note
+	 * that drivers can install before or after a device is enumerated.
+	 *
+	 * TBD: Assumes LDM provides driver hot-plug capability.
+	 */
+	acpi_bus_find_driver(device);
+
+end:
+	if (!result)
+		*child = device;
+	else {
+		if (device->pnp.cid_list)
+			kfree(device->pnp.cid_list);
+		kfree(device);
+	}
+
+	return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_add);
+
+
+int acpi_bus_scan (struct acpi_device	*start)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_device	*parent = NULL;
+	struct acpi_device	*child = NULL;
+	acpi_handle		phandle = NULL;
+	acpi_handle		chandle = NULL;
+	acpi_object_type	type = 0;
+	u32			level = 1;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_scan");
+
+	if (!start)
+		return_VALUE(-EINVAL);
+
+	parent = start;
+	phandle = start->handle;
+	
+	/*
+	 * Parse through the ACPI namespace, identify all 'devices', and
+	 * create a new 'struct acpi_device' for each.
+	 */
+	while ((level > 0) && parent) {
+
+		status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
+			chandle, &chandle);
+
+		/*
+		 * If this scope is exhausted then move our way back up.
+		 */
+		if (ACPI_FAILURE(status)) {
+			level--;
+			chandle = phandle;
+			acpi_get_parent(phandle, &phandle);
+			if (parent->parent)
+				parent = parent->parent;
+			continue;
+		}
+
+		status = acpi_get_type(chandle, &type);
+		if (ACPI_FAILURE(status))
+			continue;
+
+		/*
+		 * If this is a scope object then parse it (depth-first).
+		 */
+		if (type == ACPI_TYPE_LOCAL_SCOPE) {
+			level++;
+			phandle = chandle;
+			chandle = NULL;
+			continue;
+		}
+
+		/*
+		 * We're only interested in objects that we consider 'devices'.
+		 */
+		switch (type) {
+		case ACPI_TYPE_DEVICE:
+			type = ACPI_BUS_TYPE_DEVICE;
+			break;
+		case ACPI_TYPE_PROCESSOR:
+			type = ACPI_BUS_TYPE_PROCESSOR;
+			break;
+		case ACPI_TYPE_THERMAL:
+			type = ACPI_BUS_TYPE_THERMAL;
+			break;
+		case ACPI_TYPE_POWER:
+			type = ACPI_BUS_TYPE_POWER;
+			break;
+		default:
+			continue;
+		}
+
+		status = acpi_bus_add(&child, parent, chandle, type);
+		if (ACPI_FAILURE(status))
+			continue;
+
+		/*
+		 * If the device is present, enabled, and functioning then
+		 * parse its scope (depth-first).  Note that we need to
+		 * represent absent devices to facilitate PnP notifications
+		 * -- but only the subtree head (not all of its children,
+		 * which will be enumerated when the parent is inserted).
+		 *
+		 * TBD: Need notifications and other detection mechanisms
+		 *	in place before we can fully implement this.
+		 */
+		if (child->status.present) {
+			status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
+						      NULL, NULL);
+			if (ACPI_SUCCESS(status)) {
+				level++;
+				phandle = chandle;
+				chandle = NULL;
+				parent = child;
+			}
+		}
+	}
+
+	return_VALUE(0);
+}
+EXPORT_SYMBOL(acpi_bus_scan);
+
+
+static int
+acpi_bus_trim(struct acpi_device	*start,
+		int rmdevice)
+{
+	acpi_status		status;
+	struct acpi_device	*parent, *child;
+	acpi_handle		phandle, chandle;
+	acpi_object_type	type;
+	u32			level = 1;
+	int			err = 0;
+
+	parent  = start;
+	phandle = start->handle;
+	child = chandle = NULL;
+
+	while ((level > 0) && parent && (!err)) {
+		status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
+			chandle, &chandle);
+
+		/*
+		 * If this scope is exhausted then move our way back up.
+		 */
+		if (ACPI_FAILURE(status)) {
+			level--;
+			chandle = phandle;
+			acpi_get_parent(phandle, &phandle);
+			child = parent;
+			parent = parent->parent;
+
+			if (level == 0)
+				err = acpi_bus_remove(child, rmdevice);
+			else
+				err = acpi_bus_remove(child, 1);
+
+			continue;
+		}
+
+		status = acpi_get_type(chandle, &type);
+		if (ACPI_FAILURE(status)) {
+			continue;
+		}
+		/*
+		 * If there is a device corresponding to chandle then
+		 * parse it (depth-first).
+		 */
+		if (acpi_bus_get_device(chandle, &child) == 0) {
+			level++;
+			phandle = chandle;
+			chandle = NULL;
+			parent = child;
+		}
+		continue;
+	}
+	return err;
+}
+
+static int
+acpi_bus_scan_fixed (
+	struct acpi_device	*root)
+{
+	int			result = 0;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_scan_fixed");
+
+	if (!root)
+		return_VALUE(-ENODEV);
+
+	/*
+	 * Enumerate all fixed-feature devices.
+	 */
+	if (acpi_fadt.pwr_button == 0)
+		result = acpi_bus_add(&device, acpi_root, 
+			NULL, ACPI_BUS_TYPE_POWER_BUTTON);
+
+	if (acpi_fadt.sleep_button == 0)
+		result = acpi_bus_add(&device, acpi_root, 
+			NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
+
+	return_VALUE(result);
+}
+
+
+static int __init acpi_scan_init(void)
+{
+	int result;
+
+	ACPI_FUNCTION_TRACE("acpi_scan_init");
+
+	if (acpi_disabled)
+		return_VALUE(0);
+
+	kset_register(&acpi_namespace_kset);
+
+	/*
+	 * Create the root device in the bus's device tree
+	 */
+	result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 
+		ACPI_BUS_TYPE_SYSTEM);
+	if (result)
+		goto Done;
+
+	/*
+	 * Enumerate devices in the ACPI namespace.
+	 */
+	result = acpi_bus_scan_fixed(acpi_root);
+	if (!result) 
+		result = acpi_bus_scan(acpi_root);
+
+	if (result)
+		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
+
+ Done:
+	return_VALUE(result);
+}
+
+subsys_initcall(acpi_scan_init);
diff --git a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile
new file mode 100644
index 0000000..d6c0177
--- /dev/null
+++ b/drivers/acpi/sleep/Makefile
@@ -0,0 +1,5 @@
+obj-y					:= poweroff.o wakeup.o
+obj-$(CONFIG_ACPI_SLEEP)		+= main.o
+obj-$(CONFIG_ACPI_SLEEP_PROC_FS)	+= proc.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
new file mode 100644
index 0000000..0a5d2a9
--- /dev/null
+++ b/drivers/acpi/sleep/main.c
@@ -0,0 +1,234 @@
+/*
+ * sleep.c - ACPI sleep support.
+ *
+ * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (c) 2000-2003 Patrick Mochel
+ * Copyright (c) 2003 Open Source Development Lab
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/dmi.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <asm/io.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include "sleep.h"
+
+u8 sleep_states[ACPI_S_STATE_COUNT];
+
+static struct pm_ops acpi_pm_ops;
+
+extern void do_suspend_lowlevel_s4bios(void);
+extern void do_suspend_lowlevel(void);
+
+static u32 acpi_suspend_states[] = {
+	[PM_SUSPEND_ON]		= ACPI_STATE_S0,
+	[PM_SUSPEND_STANDBY]	= ACPI_STATE_S1,
+	[PM_SUSPEND_MEM]	= ACPI_STATE_S3,
+	[PM_SUSPEND_DISK]	= ACPI_STATE_S4,
+};
+
+static int init_8259A_after_S1;
+
+/**
+ *	acpi_pm_prepare - Do preliminary suspend work.
+ *	@pm_state:		suspend state we're entering.
+ *
+ *	Make sure we support the state. If we do, and we need it, set the
+ *	firmware waking vector and do arch-specific nastiness to get the 
+ *	wakeup code to the waking vector. 
+ */
+
+static int acpi_pm_prepare(suspend_state_t pm_state)
+{
+	u32 acpi_state = acpi_suspend_states[pm_state];
+
+	if (!sleep_states[acpi_state])
+		return -EPERM;
+
+	/* do we have a wakeup address for S2 and S3? */
+	/* Here, we support only S4BIOS, those we set the wakeup address */
+	/* S4OS is only supported for now via swsusp.. */
+	if (pm_state == PM_SUSPEND_MEM || pm_state == PM_SUSPEND_DISK) {
+		if (!acpi_wakeup_address)
+			return -EFAULT;
+		acpi_set_firmware_waking_vector(
+			(acpi_physical_address) virt_to_phys(
+				(void *)acpi_wakeup_address));
+	}
+	ACPI_FLUSH_CPU_CACHE();
+	acpi_enable_wakeup_device_prep(acpi_state);
+	acpi_enter_sleep_state_prep(acpi_state);
+	return 0;
+}
+
+
+/**
+ *	acpi_pm_enter - Actually enter a sleep state.
+ *	@pm_state:		State we're entering.
+ *
+ *	Flush caches and go to sleep. For STR or STD, we have to call 
+ *	arch-specific assembly, which in turn call acpi_enter_sleep_state().
+ *	It's unfortunate, but it works. Please fix if you're feeling frisky.
+ */
+
+static int acpi_pm_enter(suspend_state_t pm_state)
+{
+	acpi_status status = AE_OK;
+	unsigned long flags = 0;
+	u32 acpi_state = acpi_suspend_states[pm_state];
+
+	ACPI_FLUSH_CPU_CACHE();
+
+	/* Do arch specific saving of state. */
+	if (pm_state > PM_SUSPEND_STANDBY) {
+		int error = acpi_save_state_mem();
+		if (error)
+			return error;
+	}
+
+
+	local_irq_save(flags);
+	acpi_enable_wakeup_device(acpi_state);
+	switch (pm_state)
+	{
+	case PM_SUSPEND_STANDBY:
+		barrier();
+		status = acpi_enter_sleep_state(acpi_state);
+		break;
+
+	case PM_SUSPEND_MEM:
+		do_suspend_lowlevel();
+		break;
+
+	case PM_SUSPEND_DISK:
+		if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM)
+			status = acpi_enter_sleep_state(acpi_state);
+		else
+			do_suspend_lowlevel_s4bios();
+		break;
+	default:
+		return -EINVAL;
+	}
+	local_irq_restore(flags);
+	printk(KERN_DEBUG "Back to C!\n");
+
+	/* restore processor state
+	 * We should only be here if we're coming back from STR or STD.
+	 * And, in the case of the latter, the memory image should have already
+	 * been loaded from disk.
+	 */
+	if (pm_state > PM_SUSPEND_STANDBY)
+		acpi_restore_state_mem();
+
+
+	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
+}
+
+
+/**
+ *	acpi_pm_finish - Finish up suspend sequence.
+ *	@pm_state:		State we're coming out of.
+ *
+ *	This is called after we wake back up (or if entering the sleep state
+ *	failed). 
+ */
+
+static int acpi_pm_finish(suspend_state_t pm_state)
+{
+	u32 acpi_state = acpi_suspend_states[pm_state];
+
+	acpi_leave_sleep_state(acpi_state);
+	acpi_disable_wakeup_device(acpi_state);
+
+	/* reset firmware waking vector */
+	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+
+	if (init_8259A_after_S1) {
+		printk("Broken toshiba laptop -> kicking interrupts\n");
+		init_8259A(0);
+	}
+	return 0;
+}
+
+
+int acpi_suspend(u32 acpi_state)
+{
+	suspend_state_t states[] = {
+		[1]	= PM_SUSPEND_STANDBY,
+		[3]	= PM_SUSPEND_MEM,
+		[4]	= PM_SUSPEND_DISK,
+	};
+
+	if (acpi_state <= 4 && states[acpi_state])
+		return pm_suspend(states[acpi_state]);
+	return -EINVAL;
+}
+
+static struct pm_ops acpi_pm_ops = {
+	.prepare	= acpi_pm_prepare,
+	.enter		= acpi_pm_enter,
+	.finish		= acpi_pm_finish,
+};
+
+
+/*
+ * Toshiba fails to preserve interrupts over S1, reinitialization
+ * of 8259 is needed after S1 resume.
+ */
+static int __init init_ints_after_s1(struct dmi_system_id *d)
+{
+	printk(KERN_WARNING "%s with broken S1 detected.\n", d->ident);
+	init_8259A_after_S1 = 1;
+	return 0;
+}
+
+static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
+	{
+		.callback = init_ints_after_s1,
+		.ident = "Toshiba Satellite 4030cdt",
+		.matches = { DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), },
+	},
+	{ },
+};
+
+static int __init acpi_sleep_init(void)
+{
+	int			i = 0;
+
+	dmi_check_system(acpisleep_dmi_table);
+
+	if (acpi_disabled)
+		return 0;
+
+	printk(KERN_INFO PREFIX "(supports");
+	for (i=0; i < ACPI_S_STATE_COUNT; i++) {
+		acpi_status status;
+		u8 type_a, type_b;
+		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
+		if (ACPI_SUCCESS(status)) {
+			sleep_states[i] = 1;
+			printk(" S%d", i);
+		}
+		if (i == ACPI_STATE_S4) {
+			if (acpi_gbl_FACS->S4bios_f) {
+				sleep_states[i] = 1;
+				printk(" S4bios");
+				acpi_pm_ops.pm_disk_mode = PM_DISK_FIRMWARE;
+			}
+			if (sleep_states[i])
+				acpi_pm_ops.pm_disk_mode = PM_DISK_PLATFORM;
+		}
+	}
+	printk(")\n");
+
+	pm_set_ops(&acpi_pm_ops);
+	return 0;
+}
+
+late_initcall(acpi_sleep_init);
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
new file mode 100644
index 0000000..da23775
--- /dev/null
+++ b/drivers/acpi/sleep/poweroff.c
@@ -0,0 +1,39 @@
+/*
+ * poweroff.c - ACPI handler for powering off the system.
+ *
+ * AKA S5, but it is independent of whether or not the kernel supports
+ * any other sleep support in the system.
+ */
+
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <acpi/acpi_bus.h>
+#include <linux/sched.h>
+#include "sleep.h"
+
+static void
+acpi_power_off (void)
+{
+	printk("%s called\n",__FUNCTION__);
+	/* Some SMP machines only can poweroff in boot CPU */
+	set_cpus_allowed(current, cpumask_of_cpu(0));
+	acpi_wakeup_gpe_poweroff_prepare();
+	acpi_enter_sleep_state_prep(ACPI_STATE_S5);
+	ACPI_DISABLE_IRQS();
+	acpi_enter_sleep_state(ACPI_STATE_S5);
+}
+
+static int acpi_poweroff_init(void)
+{
+	if (!acpi_disabled) {
+		u8 type_a, type_b;
+		acpi_status status;
+
+		status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
+		if (ACPI_SUCCESS(status))
+			pm_power_off = acpi_power_off;
+	}
+	return 0;
+}
+
+late_initcall(acpi_poweroff_init);
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
new file mode 100644
index 0000000..fd7c5a0
--- /dev/null
+++ b/drivers/acpi/sleep/proc.c
@@ -0,0 +1,509 @@
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/suspend.h>
+#include <linux/bcd.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#ifdef CONFIG_X86
+#include <linux/mc146818rtc.h>
+#endif
+
+#include "sleep.h"
+
+#define ACPI_SYSTEM_FILE_SLEEP		"sleep"
+#define ACPI_SYSTEM_FILE_ALARM		"alarm"
+#define ACPI_SYSTEM_FILE_WAKEUP_DEVICE   "wakeup"
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("sleep")
+
+
+static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
+{
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
+
+	for (i = 0; i <= ACPI_STATE_S5; i++) {
+		if (sleep_states[i]) {
+			seq_printf(seq,"S%d ", i);
+			if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
+				seq_printf(seq, "S4bios ");
+		}
+	}
+
+	seq_puts(seq, "\n");
+
+	return 0;
+}
+
+static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
+}
+
+static ssize_t
+acpi_system_write_sleep (
+	struct file		*file,
+	const char __user	*buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	char	str[12];
+	u32	state = 0;
+	int	error = 0;
+
+	if (count > sizeof(str) - 1)
+		goto Done;
+	memset(str,0,sizeof(str));
+	if (copy_from_user(str, buffer, count))
+		return -EFAULT;
+
+	/* Check for S4 bios request */
+	if (!strcmp(str,"4b")) {
+		error = acpi_suspend(4);
+		goto Done;
+	}
+	state = simple_strtoul(str, NULL, 0);
+#ifdef CONFIG_SOFTWARE_SUSPEND
+	if (state == 4) {
+		error = software_suspend();
+		goto Done;
+	}
+#endif
+	error = acpi_suspend(state);
+ Done:
+	return error ? error : count;
+}
+
+static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
+{
+	u32			sec, min, hr;
+	u32			day, mo, yr;
+	unsigned char		rtc_control = 0;
+	unsigned long 		flags;
+
+	ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show");
+
+	spin_lock_irqsave(&rtc_lock, flags);
+
+	sec = CMOS_READ(RTC_SECONDS_ALARM);
+	min = CMOS_READ(RTC_MINUTES_ALARM);
+	hr = CMOS_READ(RTC_HOURS_ALARM);
+	rtc_control = CMOS_READ(RTC_CONTROL);
+
+	/* If we ever get an FACP with proper values... */
+	if (acpi_gbl_FADT->day_alrm)
+		/* ACPI spec: only low 6 its should be cared */
+		day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F;
+	else
+		day =  CMOS_READ(RTC_DAY_OF_MONTH);
+	if (acpi_gbl_FADT->mon_alrm)
+		mo = CMOS_READ(acpi_gbl_FADT->mon_alrm);
+	else
+		mo = CMOS_READ(RTC_MONTH);
+	if (acpi_gbl_FADT->century)
+		yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);
+	else
+		yr = CMOS_READ(RTC_YEAR);
+
+	spin_unlock_irqrestore(&rtc_lock, flags);
+
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hr);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mo);
+		BCD_TO_BIN(yr);
+	}
+
+	/* we're trusting the FADT (see above)*/
+	if (!acpi_gbl_FADT->century)
+	/* If we're not trusting the FADT, we should at least make it
+	 * right for _this_ century... ehm, what is _this_ century?
+	 *
+	 * TBD:
+	 *  ASAP: find piece of code in the kernel, e.g. star tracker driver,
+	 *        which we can trust to determine the century correctly. Atom
+	 *        watch driver would be nice, too...
+	 *
+	 *  if that has not happened, change for first release in 2050:
+ 	 *        if (yr<50)
+	 *                yr += 2100;
+	 *        else
+	 *                yr += 2000;   // current line of code
+	 *
+	 *  if that has not happened either, please do on 2099/12/31:23:59:59
+	 *        s/2000/2100
+	 *
+	 */
+		yr += 2000;
+
+	seq_printf(seq,"%4.4u-", yr);
+	(mo > 12)  ? seq_puts(seq, "**-")  : seq_printf(seq, "%2.2u-", mo);
+	(day > 31) ? seq_puts(seq, "** ")  : seq_printf(seq, "%2.2u ", day);
+	(hr > 23)  ? seq_puts(seq, "**:")  : seq_printf(seq, "%2.2u:", hr);
+	(min > 59) ? seq_puts(seq, "**:")  : seq_printf(seq, "%2.2u:", min);
+	(sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec);
+
+	return 0;
+}
+
+static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data);
+}
+
+
+static int
+get_date_field (
+	char			**p,
+	u32			*value)
+{
+	char			*next = NULL;
+	char			*string_end = NULL;
+	int			result = -EINVAL;
+
+	/*
+	 * Try to find delimeter, only to insert null.  The end of the
+	 * string won't have one, but is still valid.
+	 */
+	next = strpbrk(*p, "- :");
+	if (next)
+		*next++ = '\0';
+
+	*value = simple_strtoul(*p, &string_end, 10);
+
+	/* Signal success if we got a good digit */
+	if (string_end != *p)
+		result = 0;
+
+	if (next)
+		*p = next;
+
+	return result;
+}
+
+
+static ssize_t
+acpi_system_write_alarm (
+	struct file		*file,
+	const char __user	*buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	int			result = 0;
+	char			alarm_string[30] = {'\0'};
+	char			*p = alarm_string;
+	u32			sec, min, hr, day, mo, yr;
+	int			adjust = 0;
+	unsigned char		rtc_control = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_system_write_alarm");
+
+	if (count > sizeof(alarm_string) - 1)
+		return_VALUE(-EINVAL);
+	
+	if (copy_from_user(alarm_string, buffer, count))
+		return_VALUE(-EFAULT);
+
+	alarm_string[count] = '\0';
+
+	/* check for time adjustment */
+	if (alarm_string[0] == '+') {
+		p++;
+		adjust = 1;
+	}
+
+	if ((result = get_date_field(&p, &yr)))
+		goto end;
+	if ((result = get_date_field(&p, &mo)))
+		goto end;
+	if ((result = get_date_field(&p, &day)))
+		goto end;
+	if ((result = get_date_field(&p, &hr)))
+		goto end;
+	if ((result = get_date_field(&p, &min)))
+		goto end;
+	if ((result = get_date_field(&p, &sec)))
+		goto end;
+
+	if (sec > 59) {
+		min += 1;
+		sec -= 60;
+	}
+	if (min > 59) {
+		hr += 1;
+		min -= 60;
+	}
+	if (hr > 23) {
+		day += 1;
+		hr -= 24;
+	}
+	if (day > 31) {
+		mo += 1;
+		day -= 31;
+	}
+	if (mo > 12) {
+		yr += 1;
+		mo -= 12;
+	}
+
+	spin_lock_irq(&rtc_lock);
+
+	rtc_control = CMOS_READ(RTC_CONTROL);
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BIN_TO_BCD(yr);
+		BIN_TO_BCD(mo);
+		BIN_TO_BCD(day);
+		BIN_TO_BCD(hr);
+		BIN_TO_BCD(min);
+		BIN_TO_BCD(sec);
+	}
+
+	if (adjust) {
+		yr  += CMOS_READ(RTC_YEAR);
+		mo  += CMOS_READ(RTC_MONTH);
+		day += CMOS_READ(RTC_DAY_OF_MONTH);
+		hr  += CMOS_READ(RTC_HOURS);
+		min += CMOS_READ(RTC_MINUTES);
+		sec += CMOS_READ(RTC_SECONDS);
+	}
+
+	spin_unlock_irq(&rtc_lock);
+
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(yr);
+		BCD_TO_BIN(mo);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(hr);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(sec);
+	}
+
+	if (sec > 59) {
+		min++;
+		sec -= 60;
+	}
+	if (min > 59) {
+		hr++;
+		min -= 60;
+	}
+	if (hr > 23) {
+		day++;
+		hr -= 24;
+	}
+	if (day > 31) {
+		mo++;
+		day -= 31;
+	}
+	if (mo > 12) {
+		yr++;
+		mo -= 12;
+	}
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BIN_TO_BCD(yr);
+		BIN_TO_BCD(mo);
+		BIN_TO_BCD(day);
+		BIN_TO_BCD(hr);
+		BIN_TO_BCD(min);
+		BIN_TO_BCD(sec);
+	}
+
+	spin_lock_irq(&rtc_lock);
+	/*
+	 * Disable alarm interrupt before setting alarm timer or else
+	 * when ACPI_EVENT_RTC is enabled, a spurious ACPI interrupt occurs
+	 */
+	rtc_control &= ~RTC_AIE;
+	CMOS_WRITE(rtc_control, RTC_CONTROL);
+	CMOS_READ(RTC_INTR_FLAGS);
+
+	/* write the fields the rtc knows about */
+	CMOS_WRITE(hr, RTC_HOURS_ALARM);
+	CMOS_WRITE(min, RTC_MINUTES_ALARM);
+	CMOS_WRITE(sec, RTC_SECONDS_ALARM);
+
+	/*
+	 * If the system supports an enhanced alarm it will have non-zero
+	 * offsets into the CMOS RAM here -- which for some reason are pointing
+	 * to the RTC area of memory.
+	 */
+	if (acpi_gbl_FADT->day_alrm)
+		CMOS_WRITE(day, acpi_gbl_FADT->day_alrm);
+	if (acpi_gbl_FADT->mon_alrm)
+		CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
+	if (acpi_gbl_FADT->century)
+		CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
+	/* enable the rtc alarm interrupt */
+	rtc_control |= RTC_AIE;
+	CMOS_WRITE(rtc_control, RTC_CONTROL);
+	CMOS_READ(RTC_INTR_FLAGS);
+
+	spin_unlock_irq(&rtc_lock);
+
+	acpi_clear_event(ACPI_EVENT_RTC);
+	acpi_enable_event(ACPI_EVENT_RTC, 0);
+
+	*ppos += count;
+
+	result = 0;
+end:
+	return_VALUE(result ? result : count);
+}
+
+extern struct list_head	acpi_wakeup_device_list;
+extern spinlock_t acpi_device_lock;
+
+static int
+acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
+{
+	struct list_head * node, * next;
+
+	seq_printf(seq, "Device	Sleep state	Status\n");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
+
+		if (!dev->wakeup.flags.valid)
+			continue;
+		spin_unlock(&acpi_device_lock);
+		if (dev->wakeup.flags.run_wake)
+			seq_printf(seq, "%4s	%4d		%8s\n",
+				dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
+				dev->wakeup.state.enabled ? "*enabled" : "*disabled");
+		else
+			seq_printf(seq, "%4s	%4d		%8s\n",
+				dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
+				dev->wakeup.state.enabled ? "enabled" : "disabled");
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+	return 0;
+}
+
+static ssize_t
+acpi_system_write_wakeup_device (
+	struct file		*file,
+	const char __user	*buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	struct list_head * node, * next;
+	char		strbuf[5];
+	char		str[5] = "";
+	int 		len = count;
+	struct acpi_device *found_dev = NULL;
+
+	if (len > 4) len = 4;
+
+	if (copy_from_user(strbuf, buffer, len))
+		return -EFAULT;
+	strbuf[len] = '\0';
+	sscanf(strbuf, "%s", str);
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
+		if (!dev->wakeup.flags.valid)
+			continue;
+
+		if (!strncmp(dev->pnp.bus_id, str, 4)) {
+			dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0:1;
+			found_dev = dev;
+			break;
+		}
+	}
+	if (found_dev) {
+		list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+			struct acpi_device * dev = container_of(node,
+				struct acpi_device, wakeup_list);
+
+			if ((dev != found_dev) &&
+				(dev->wakeup.gpe_number == found_dev->wakeup.gpe_number) &&
+				(dev->wakeup.gpe_device == found_dev->wakeup.gpe_device)) {
+				printk(KERN_WARNING "ACPI: '%s' and '%s' have the same GPE, "
+					"can't disable/enable one seperately\n",
+					dev->pnp.bus_id, found_dev->pnp.bus_id);
+				dev->wakeup.state.enabled = found_dev->wakeup.state.enabled;
+			}
+		}
+	}
+	spin_unlock(&acpi_device_lock);
+	return count;
+}
+
+static int
+acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_system_wakeup_device_seq_show, PDE(inode)->data);
+}
+
+static struct file_operations acpi_system_wakeup_device_fops = {
+	.open		= acpi_system_wakeup_device_open_fs,
+	.read		= seq_read,
+	.write		= acpi_system_write_wakeup_device,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_system_sleep_fops = {
+	.open		= acpi_system_sleep_open_fs,
+	.read		= seq_read,
+	.write		= acpi_system_write_sleep,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_system_alarm_fops = {
+	.open		= acpi_system_alarm_open_fs,
+	.read		= seq_read,
+	.write		= acpi_system_write_alarm,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+static u32 rtc_handler(void * context)
+{
+	acpi_clear_event(ACPI_EVENT_RTC);
+	acpi_disable_event(ACPI_EVENT_RTC, 0);
+
+	return ACPI_INTERRUPT_HANDLED;
+}
+
+static int acpi_sleep_proc_init(void)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	if (acpi_disabled)
+		return 0;
+ 
+	/* 'sleep' [R/W]*/
+	entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
+				  S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_sleep_fops;
+
+	/* 'alarm' [R/W] */
+	entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_alarm_fops;
+
+	/* 'wakeup device' [R/W]*/
+	entry = create_proc_entry(ACPI_SYSTEM_FILE_WAKEUP_DEVICE,
+				  S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_wakeup_device_fops;
+
+	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
+	return 0;
+}
+
+late_initcall(acpi_sleep_proc_init);
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
new file mode 100644
index 0000000..efd0001
--- /dev/null
+++ b/drivers/acpi/sleep/sleep.h
@@ -0,0 +1,8 @@
+
+extern u8 sleep_states[];
+extern int acpi_suspend (u32 state);
+
+extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
+extern void acpi_enable_wakeup_device(u8 sleep_state);
+extern void acpi_disable_wakeup_device(u8 sleep_state);
+extern void acpi_wakeup_gpe_poweroff_prepare(void);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
new file mode 100644
index 0000000..d9b1999
--- /dev/null
+++ b/drivers/acpi/sleep/wakeup.c
@@ -0,0 +1,209 @@
+/*
+ * wakeup.c - support wakeup devices
+ * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <acpi/acevents.h>
+#include "sleep.h"
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("wakeup_devices")
+
+extern struct list_head	acpi_wakeup_device_list;
+extern spinlock_t acpi_device_lock;
+
+#ifdef CONFIG_ACPI_SLEEP
+/**
+ * acpi_enable_wakeup_device_prep - prepare wakeup devices
+ *	@sleep_state:	ACPI state
+ * Enable all wakup devices power if the devices' wakeup level
+ * is higher than requested sleep level
+ */
+
+void
+acpi_enable_wakeup_device_prep(
+	u8		sleep_state)
+{
+	struct list_head * node, * next;
+
+	ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+		
+		if (!dev->wakeup.flags.valid || 
+			!dev->wakeup.state.enabled ||
+			(sleep_state > (u32) dev->wakeup.sleep_state))
+			continue;
+
+		spin_unlock(&acpi_device_lock);
+		acpi_enable_wakeup_device_power(dev);
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+}
+
+/**
+ * acpi_enable_wakeup_device - enable wakeup devices
+ *	@sleep_state:	ACPI state
+ * Enable all wakup devices's GPE
+ */
+void
+acpi_enable_wakeup_device(
+	u8		sleep_state)
+{
+	struct list_head * node, * next;
+
+	/* 
+	 * Caution: this routine must be invoked when interrupt is disabled 
+	 * Refer ACPI2.0: P212
+	 */
+	ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+
+		/* If users want to disable run-wake GPE,
+		 * we only disable it for wake and leave it for runtime
+		 */
+		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+			spin_unlock(&acpi_device_lock);
+			acpi_set_gpe_type(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_GPE_TYPE_RUNTIME);
+			/* Re-enable it, since set_gpe_type will disable it */
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_ISR);
+			spin_lock(&acpi_device_lock);
+			continue;
+		}
+
+		if (!dev->wakeup.flags.valid ||
+			!dev->wakeup.state.enabled ||
+			(sleep_state > (u32) dev->wakeup.sleep_state))
+			continue;
+
+		spin_unlock(&acpi_device_lock);
+		/* run-wake GPE has been enabled */
+		if (!dev->wakeup.flags.run_wake)
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_ISR);
+		dev->wakeup.state.active = 1;
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+}
+
+/**
+ * acpi_disable_wakeup_device - disable devices' wakeup capability
+ *	@sleep_state:	ACPI state
+ * Disable all wakup devices's GPE and wakeup capability
+ */
+void
+acpi_disable_wakeup_device (
+	u8		sleep_state)
+{
+	struct list_head * node, * next;
+
+	ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+
+		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+			spin_unlock(&acpi_device_lock);
+			acpi_set_gpe_type(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
+			/* Re-enable it, since set_gpe_type will disable it */
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+			spin_lock(&acpi_device_lock);
+			continue;
+		}
+
+		if (!dev->wakeup.flags.valid || 
+			!dev->wakeup.state.active ||
+			(sleep_state > (u32) dev->wakeup.sleep_state))
+			continue;
+
+		spin_unlock(&acpi_device_lock);
+		acpi_disable_wakeup_device_power(dev);
+		/* Never disable run-wake GPE */
+		if (!dev->wakeup.flags.run_wake) {
+			acpi_disable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+			acpi_clear_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+		}
+		dev->wakeup.state.active = 0;
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+}
+
+static int __init acpi_wakeup_device_init(void)
+{
+	struct list_head * node, * next;
+
+	if (acpi_disabled)
+		return 0;
+	printk("ACPI wakeup devices: \n");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+		
+		/* In case user doesn't load button driver */
+		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+			spin_unlock(&acpi_device_lock);
+			acpi_set_gpe_type(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+			dev->wakeup.state.enabled = 1;
+			spin_lock(&acpi_device_lock);
+		}
+		printk("%4s ", dev->pnp.bus_id);
+	}
+	spin_unlock(&acpi_device_lock);
+	printk("\n");
+
+	return 0;
+}
+
+late_initcall(acpi_wakeup_device_init);
+#endif
+
+/*
+ * Disable all wakeup GPEs before power off.
+ * 
+ * Since acpi_enter_sleep_state() will disable all
+ * RUNTIME GPEs, we simply mark all GPES that
+ * are not enabled for wakeup from S5 as RUNTIME.
+ */
+void acpi_wakeup_gpe_poweroff_prepare(void)
+{
+	struct list_head * node, * next;
+
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node,
+			struct acpi_device, wakeup_list);
+
+		/* The GPE can wakeup system from S5, don't touch it */
+		if ((u32)dev->wakeup.sleep_state == ACPI_STATE_S5)
+			continue;
+		/* acpi_set_gpe_type will automatically disable GPE */
+		acpi_set_gpe_type(dev->wakeup.gpe_device,
+			dev->wakeup.gpe_number, ACPI_GPE_TYPE_RUNTIME);
+	}
+}
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
new file mode 100644
index 0000000..8925a6c
--- /dev/null
+++ b/drivers/acpi/system.c
@@ -0,0 +1,187 @@
+/*
+ *  acpi_system.c - ACPI System Driver ($Revision: 63 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("acpi_system")
+
+#define ACPI_SYSTEM_CLASS		"system"
+#define ACPI_SYSTEM_DRIVER_NAME		"ACPI System Driver"
+#define ACPI_SYSTEM_DEVICE_NAME		"System"
+#define ACPI_SYSTEM_FILE_INFO		"info"
+#define ACPI_SYSTEM_FILE_EVENT		"event"
+#define ACPI_SYSTEM_FILE_DSDT		"dsdt"
+#define ACPI_SYSTEM_FILE_FADT		"fadt"
+
+extern FADT_DESCRIPTOR		acpi_fadt;
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_system_read_info (struct seq_file *seq, void *offset)
+{
+	ACPI_FUNCTION_TRACE("acpi_system_read_info");
+
+	seq_printf(seq, "version:                 %x\n", ACPI_CA_VERSION);
+	return_VALUE(0);
+}
+
+static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_system_read_info, PDE(inode)->data);
+}
+
+static struct file_operations acpi_system_info_ops = {
+	.open		= acpi_system_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static ssize_t acpi_system_read_dsdt (struct file*, char __user *, size_t, loff_t*);
+
+static struct file_operations acpi_system_dsdt_ops = {
+	.read =			acpi_system_read_dsdt,
+};
+
+static ssize_t
+acpi_system_read_dsdt (
+	struct file		*file,
+	char			__user *buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_buffer	dsdt = {ACPI_ALLOCATE_BUFFER, NULL};
+	ssize_t			res;
+
+	ACPI_FUNCTION_TRACE("acpi_system_read_dsdt");
+
+	status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	res = simple_read_from_buffer(buffer, count, ppos,
+				      dsdt.pointer, dsdt.length);
+	acpi_os_free(dsdt.pointer);
+
+	return_VALUE(res);
+}
+
+
+static ssize_t acpi_system_read_fadt (struct file*, char __user *, size_t, loff_t*);
+
+static struct file_operations acpi_system_fadt_ops = {
+	.read =			acpi_system_read_fadt,
+};
+
+static ssize_t
+acpi_system_read_fadt (
+	struct file		*file,
+	char			__user *buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_buffer	fadt = {ACPI_ALLOCATE_BUFFER, NULL};
+	ssize_t			res;
+
+	ACPI_FUNCTION_TRACE("acpi_system_read_fadt");
+
+	status = acpi_get_table(ACPI_TABLE_FADT, 1, &fadt);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	res = simple_read_from_buffer(buffer, count, ppos,
+				      fadt.pointer, fadt.length);
+	acpi_os_free(fadt.pointer);
+
+	return_VALUE(res);
+}
+
+
+static int __init acpi_system_init (void)
+{
+	struct proc_dir_entry	*entry;
+	int error = 0;
+	char * name;
+
+	ACPI_FUNCTION_TRACE("acpi_system_init");
+
+	if (acpi_disabled)
+		return_VALUE(0);
+
+	/* 'info' [R] */
+	name = ACPI_SYSTEM_FILE_INFO;
+	entry = create_proc_entry(name,
+		S_IRUGO, acpi_root_dir);
+	if (!entry)
+		goto Error;
+	else {
+		entry->proc_fops = &acpi_system_info_ops;
+	}
+
+	/* 'dsdt' [R] */
+	name = ACPI_SYSTEM_FILE_DSDT;
+	entry = create_proc_entry(name, S_IRUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_dsdt_ops;
+	else 
+		goto Error;
+
+	/* 'fadt' [R] */
+	name = ACPI_SYSTEM_FILE_FADT;
+	entry = create_proc_entry(name, S_IRUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_fadt_ops;
+	else
+		goto Error;
+
+ Done:
+	return_VALUE(error);
+
+ Error:
+	ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			 "Unable to create '%s' proc fs entry\n", name));
+
+	remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
+	remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
+	remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
+
+	error = -EFAULT;
+	goto Done;
+}
+
+
+subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
new file mode 100644
index 0000000..fb64bd5
--- /dev/null
+++ b/drivers/acpi/tables.c
@@ -0,0 +1,609 @@
+/*
+ *  acpi_tables.c - ACPI Boot-Time Table Parsing
+ *
+ *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/bootmem.h>
+
+#define PREFIX			"ACPI: "
+
+#define ACPI_MAX_TABLES		256
+
+static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
+	[ACPI_TABLE_UNKNOWN]	= "????",
+	[ACPI_APIC]		= "APIC",
+	[ACPI_BOOT]		= "BOOT",
+	[ACPI_DBGP]		= "DBGP",
+	[ACPI_DSDT]		= "DSDT",
+	[ACPI_ECDT]		= "ECDT",
+	[ACPI_ETDT]		= "ETDT",
+	[ACPI_FADT]		= "FACP",
+	[ACPI_FACS]		= "FACS",
+	[ACPI_OEMX]		= "OEM",
+	[ACPI_PSDT]		= "PSDT",
+	[ACPI_SBST]		= "SBST",
+	[ACPI_SLIT]		= "SLIT",
+	[ACPI_SPCR]		= "SPCR",
+	[ACPI_SRAT]		= "SRAT",
+	[ACPI_SSDT]		= "SSDT",
+	[ACPI_SPMI]		= "SPMI",
+	[ACPI_HPET]		= "HPET",
+	[ACPI_MCFG]		= "MCFG",
+};
+
+static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
+static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
+
+/* System Description Table (RSDT/XSDT) */
+struct acpi_table_sdt {
+	unsigned long		pa;
+	enum acpi_table_id	id;
+	unsigned long		size;
+} __attribute__ ((packed));
+
+static unsigned long		sdt_pa;		/* Physical Address */
+static unsigned long		sdt_count;	/* Table count */
+
+static struct acpi_table_sdt	sdt_entry[ACPI_MAX_TABLES];
+
+void
+acpi_table_print (
+	struct acpi_table_header *header,
+	unsigned long		phys_addr)
+{
+	char			*name = NULL;
+
+	if (!header)
+		return;
+
+	/* Some table signatures aren't good table names */
+
+	if (!strncmp((char *) &header->signature,
+		acpi_table_signatures[ACPI_APIC],
+		sizeof(header->signature))) {
+		name = "MADT";
+	}
+	else if (!strncmp((char *) &header->signature,
+		acpi_table_signatures[ACPI_FADT],
+		sizeof(header->signature))) {
+		name = "FADT";
+	}
+	else
+		name = header->signature;
+
+	printk(KERN_DEBUG PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n",
+		name, header->revision, header->oem_id,
+		header->oem_table_id, header->oem_revision,
+		header->asl_compiler_id, header->asl_compiler_revision,
+		(void *) phys_addr);
+}
+
+
+void
+acpi_table_print_madt_entry (
+	acpi_table_entry_header	*header)
+{
+	if (!header)
+		return;
+
+	switch (header->type) {
+
+	case ACPI_MADT_LAPIC:
+	{
+		struct acpi_table_lapic *p =
+			(struct acpi_table_lapic*) header;
+		printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
+			p->acpi_id, p->id, p->flags.enabled?"enabled":"disabled");
+	}
+		break;
+
+	case ACPI_MADT_IOAPIC:
+	{
+		struct acpi_table_ioapic *p =
+			(struct acpi_table_ioapic*) header;
+		printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
+			p->id, p->address, p->global_irq_base);
+	}
+		break;
+
+	case ACPI_MADT_INT_SRC_OVR:
+	{
+		struct acpi_table_int_src_ovr *p =
+			(struct acpi_table_int_src_ovr*) header;
+		printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
+			p->bus, p->bus_irq, p->global_irq,
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger]);
+		if(p->flags.reserved)
+			printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
+				p->flags.reserved);
+
+	}
+		break;
+
+	case ACPI_MADT_NMI_SRC:
+	{
+		struct acpi_table_nmi_src *p =
+			(struct acpi_table_nmi_src*) header;
+		printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n",
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger], p->global_irq);
+	}
+		break;
+
+	case ACPI_MADT_LAPIC_NMI:
+	{
+		struct acpi_table_lapic_nmi *p =
+			(struct acpi_table_lapic_nmi*) header;
+		printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
+			p->acpi_id,
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger], p->lint);
+	}
+		break;
+
+	case ACPI_MADT_LAPIC_ADDR_OVR:
+	{
+		struct acpi_table_lapic_addr_ovr *p =
+			(struct acpi_table_lapic_addr_ovr*) header;
+		printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n",
+			(void *) (unsigned long) p->address);
+	}
+		break;
+
+	case ACPI_MADT_IOSAPIC:
+	{
+		struct acpi_table_iosapic *p =
+			(struct acpi_table_iosapic*) header;
+		printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
+			p->id, (void *) (unsigned long) p->address, p->global_irq_base);
+	}
+		break;
+
+	case ACPI_MADT_LSAPIC:
+	{
+		struct acpi_table_lsapic *p =
+			(struct acpi_table_lsapic*) header;
+		printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
+			p->acpi_id, p->id, p->eid, p->flags.enabled?"enabled":"disabled");
+	}
+		break;
+
+	case ACPI_MADT_PLAT_INT_SRC:
+	{
+		struct acpi_table_plat_int_src *p =
+			(struct acpi_table_plat_int_src*) header;
+		printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger],
+			p->type, p->id, p->eid, p->iosapic_vector, p->global_irq);
+	}
+		break;
+
+	default:
+		printk(KERN_WARNING PREFIX "Found unsupported MADT entry (type = 0x%x)\n",
+			header->type);
+		break;
+	}
+}
+
+
+static int
+acpi_table_compute_checksum (
+	void			*table_pointer,
+	unsigned long		length)
+{
+	u8			*p = (u8 *) table_pointer;
+	unsigned long		remains = length;
+	unsigned long		sum = 0;
+
+	if (!p || !length)
+		return -EINVAL;
+
+	while (remains--)
+		sum += *p++;
+
+	return (sum & 0xFF);
+}
+
+/*
+ * acpi_get_table_header_early()
+ * for acpi_blacklisted(), acpi_table_get_sdt()
+ */
+int __init
+acpi_get_table_header_early (
+	enum acpi_table_id	id,
+	struct acpi_table_header **header)
+{
+	unsigned int i;
+	enum acpi_table_id temp_id;
+
+	/* DSDT is different from the rest */
+	if (id == ACPI_DSDT)
+		temp_id = ACPI_FADT;
+	else
+		temp_id = id;
+
+	/* Locate the table. */
+
+	for (i = 0; i < sdt_count; i++) {
+		if (sdt_entry[i].id != temp_id)
+			continue;
+		*header = (void *)
+			__acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
+		if (!*header) {
+			printk(KERN_WARNING PREFIX "Unable to map %s\n",
+			       acpi_table_signatures[temp_id]);
+			return -ENODEV;
+		}
+		break;
+	}
+
+	if (!*header) {
+		printk(KERN_WARNING PREFIX "%s not present\n",
+		       acpi_table_signatures[id]);
+		return -ENODEV;
+	}
+
+	/* Map the DSDT header via the pointer in the FADT */
+	if (id == ACPI_DSDT) {
+		struct fadt_descriptor_rev2 *fadt = (struct fadt_descriptor_rev2 *) *header;
+
+		if (fadt->revision == 3 && fadt->Xdsdt) {
+			*header = (void *) __acpi_map_table(fadt->Xdsdt,
+					sizeof(struct acpi_table_header));
+		} else if (fadt->V1_dsdt) {
+			*header = (void *) __acpi_map_table(fadt->V1_dsdt,
+					sizeof(struct acpi_table_header));
+		} else
+			*header = NULL;
+
+		if (!*header) {
+			printk(KERN_WARNING PREFIX "Unable to map DSDT\n");
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+	 
+
+int __init
+acpi_table_parse_madt_family (
+	enum acpi_table_id	id,
+	unsigned long		madt_size,
+	int			entry_id,
+	acpi_madt_entry_handler	handler,
+	unsigned int		max_entries)
+{
+	void			*madt = NULL;
+	acpi_table_entry_header	*entry;
+	unsigned int		count = 0;
+	unsigned long		madt_end;
+	unsigned int		i;
+
+	if (!handler)
+		return -EINVAL;
+
+	/* Locate the MADT (if exists). There should only be one. */
+
+	for (i = 0; i < sdt_count; i++) {
+		if (sdt_entry[i].id != id)
+			continue;
+		madt = (void *)
+			__acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
+		if (!madt) {
+			printk(KERN_WARNING PREFIX "Unable to map %s\n",
+			       acpi_table_signatures[id]);
+			return -ENODEV;
+		}
+		break;
+	}
+
+	if (!madt) {
+		printk(KERN_WARNING PREFIX "%s not present\n",
+		       acpi_table_signatures[id]);
+		return -ENODEV;
+	}
+
+	madt_end = (unsigned long) madt + sdt_entry[i].size;
+
+	/* Parse all entries looking for a match. */
+
+	entry = (acpi_table_entry_header *)
+		((unsigned long) madt + madt_size);
+
+	while (((unsigned long) entry) + sizeof(acpi_table_entry_header) < madt_end) {
+		if (entry->type == entry_id &&
+		    (!max_entries || count++ < max_entries))
+			if (handler(entry, madt_end))
+				return -EINVAL;
+
+		entry = (acpi_table_entry_header *)
+			((unsigned long) entry + entry->length);
+	}
+	if (max_entries && count > max_entries) {
+		printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of "
+		       "%i found\n", acpi_table_signatures[id], entry_id,
+		       count - max_entries, count);
+	}
+
+	return count;
+}
+
+
+int __init
+acpi_table_parse_madt (
+	enum acpi_madt_entry_id	id,
+	acpi_madt_entry_handler	handler,
+	unsigned int max_entries)
+{
+	return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt),
+					    id, handler, max_entries);
+}
+
+
+int __init
+acpi_table_parse (
+	enum acpi_table_id	id,
+	acpi_table_handler	handler)
+{
+	int			count = 0;
+	unsigned int		i = 0;
+
+	if (!handler)
+		return -EINVAL;
+
+	for (i = 0; i < sdt_count; i++) {
+		if (sdt_entry[i].id != id)
+			continue;
+		count++;
+		if (count == 1)
+			handler(sdt_entry[i].pa, sdt_entry[i].size);
+
+		else
+			printk(KERN_WARNING PREFIX "%d duplicate %s table ignored.\n",
+				count, acpi_table_signatures[id]);
+	}
+
+	return count;
+}
+
+
+static int __init
+acpi_table_get_sdt (
+	struct acpi_table_rsdp	*rsdp)
+{
+	struct acpi_table_header *header = NULL;
+	unsigned int		i, id = 0;
+
+	if (!rsdp)
+		return -EINVAL;
+
+	/* First check XSDT (but only on ACPI 2.0-compatible systems) */
+
+	if ((rsdp->revision >= 2) &&
+		(((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) {
+			
+		struct acpi_table_xsdt	*mapped_xsdt = NULL;
+
+		sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
+
+		/* map in just the header */
+		header = (struct acpi_table_header *)
+			__acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
+
+		if (!header) {
+			printk(KERN_WARNING PREFIX "Unable to map XSDT header\n");
+			return -ENODEV;
+		}
+
+		/* remap in the entire table before processing */
+		mapped_xsdt = (struct acpi_table_xsdt *)
+			__acpi_map_table(sdt_pa, header->length);
+		if (!mapped_xsdt) {
+			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
+			return -ENODEV;
+		}
+		header = &mapped_xsdt->header;
+
+		if (strncmp(header->signature, "XSDT", 4)) {
+			printk(KERN_WARNING PREFIX "XSDT signature incorrect\n");
+			return -ENODEV;
+		}
+
+		if (acpi_table_compute_checksum(header, header->length)) {
+			printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
+			return -ENODEV;
+		}
+
+		sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3;
+		if (sdt_count > ACPI_MAX_TABLES) {
+			printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n",
+				(sdt_count - ACPI_MAX_TABLES));
+			sdt_count = ACPI_MAX_TABLES;
+		}
+
+		for (i = 0; i < sdt_count; i++)
+			sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
+	}
+
+	/* Then check RSDT */
+
+	else if (rsdp->rsdt_address) {
+
+		struct acpi_table_rsdt	*mapped_rsdt = NULL;
+
+		sdt_pa = rsdp->rsdt_address;
+
+		/* map in just the header */
+		header = (struct acpi_table_header *)
+			__acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
+		if (!header) {
+			printk(KERN_WARNING PREFIX "Unable to map RSDT header\n");
+			return -ENODEV;
+		}
+
+		/* remap in the entire table before processing */
+		mapped_rsdt = (struct acpi_table_rsdt *)
+			__acpi_map_table(sdt_pa, header->length);
+		if (!mapped_rsdt) {
+			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
+			return -ENODEV;
+		}
+		header = &mapped_rsdt->header;
+
+		if (strncmp(header->signature, "RSDT", 4)) {
+			printk(KERN_WARNING PREFIX "RSDT signature incorrect\n");
+			return -ENODEV;
+		}
+
+		if (acpi_table_compute_checksum(header, header->length)) {
+			printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n");
+			return -ENODEV;
+		}
+
+		sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 2;
+		if (sdt_count > ACPI_MAX_TABLES) {
+			printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n",
+				(sdt_count - ACPI_MAX_TABLES));
+			sdt_count = ACPI_MAX_TABLES;
+		}
+
+		for (i = 0; i < sdt_count; i++)
+			sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
+	}
+
+	else {
+		printk(KERN_WARNING PREFIX "No System Description Table (RSDT/XSDT) specified in RSDP\n");
+		return -ENODEV;
+	}
+
+	acpi_table_print(header, sdt_pa);
+
+	for (i = 0; i < sdt_count; i++) {
+
+		/* map in just the header */
+		header = (struct acpi_table_header *)
+			__acpi_map_table(sdt_entry[i].pa,
+				sizeof(struct acpi_table_header));
+		if (!header)
+			continue;
+
+		/* remap in the entire table before processing */
+		header = (struct acpi_table_header *)
+			__acpi_map_table(sdt_entry[i].pa,
+				header->length);
+		if (!header)
+			continue;
+	               
+		acpi_table_print(header, sdt_entry[i].pa);
+
+		if (acpi_table_compute_checksum(header, header->length)) {
+			printk(KERN_WARNING "  >>> ERROR: Invalid checksum\n");
+			continue;
+		}
+
+		sdt_entry[i].size = header->length;
+
+		for (id = 0; id < ACPI_TABLE_COUNT; id++) {
+			if (!strncmp((char *) &header->signature,
+				acpi_table_signatures[id],
+				sizeof(header->signature))) {
+				sdt_entry[i].id = id;
+			}
+		}
+	}
+
+	/* 
+	 * The DSDT is *not* in the RSDT (why not? no idea.) but we want
+	 * to print its info, because this is what people usually blacklist
+	 * against. Unfortunately, we don't know the phys_addr, so just
+	 * print 0. Maybe no one will notice.
+	 */
+	if(!acpi_get_table_header_early(ACPI_DSDT, &header))
+		acpi_table_print(header, 0);
+
+	return 0;
+}
+
+/*
+ * acpi_table_init()
+ *
+ * find RSDP, find and checksum SDT/XSDT.
+ * checksum all tables, print SDT/XSDT
+ * 
+ * result: sdt_entry[] is initialized
+ */
+
+int __init
+acpi_table_init (void)
+{
+	struct acpi_table_rsdp	*rsdp = NULL;
+	unsigned long		rsdp_phys = 0;
+	int			result = 0;
+
+	/* Locate and map the Root System Description Table (RSDP) */
+
+	rsdp_phys = acpi_find_rsdp();
+	if (!rsdp_phys) {
+		printk(KERN_ERR PREFIX "Unable to locate RSDP\n");
+		return -ENODEV;
+	}
+
+	rsdp = (struct acpi_table_rsdp *) __va(rsdp_phys);
+	if (!rsdp) {
+		printk(KERN_WARNING PREFIX "Unable to map RSDP\n");
+		return -ENODEV;
+	}
+
+	printk(KERN_DEBUG PREFIX "RSDP (v%3.3d %6.6s                                ) @ 0x%p\n",
+		rsdp->revision, rsdp->oem_id, (void *) rsdp_phys);
+
+	if (rsdp->revision < 2)
+		result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp));
+	else
+		result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length);
+
+	if (result) {
+		printk(KERN_WARNING "  >>> ERROR: Invalid checksum\n");
+		return -ENODEV;
+	}
+
+	/* Locate and map the System Description table (RSDT/XSDT) */
+
+	if (acpi_table_get_sdt(rsdp))
+		return -ENODEV;
+
+	return 0;
+}
diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile
new file mode 100644
index 0000000..aa4c695
--- /dev/null
+++ b/drivers/acpi/tables/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := tbconvrt.o  tbget.o     tbrsdt.o   tbxface.o  \
+	 tbgetall.o  tbinstal.o  tbutils.o  tbxfroot.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
new file mode 100644
index 0000000..334327c
--- /dev/null
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -0,0 +1,564 @@
+/******************************************************************************
+ *
+ * Module Name: tbconvrt - ACPI Table conversion utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbconvrt")
+
+
+u8 acpi_fadt_is_v1;
+EXPORT_SYMBOL(acpi_fadt_is_v1);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_table_count
+ *
+ * PARAMETERS:  RSDP            - Pointer to the RSDP
+ *              RSDT            - Pointer to the RSDT/XSDT
+ *
+ * RETURN:      The number of tables pointed to by the RSDT or XSDT.
+ *
+ * DESCRIPTION: Calculate the number of tables.  Automatically handles either
+ *              an RSDT or XSDT.
+ *
+ ******************************************************************************/
+
+u32
+acpi_tb_get_table_count (
+	struct rsdp_descriptor          *RSDP,
+	struct acpi_table_header        *RSDT)
+{
+	u32                             pointer_size;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (RSDP->revision < 2) {
+		pointer_size = sizeof (u32);
+	}
+	else {
+		pointer_size = sizeof (u64);
+	}
+
+	/*
+	 * Determine the number of tables pointed to by the RSDT/XSDT.
+	 * This is defined by the ACPI Specification to be the number of
+	 * pointers contained within the RSDT/XSDT.  The size of the pointers
+	 * is architecture-dependent.
+	 */
+	return ((RSDT->length - sizeof (struct acpi_table_header)) / pointer_size);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_convert_to_xsdt
+ *
+ * PARAMETERS:  table_info      - Info about the RSDT
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert an RSDT to an XSDT (internal common format)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_convert_to_xsdt (
+	struct acpi_table_desc          *table_info)
+{
+	acpi_size                       table_size;
+	u32                             i;
+	XSDT_DESCRIPTOR         *new_table;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Compute size of the converted XSDT */
+
+	table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) +
+			  sizeof (struct acpi_table_header);
+
+	/* Allocate an XSDT */
+
+	new_table = ACPI_MEM_CALLOCATE (table_size);
+	if (!new_table) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Copy the header and set the length */
+
+	ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header));
+	new_table->length = (u32) table_size;
+
+	/* Copy the table pointers */
+
+	for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
+		if (acpi_gbl_RSDP->revision < 2) {
+			ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
+				(ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]);
+		}
+		else {
+			new_table->table_offset_entry[i] =
+				(ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info->pointer))->table_offset_entry[i];
+		}
+	}
+
+	/* Delete the original table (either mapped or in a buffer) */
+
+	acpi_tb_delete_single_table (table_info);
+
+	/* Point the table descriptor to the new table */
+
+	table_info->pointer     = ACPI_CAST_PTR (struct acpi_table_header, new_table);
+	table_info->length      = table_size;
+	table_info->allocation  = ACPI_MEM_ALLOCATED;
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_init_generic_address
+ *
+ * PARAMETERS:  new_gas_struct      - GAS struct to be initialized
+ *              register_bit_width  - Width of this register
+ *              Address             - Address of the register
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize a GAS structure.
+ *
+ ******************************************************************************/
+
+static void
+acpi_tb_init_generic_address (
+	struct acpi_generic_address     *new_gas_struct,
+	u8                              register_bit_width,
+	acpi_physical_address           address)
+{
+
+	ACPI_STORE_ADDRESS (new_gas_struct->address, address);
+
+	new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
+	new_gas_struct->register_bit_width = register_bit_width;
+	new_gas_struct->register_bit_offset = 0;
+	new_gas_struct->access_width    = 0;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_convert_fadt1
+ *
+ * PARAMETERS:  local_fadt      - Pointer to new FADT
+ *              original_fadt   - Pointer to old FADT
+ *
+ * RETURN:      Populates local_fadt
+ *
+ * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format
+ *
+ ******************************************************************************/
+
+static void
+acpi_tb_convert_fadt1 (
+	struct fadt_descriptor_rev2    *local_fadt,
+	struct fadt_descriptor_rev1    *original_fadt)
+{
+
+
+	/* ACPI 1.0 FACS */
+	/* The BIOS stored FADT should agree with Revision 1.0 */
+	acpi_fadt_is_v1 = 1;
+
+	/*
+	 * Copy the table header and the common part of the tables.
+	 *
+	 * The 2.0 table is an extension of the 1.0 table, so the entire 1.0
+	 * table can be copied first, then expand some fields to 64 bits.
+	 */
+	ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev1));
+
+	/* Convert table pointers to 64-bit fields */
+
+	ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
+	ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
+
+	/*
+	 * System Interrupt Model isn't used in ACPI 2.0 (local_fadt->Reserved1 = 0;)
+	 */
+
+	/*
+	 * This field is set by the OEM to convey the preferred power management
+	 * profile to OSPM. It doesn't have any 1.0 equivalence.  Since we don't
+	 * know what kind of 32-bit system this is, we will use "unspecified".
+	 */
+	local_fadt->prefer_PM_profile = PM_UNSPECIFIED;
+
+	/*
+	 * Processor Performance State Control. This is the value OSPM writes to
+	 * the SMI_CMD register to assume processor performance state control
+	 * responsibility. There isn't any equivalence in 1.0, but as many 1.x
+	 * ACPI tables contain _PCT and _PSS we also keep this value, unless
+	 * acpi_strict is set.
+	 */
+	if (acpi_strict)
+		local_fadt->pstate_cnt = 0;
+
+	/*
+	 * Support for the _CST object and C States change notification.
+	 * This data item hasn't any 1.0 equivalence so leave it zero.
+	 */
+	local_fadt->cst_cnt = 0;
+
+	/*
+	 * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0.
+	 * It primarily adds the FADT reset mechanism.
+	 */
+	if ((original_fadt->revision == 2) &&
+		(original_fadt->length == sizeof (struct fadt_descriptor_rev2_minus))) {
+		/*
+		 * Grab the entire generic address struct, plus the 1-byte reset value
+		 * that immediately follows.
+		 */
+		ACPI_MEMCPY (&local_fadt->reset_register,
+			&(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register,
+  			sizeof (struct acpi_generic_address) + 1);
+	}
+	else {
+		/*
+		 * Since there isn't any equivalence in 1.0 and since it is highly
+		 * likely that a 1.0 system has legacy support.
+		 */
+		local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES;
+	}
+
+	/*
+	 * Convert the V1.0 block addresses to V2.0 GAS structures
+	 */
+	acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1a_evt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1b_evt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1a_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1b_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm2_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len,
+			  (acpi_physical_address)   local_fadt->V1_pm_tmr_blk);
+	acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0,
+			  (acpi_physical_address)   local_fadt->V1_gpe0_blk);
+	acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0,
+			  (acpi_physical_address)   local_fadt->V1_gpe1_blk);
+
+	/* Create separate GAS structs for the PM1 Enable registers */
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
+		 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		 (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+
+	/* PM1B is optional; leave null if not present */
+
+	if (local_fadt->xpm1b_evt_blk.address) {
+		acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+			 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+			 (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+				ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_convert_fadt2
+ *
+ * PARAMETERS:  local_fadt      - Pointer to new FADT
+ *              original_fadt   - Pointer to old FADT
+ *
+ * RETURN:      Populates local_fadt
+ *
+ * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format.
+ *              Handles optional "X" fields.
+ *
+ ******************************************************************************/
+
+static void
+acpi_tb_convert_fadt2 (
+	struct fadt_descriptor_rev2    *local_fadt,
+	struct fadt_descriptor_rev2    *original_fadt)
+{
+
+	/* We have an ACPI 2.0 FADT but we must copy it to our local buffer */
+
+	ACPI_MEMCPY (local_fadt, original_fadt, sizeof (struct fadt_descriptor_rev2));
+
+	/*
+	 * "X" fields are optional extensions to the original V1.0 fields, so
+	 * we must selectively expand V1.0 fields if the corresponding X field
+	 * is zero.
+	 */
+	if (!(local_fadt->xfirmware_ctrl)) {
+		ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
+	}
+
+	if (!(local_fadt->Xdsdt)) {
+		ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
+	}
+
+	if (!(local_fadt->xpm1a_evt_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
+			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
+	}
+
+	if (!(local_fadt->xpm1b_evt_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
+			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
+	}
+
+	if (!(local_fadt->xpm1a_cnt_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
+			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
+	}
+
+	if (!(local_fadt->xpm1b_cnt_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
+			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
+	}
+
+	if (!(local_fadt->xpm2_cnt_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
+			local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
+	}
+
+	if (!(local_fadt->xpm_tmr_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
+			local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
+	}
+
+	if (!(local_fadt->xgpe0_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xgpe0_blk,
+			0, (acpi_physical_address) local_fadt->V1_gpe0_blk);
+	}
+
+	if (!(local_fadt->xgpe1_blk.address)) {
+		acpi_tb_init_generic_address (&local_fadt->xgpe1_blk,
+			0, (acpi_physical_address) local_fadt->V1_gpe1_blk);
+	}
+
+	/* Create separate GAS structs for the PM1 Enable registers */
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
+		(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		(acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+	acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id;
+
+	/* PM1B is optional; leave null if not present */
+
+	if (local_fadt->xpm1b_evt_blk.address) {
+		acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+			(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+			(acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+				ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+		acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_convert_table_fadt
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local
+ *              ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply
+ *              copied to the local FADT.  The ACPI CA software uses this
+ *              local FADT. Thus a significant amount of special #ifdef
+ *              type codeing is saved.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_convert_table_fadt (void)
+{
+	struct fadt_descriptor_rev2    *local_fadt;
+	struct acpi_table_desc         *table_desc;
+
+
+	ACPI_FUNCTION_TRACE ("tb_convert_table_fadt");
+
+
+	/*
+	 * acpi_gbl_FADT is valid. Validate the FADT length. The table must be
+	 * at least as long as the version 1.0 FADT
+	 */
+	if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
+		ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n", acpi_gbl_FADT->length));
+		return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+	}
+
+	/* Allocate buffer for the ACPI 2.0(+) FADT */
+
+	local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2));
+	if (!local_fadt) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) {
+		if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) {
+			/* Length is too short to be a V2.0 table */
+
+			ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
+					 acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
+
+			acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
+		}
+		else {
+			/* Valid V2.0 table */
+
+			acpi_tb_convert_fadt2 (local_fadt, acpi_gbl_FADT);
+		}
+	}
+	else {
+		/* Valid V1.0 table */
+
+		acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
+	}
+
+	/*
+	 * Global FADT pointer will point to the new common V2.0 FADT
+	 */
+	acpi_gbl_FADT = local_fadt;
+	acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR);
+
+	/* Free the original table */
+
+	table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next;
+	acpi_tb_delete_single_table (table_desc);
+
+	/* Install the new table */
+
+	table_desc->pointer     = ACPI_CAST_PTR (struct acpi_table_header, acpi_gbl_FADT);
+	table_desc->allocation  = ACPI_MEM_ALLOCATED;
+	table_desc->length      = sizeof (struct fadt_descriptor_rev2);
+
+	/* Dump the entire FADT */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
+		"Hex dump of common internal FADT, size %d (%X)\n",
+		acpi_gbl_FADT->length, acpi_gbl_FADT->length));
+	ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_convert_table_facs
+ *
+ * PARAMETERS:  table_info      - Info for currently installed FACS
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal
+ *              table format.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_build_common_facs (
+	struct acpi_table_desc          *table_info)
+{
+
+	ACPI_FUNCTION_TRACE ("tb_build_common_facs");
+
+
+	/* Absolute minimum length is 24, but the ACPI spec says 64 */
+
+	if (acpi_gbl_FACS->length < 24) {
+		ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n", acpi_gbl_FACS->length));
+		return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+	}
+
+	if (acpi_gbl_FACS->length < 64) {
+		ACPI_REPORT_WARNING (("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
+			acpi_gbl_FACS->length));
+	}
+
+	/* Copy fields to the new FACS */
+
+	acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock);
+
+	if ((acpi_gbl_RSDP->revision < 2) ||
+		(acpi_gbl_FACS->length < 32) ||
+		(!(acpi_gbl_FACS->xfirmware_waking_vector))) {
+		/* ACPI 1.0 FACS or short table or optional X_ field is zero */
+
+		acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64, &(acpi_gbl_FACS->firmware_waking_vector));
+		acpi_gbl_common_fACS.vector_width = 32;
+	}
+	else {
+		/* ACPI 2.0 FACS with valid X_ field */
+
+		acpi_gbl_common_fACS.firmware_waking_vector = &acpi_gbl_FACS->xfirmware_waking_vector;
+		acpi_gbl_common_fACS.vector_width = 64;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
new file mode 100644
index 0000000..896f3dd
--- /dev/null
+++ b/drivers/acpi/tables/tbget.c
@@ -0,0 +1,493 @@
+/******************************************************************************
+ *
+ * Module Name: tbget - ACPI Table get* routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbget")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_table
+ *
+ * PARAMETERS:  Address             - Address of table to retrieve.  Can be
+ *                                    Logical or Physical
+ *              table_info          - Where table info is returned
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Get entire table of unknown size.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_desc          *table_info)
+{
+	acpi_status                     status;
+	struct acpi_table_header        header;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_table");
+
+
+	/*
+	 * Get the header in order to get signature and table size
+	 */
+	status = acpi_tb_get_table_header (address, &header);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get the entire table */
+
+	status = acpi_tb_get_table_body (address, &header, table_info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
+			header.length, acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_table_header
+ *
+ * PARAMETERS:  Address             - Address of table to retrieve.  Can be
+ *                                    Logical or Physical
+ *              return_header       - Where the table header is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get an ACPI table header.  Works in both physical or virtual
+ *              addressing mode.  Works with both physical or logical pointers.
+ *              Table is either copied or mapped, depending on the pointer
+ *              type and mode of the processor.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_table_header (
+	struct acpi_pointer             *address,
+	struct acpi_table_header        *return_header)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_table_header        *header = NULL;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_table_header");
+
+
+	/*
+	 * Flags contains the current processor mode (Virtual or Physical addressing)
+	 * The pointer_type is either Logical or Physical
+	 */
+	switch (address->pointer_type) {
+	case ACPI_PHYSMODE_PHYSPTR:
+	case ACPI_LOGMODE_LOGPTR:
+
+		/* Pointer matches processor mode, copy the header */
+
+		ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (struct acpi_table_header));
+		break;
+
+
+	case ACPI_LOGMODE_PHYSPTR:
+
+		/* Create a logical address for the physical pointer*/
+
+		status = acpi_os_map_memory (address->pointer.physical, sizeof (struct acpi_table_header),
+				  (void *) &header);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
+				ACPI_FORMAT_UINT64 (address->pointer.physical),
+				sizeof (struct acpi_table_header)));
+			return_ACPI_STATUS (status);
+		}
+
+		/* Copy header and delete mapping */
+
+		ACPI_MEMCPY (return_header, header, sizeof (struct acpi_table_header));
+		acpi_os_unmap_memory (header, sizeof (struct acpi_table_header));
+		break;
+
+
+	default:
+
+		ACPI_REPORT_ERROR (("Invalid address flags %X\n",
+			address->pointer_type));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n",
+		return_header->signature));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_table_body
+ *
+ * PARAMETERS:  Address             - Address of table to retrieve.  Can be
+ *                                    Logical or Physical
+ *              Header              - Header of the table to retrieve
+ *              table_info          - Where the table info is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to
+ *              replace the table with a newer version (table override.)
+ *              Works in both physical or virtual
+ *              addressing mode.  Works with both physical or logical pointers.
+ *              Table is either copied or mapped, depending on the pointer
+ *              type and mode of the processor.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_table_body (
+	struct acpi_pointer             *address,
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_table_body");
+
+
+	if (!table_info || !address) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Attempt table override.
+	 */
+	status = acpi_tb_table_override (header, table_info);
+	if (ACPI_SUCCESS (status)) {
+		/* Table was overridden by the host OS */
+
+		return_ACPI_STATUS (status);
+	}
+
+	/* No override, get the original table */
+
+	status = acpi_tb_get_this_table (address, header, table_info);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_table_override
+ *
+ * PARAMETERS:  Header              - Pointer to table header
+ *              table_info          - Return info if table is overridden
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Attempts override of current table with a new one if provided
+ *              by the host OS.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_table_override (
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info)
+{
+	struct acpi_table_header        *new_table;
+	acpi_status                     status;
+	struct acpi_pointer             address;
+
+
+	ACPI_FUNCTION_TRACE ("tb_table_override");
+
+
+	/*
+	 * The OSL will examine the header and decide whether to override this
+	 * table.  If it decides to override, a table will be returned in new_table,
+	 * which we will then copy.
+	 */
+	status = acpi_os_table_override (header, &new_table);
+	if (ACPI_FAILURE (status)) {
+		/* Some severe error from the OSL, but we basically ignore it */
+
+		ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
+			acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	if (!new_table) {
+		/* No table override */
+
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	/*
+	 * We have a new table to override the old one.  Get a copy of
+	 * the new one.  We know that the new table has a logical pointer.
+	 */
+	address.pointer_type    = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
+	address.pointer.logical = new_table;
+
+	status = acpi_tb_get_this_table (&address, new_table, table_info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
+			acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	/* Copy the table info */
+
+	ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
+		table_info->pointer->signature));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_this_table
+ *
+ * PARAMETERS:  Address             - Address of table to retrieve.  Can be
+ *                                    Logical or Physical
+ *              Header              - Header of the table to retrieve
+ *              table_info          - Where the table info is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get an entire ACPI table.  Works in both physical or virtual
+ *              addressing mode.  Works with both physical or logical pointers.
+ *              Table is either copied or mapped, depending on the pointer
+ *              type and mode of the processor.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_this_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info)
+{
+	struct acpi_table_header        *full_table = NULL;
+	u8                              allocation;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_this_table");
+
+
+	/*
+	 * Flags contains the current processor mode (Virtual or Physical addressing)
+	 * The pointer_type is either Logical or Physical
+	 */
+	switch (address->pointer_type) {
+	case ACPI_PHYSMODE_PHYSPTR:
+	case ACPI_LOGMODE_LOGPTR:
+
+		/* Pointer matches processor mode, copy the table to a new buffer */
+
+		full_table = ACPI_MEM_ALLOCATE (header->length);
+		if (!full_table) {
+			ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
+				header->signature, header->length));
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+
+		/* Copy the entire table (including header) to the local buffer */
+
+		ACPI_MEMCPY (full_table, address->pointer.logical, header->length);
+
+		/* Save allocation type */
+
+		allocation = ACPI_MEM_ALLOCATED;
+		break;
+
+
+	case ACPI_LOGMODE_PHYSPTR:
+
+		/*
+		 * Just map the table's physical memory
+		 * into our address space.
+		 */
+		status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length,
+				  (void *) &full_table);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
+				header->signature,
+				ACPI_FORMAT_UINT64 (address->pointer.physical), header->length));
+			return (status);
+		}
+
+		/* Save allocation type */
+
+		allocation = ACPI_MEM_MAPPED;
+		break;
+
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
+			address->pointer_type));
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Validate checksum for _most_ tables,
+	 * even the ones whose signature we don't recognize
+	 */
+	if (table_info->type != ACPI_TABLE_FACS) {
+		status = acpi_tb_verify_table_checksum (full_table);
+
+#if (!ACPI_CHECKSUM_ABORT)
+		if (ACPI_FAILURE (status)) {
+			/* Ignore the error if configuration says so */
+
+			status = AE_OK;
+		}
+#endif
+	}
+
+	/* Return values */
+
+	table_info->pointer     = full_table;
+	table_info->length      = (acpi_size) header->length;
+	table_info->allocation  = allocation;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
+		full_table->signature,
+		ACPI_FORMAT_UINT64 (address->pointer.physical), full_table));
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_table_ptr
+ *
+ * PARAMETERS:  table_type      - one of the defined table types
+ *              Instance        - Which table of this type
+ *              table_ptr_loc   - pointer to location to place the pointer for
+ *                                return
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the pointer to an ACPI table.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_table_ptr (
+	acpi_table_type                 table_type,
+	u32                             instance,
+	struct acpi_table_header        **table_ptr_loc)
+{
+	struct acpi_table_desc          *table_desc;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_table_ptr");
+
+
+	if (!acpi_gbl_DSDT) {
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	if (table_type > ACPI_TABLE_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * For all table types (Single/Multiple), the first
+	 * instance is always in the list head.
+	 */
+	if (instance == 1) {
+		/* Get the first */
+
+		*table_ptr_loc = NULL;
+		if (acpi_gbl_table_lists[table_type].next) {
+			*table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
+		}
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * Check for instance out of range
+	 */
+	if (instance > acpi_gbl_table_lists[table_type].count) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/* Walk the list to get the desired table
+	 * Since the if (Instance == 1) check above checked for the
+	 * first table, setting table_desc equal to the .Next member
+	 * is actually pointing to the second table.  Therefore, we
+	 * need to walk from the 2nd table until we reach the Instance
+	 * that the user is looking for and return its table pointer.
+	 */
+	table_desc = acpi_gbl_table_lists[table_type].next;
+	for (i = 2; i < instance; i++) {
+		table_desc = table_desc->next;
+	}
+
+	/* We are now pointing to the requested table's descriptor */
+
+	*table_ptr_loc = table_desc->pointer;
+
+	return_ACPI_STATUS (AE_OK);
+}
+
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
new file mode 100644
index 0000000..adc4270
--- /dev/null
+++ b/drivers/acpi/tables/tbgetall.c
@@ -0,0 +1,313 @@
+/******************************************************************************
+ *
+ * Module Name: tbgetall - Get all required ACPI tables
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbgetall")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_primary_table
+ *
+ * PARAMETERS:  Address             - Physical address of table to retrieve
+ *              *table_info         - Where the table info is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Maps the physical address of table into a logical address
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_primary_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_desc          *table_info)
+{
+	acpi_status                     status;
+	struct acpi_table_header        header;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_primary_table");
+
+
+	/* Ignore a NULL address in the RSDT */
+
+	if (!address->pointer.value) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/*
+	 * Get the header in order to get signature and table size
+	 */
+	status = acpi_tb_get_table_header (address, &header);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Clear the table_info */
+
+	ACPI_MEMSET (table_info, 0, sizeof (struct acpi_table_desc));
+
+	/*
+	 * Check the table signature and make sure it is recognized.
+	 * Also checks the header checksum
+	 */
+	table_info->pointer = &header;
+	status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get the entire table */
+
+	status = acpi_tb_get_table_body (address, &header, table_info);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Install the table */
+
+	status = acpi_tb_install_table (table_info);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_secondary_table
+ *
+ * PARAMETERS:  Address             - Physical address of table to retrieve
+ *              *table_info         - Where the table info is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Maps the physical address of table into a logical address
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_secondary_table (
+	struct acpi_pointer             *address,
+	acpi_string                     signature,
+	struct acpi_table_desc          *table_info)
+{
+	acpi_status                     status;
+	struct acpi_table_header        header;
+
+
+	ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature);
+
+
+	/* Get the header in order to match the signature */
+
+	status = acpi_tb_get_table_header (address, &header);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Signature must match request */
+
+	if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
+		ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n",
+			signature, header.signature));
+		return_ACPI_STATUS (AE_BAD_SIGNATURE);
+	}
+
+	/*
+	 * Check the table signature and make sure it is recognized.
+	 * Also checks the header checksum
+	 */
+	table_info->pointer = &header;
+	status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get the entire table */
+
+	status = acpi_tb_get_table_body (address, &header, table_info);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Install the table */
+
+	status = acpi_tb_install_table (table_info);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_required_tables
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load and validate tables other than the RSDT.  The RSDT must
+ *              already be loaded and validated.
+ *
+ *              Get the minimum set of ACPI tables, namely:
+ *
+ *              1) FADT (via RSDT in loop below)
+ *              2) FACS (via FADT)
+ *              3) DSDT (via FADT)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_required_tables (
+	void)
+{
+	acpi_status                     status = AE_OK;
+	u32                             i;
+	struct acpi_table_desc          table_info;
+	struct acpi_pointer             address;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_required_tables");
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
+		acpi_gbl_rsdt_table_count));
+
+
+	address.pointer_type  = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
+
+	/*
+	 * Loop through all table pointers found in RSDT.
+	 * This will NOT include the FACS and DSDT - we must get
+	 * them after the loop.
+	 *
+	 * The only tables we are interested in getting here is the FADT and
+	 * any SSDTs.
+	 */
+	for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
+		/* Get the table address from the common internal XSDT */
+
+		address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];
+
+		/*
+		 * Get the tables needed by this subsystem (FADT and any SSDTs).
+		 * NOTE: All other tables are completely ignored at this time.
+		 */
+		status = acpi_tb_get_primary_table (&address, &table_info);
+		if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
+			ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
+				acpi_format_exception (status),
+				ACPI_FORMAT_UINT64 (address.pointer.value)));
+		}
+	}
+
+	/* We must have a FADT to continue */
+
+	if (!acpi_gbl_FADT) {
+		ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	/*
+	 * Convert the FADT to a common format.  This allows earlier revisions of the
+	 * table to coexist with newer versions, using common access code.
+	 */
+	status = acpi_tb_convert_table_fadt ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Get the FACS (Pointed to by the FADT)
+	 */
+	address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;
+
+	status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
+			acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Create the common FACS pointer table
+	 * (Contains pointers to the original table)
+	 */
+	status = acpi_tb_build_common_facs (&table_info);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Get/install the DSDT (Pointed to by the FADT)
+	 */
+	address.pointer.value = acpi_gbl_FADT->Xdsdt;
+
+	status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
+		return_ACPI_STATUS (status);
+	}
+
+	/* Set Integer Width (32/64) based upon DSDT revision */
+
+	acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);
+
+	/* Dump the entire DSDT */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
+		"Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
+		acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
+	ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
+
+	/* Always delete the RSDP mapping, we are done with it */
+
+	acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP);
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
new file mode 100644
index 0000000..85d5bb0
--- /dev/null
+++ b/drivers/acpi/tables/tbinstal.c
@@ -0,0 +1,553 @@
+/******************************************************************************
+ *
+ * Module Name: tbinstal - ACPI table installation and removal
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbinstal")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_match_signature
+ *
+ * PARAMETERS:  Signature           - Table signature to match
+ *              table_info          - Return data
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned"
+ *              tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_match_signature (
+	char                            *signature,
+	struct acpi_table_desc          *table_info,
+	u8                              search_type)
+{
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("tb_match_signature");
+
+
+	/*
+	 * Search for a signature match among the known table types
+	 */
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+		if (!(acpi_gbl_table_data[i].flags & search_type)) {
+			continue;
+		}
+
+		if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature,
+				   acpi_gbl_table_data[i].sig_length)) {
+			/* Found a signature match, return index if requested */
+
+			if (table_info) {
+				table_info->type = (u8) i;
+			}
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+				"Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
+				(char *) acpi_gbl_table_data[i].signature));
+
+			return_ACPI_STATUS (AE_OK);
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n",
+		(char *) signature));
+
+	return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_install_table
+ *
+ * PARAMETERS:  table_info          - Return value from acpi_tb_get_table_body
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load and validate all tables other than the RSDT.  The RSDT must
+ *              already be loaded and validated.
+ *              Install the table into the global data structs.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_install_table (
+	struct acpi_table_desc          *table_info)
+{
+	acpi_status                     status;
+
+	ACPI_FUNCTION_TRACE ("tb_install_table");
+
+
+	/* Lock tables while installing */
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n",
+			table_info->pointer->signature, acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	/* Install the table into the global data structure */
+
+	status = acpi_tb_init_table_descriptor (table_info->type, table_info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n",
+			table_info->pointer->signature, acpi_format_exception (status)));
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
+		acpi_gbl_table_data[table_info->type].name, table_info->pointer));
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_recognize_table
+ *
+ * PARAMETERS:  table_info          - Return value from acpi_tb_get_table_body
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check a table signature for a match against known table types
+ *
+ * NOTE:  All table pointers are validated as follows:
+ *          1) Table pointer must point to valid physical memory
+ *          2) Signature must be 4 ASCII chars, even if we don't recognize the
+ *             name
+ *          3) Table must be readable for length specified in the header
+ *          4) Table checksum must be valid (with the exception of the FACS
+ *             which has no checksum for some odd reason)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_recognize_table (
+	struct acpi_table_desc          *table_info,
+	u8                              search_type)
+{
+	struct acpi_table_header        *table_header;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("tb_recognize_table");
+
+
+	/* Ensure that we have a valid table pointer */
+
+	table_header = (struct acpi_table_header *) table_info->pointer;
+	if (!table_header) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * We only "recognize" a limited number of ACPI tables -- namely, the
+	 * ones that are used by the subsystem (DSDT, FADT, etc.)
+	 *
+	 * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized.
+	 * This can be any one of many valid ACPI tables, it just isn't one of
+	 * the tables that is consumed by the core subsystem
+	 */
+	status = acpi_tb_match_signature (table_header->signature, table_info, search_type);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_tb_validate_table_header (table_header);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Return the table type and length via the info struct */
+
+	table_info->length = (acpi_size) table_header->length;
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_init_table_descriptor
+ *
+ * PARAMETERS:  table_type          - The type of the table
+ *              table_info          - A table info struct
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Install a table into the global data structs.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_init_table_descriptor (
+	acpi_table_type                 table_type,
+	struct acpi_table_desc          *table_info)
+{
+	struct acpi_table_list          *list_head;
+	struct acpi_table_desc          *table_desc;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type);
+
+
+	/* Allocate a descriptor for this table */
+
+	table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+	if (!table_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * Install the table into the global data structure
+	 */
+	list_head = &acpi_gbl_table_lists[table_type];
+
+	/*
+	 * Two major types of tables:  1) Only one instance is allowed.  This
+	 * includes most ACPI tables such as the DSDT.  2) Multiple instances of
+	 * the table are allowed.  This includes SSDT and PSDTs.
+	 */
+	if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
+		/*
+		 * Only one table allowed, and a table has alread been installed
+		 * at this location, so return an error.
+		 */
+		if (list_head->next) {
+			ACPI_MEM_FREE (table_desc);
+			return_ACPI_STATUS (AE_ALREADY_EXISTS);
+		}
+
+		table_desc->next = list_head->next;
+		list_head->next = table_desc;
+
+		if (table_desc->next) {
+			table_desc->next->prev = table_desc;
+		}
+
+		list_head->count++;
+	}
+	else {
+		/*
+		 * Link the new table in to the list of tables of this type.
+		 * Insert at the end of the list, order IS IMPORTANT.
+		 *
+		 * table_desc->Prev & Next are already NULL from calloc()
+		 */
+		list_head->count++;
+
+		if (!list_head->next) {
+			list_head->next = table_desc;
+		}
+		else {
+			table_desc->next = list_head->next;
+
+			while (table_desc->next->next) {
+				table_desc->next = table_desc->next->next;
+			}
+
+			table_desc->next->next = table_desc;
+			table_desc->prev = table_desc->next;
+			table_desc->next = NULL;
+		}
+	}
+
+	/* Finish initialization of the table descriptor */
+
+	table_desc->type                = (u8) table_type;
+	table_desc->pointer             = table_info->pointer;
+	table_desc->length              = table_info->length;
+	table_desc->allocation          = table_info->allocation;
+	table_desc->aml_start           = (u8 *) (table_desc->pointer + 1),
+	table_desc->aml_length          = (u32) (table_desc->length -
+			 (u32) sizeof (struct acpi_table_header));
+	table_desc->table_id            = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_TABLE);
+	table_desc->loaded_into_namespace = FALSE;
+
+	/*
+	 * Set the appropriate global pointer (if there is one) to point to the
+	 * newly installed table
+	 */
+	if (acpi_gbl_table_data[table_type].global_ptr) {
+		*(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer;
+	}
+
+	/* Return Data */
+
+	table_info->table_id        = table_desc->table_id;
+	table_info->installed_desc  = table_desc;
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_delete_all_tables
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete all internal ACPI tables
+ *
+ ******************************************************************************/
+
+void
+acpi_tb_delete_all_tables (void)
+{
+	acpi_table_type                 type;
+
+
+	/*
+	 * Free memory allocated for ACPI tables
+	 * Memory can either be mapped or allocated
+	 */
+	for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) {
+		acpi_tb_delete_tables_by_type (type);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_delete_tables_by_type
+ *
+ * PARAMETERS:  Type                - The table type to be deleted
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete an internal ACPI table
+ *              Locks the ACPI table mutex
+ *
+ ******************************************************************************/
+
+void
+acpi_tb_delete_tables_by_type (
+	acpi_table_type                 type)
+{
+	struct acpi_table_desc          *table_desc;
+	u32                             count;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type);
+
+
+	if (type > ACPI_TABLE_MAX) {
+		return_VOID;
+	}
+
+	if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_TABLES))) {
+		return;
+	}
+
+	/* Clear the appropriate "typed" global table pointer */
+
+	switch (type) {
+	case ACPI_TABLE_RSDP:
+		acpi_gbl_RSDP = NULL;
+		break;
+
+	case ACPI_TABLE_DSDT:
+		acpi_gbl_DSDT = NULL;
+		break;
+
+	case ACPI_TABLE_FADT:
+		acpi_gbl_FADT = NULL;
+		break;
+
+	case ACPI_TABLE_FACS:
+		acpi_gbl_FACS = NULL;
+		break;
+
+	case ACPI_TABLE_XSDT:
+		acpi_gbl_XSDT = NULL;
+		break;
+
+	case ACPI_TABLE_SSDT:
+	case ACPI_TABLE_PSDT:
+	default:
+		break;
+	}
+
+	/*
+	 * Free the table
+	 * 1) Get the head of the list
+	 */
+	table_desc = acpi_gbl_table_lists[type].next;
+	count     = acpi_gbl_table_lists[type].count;
+
+	/*
+	 * 2) Walk the entire list, deleting both the allocated tables
+	 *    and the table descriptors
+	 */
+	for (i = 0; i < count; i++) {
+		table_desc = acpi_tb_uninstall_table (table_desc);
+	}
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_delete_single_table
+ *
+ * PARAMETERS:  table_info          - A table info struct
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Low-level free for a single ACPI table.  Handles cases where
+ *              the table was allocated a buffer or was mapped.
+ *
+ ******************************************************************************/
+
+void
+acpi_tb_delete_single_table (
+	struct acpi_table_desc          *table_desc)
+{
+
+	/* Must have a valid table descriptor and pointer */
+
+	if ((!table_desc) ||
+		 (!table_desc->pointer)) {
+		return;
+	}
+
+	/* Valid table, determine type of memory allocation */
+
+	switch (table_desc->allocation) {
+	case ACPI_MEM_NOT_ALLOCATED:
+		break;
+
+	case ACPI_MEM_ALLOCATED:
+
+		ACPI_MEM_FREE (table_desc->pointer);
+		break;
+
+	case ACPI_MEM_MAPPED:
+
+		acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
+		break;
+
+	default:
+		break;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_uninstall_table
+ *
+ * PARAMETERS:  table_info          - A table info struct
+ *
+ * RETURN:      Pointer to the next table in the list (of same type)
+ *
+ * DESCRIPTION: Free the memory associated with an internal ACPI table that
+ *              is either installed or has never been installed.
+ *              Table mutex should be locked.
+ *
+ ******************************************************************************/
+
+struct acpi_table_desc *
+acpi_tb_uninstall_table (
+	struct acpi_table_desc          *table_desc)
+{
+	struct acpi_table_desc          *next_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc);
+
+
+	if (!table_desc) {
+		return_PTR (NULL);
+	}
+
+	/* Unlink the descriptor from the doubly linked list */
+
+	if (table_desc->prev) {
+		table_desc->prev->next = table_desc->next;
+	}
+	else {
+		/* Is first on list, update list head */
+
+		acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
+	}
+
+	if (table_desc->next) {
+		table_desc->next->prev = table_desc->prev;
+	}
+
+	/* Free the memory allocated for the table itself */
+
+	acpi_tb_delete_single_table (table_desc);
+
+	/* Free the table descriptor */
+
+	next_desc = table_desc->next;
+	ACPI_MEM_FREE (table_desc);
+
+	/* Return pointer to the next descriptor */
+
+	return_PTR (next_desc);
+}
+
+
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
new file mode 100644
index 0000000..9c69132
--- /dev/null
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -0,0 +1,324 @@
+/******************************************************************************
+ *
+ * Module Name: tbrsdt - ACPI RSDT table utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbrsdt")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_verify_rsdp
+ *
+ * PARAMETERS:  Address         - RSDP (Pointer to RSDT)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_verify_rsdp (
+	struct acpi_pointer             *address)
+{
+	struct acpi_table_desc          table_info;
+	acpi_status                     status;
+	struct rsdp_descriptor          *rsdp;
+
+
+	ACPI_FUNCTION_TRACE ("tb_verify_rsdp");
+
+
+	switch (address->pointer_type) {
+	case ACPI_LOGICAL_POINTER:
+
+		rsdp = address->pointer.logical;
+		break;
+
+	case ACPI_PHYSICAL_POINTER:
+		/*
+		 * Obtain access to the RSDP structure
+		 */
+		status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor),
+				  (void *) &rsdp);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 *  The signature and checksum must both be correct
+	 */
+	if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+		/* Nope, BAD Signature */
+
+		status = AE_BAD_SIGNATURE;
+		goto cleanup;
+	}
+
+	/* Check the standard checksum */
+
+	if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
+		status = AE_BAD_CHECKSUM;
+		goto cleanup;
+	}
+
+	/* Check extended checksum if table version >= 2 */
+
+	if (rsdp->revision >= 2) {
+		if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
+			status = AE_BAD_CHECKSUM;
+			goto cleanup;
+		}
+	}
+
+	/* The RSDP supplied is OK */
+
+	table_info.pointer     = ACPI_CAST_PTR (struct acpi_table_header, rsdp);
+	table_info.length      = sizeof (struct rsdp_descriptor);
+	table_info.allocation  = ACPI_MEM_MAPPED;
+
+	/* Save the table pointers and allocation info */
+
+	status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Save the RSDP in a global for easy access */
+
+	acpi_gbl_RSDP = ACPI_CAST_PTR (struct rsdp_descriptor, table_info.pointer);
+	return_ACPI_STATUS (status);
+
+
+	/* Error exit */
+cleanup:
+
+	if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
+		acpi_os_unmap_memory (rsdp, sizeof (struct rsdp_descriptor));
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_rsdt_address
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      RSDT physical address
+ *
+ * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
+ *              version of the RSDP
+ *
+ ******************************************************************************/
+
+void
+acpi_tb_get_rsdt_address (
+	struct acpi_pointer             *out_address)
+{
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
+
+	/*
+	 * For RSDP revision 0 or 1, we use the RSDT.
+	 * For RSDP revision 2 (and above), we use the XSDT
+	 */
+	if (acpi_gbl_RSDP->revision < 2) {
+		out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
+	}
+	else {
+		out_address->pointer.value = acpi_gbl_RSDP->xsdt_physical_address;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_validate_rsdt
+ *
+ * PARAMETERS:  table_ptr       - Addressable pointer to the RSDT.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validate signature for the RSDT or XSDT
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_validate_rsdt (
+	struct acpi_table_header        *table_ptr)
+{
+	int                             no_match;
+
+
+	ACPI_FUNCTION_NAME ("tb_validate_rsdt");
+
+
+	/*
+	 * For RSDP revision 0 or 1, we use the RSDT.
+	 * For RSDP revision 2 and above, we use the XSDT
+	 */
+	if (acpi_gbl_RSDP->revision < 2) {
+		no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
+				  sizeof (RSDT_SIG) -1);
+	}
+	else {
+		no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
+				  sizeof (XSDT_SIG) -1);
+	}
+
+	if (no_match) {
+		/* Invalid RSDT or XSDT signature */
+
+		ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
+
+		ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
+			"RSDT/XSDT signature at %X (%p) is invalid\n",
+			acpi_gbl_RSDP->rsdt_physical_address,
+			(void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address));
+
+		if (acpi_gbl_RSDP->revision < 2) {
+			ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n"))
+		}
+		else {
+			ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n"))
+		}
+
+		ACPI_DUMP_BUFFER ((char *) table_ptr, 48);
+
+		return (AE_BAD_SIGNATURE);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_get_table_rsdt
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_get_table_rsdt (
+	void)
+{
+	struct acpi_table_desc          table_info;
+	acpi_status                     status;
+	struct acpi_pointer             address;
+
+
+	ACPI_FUNCTION_TRACE ("tb_get_table_rsdt");
+
+
+	/* Get the RSDT/XSDT via the RSDP */
+
+	acpi_tb_get_rsdt_address (&address);
+
+	table_info.type = ACPI_TABLE_XSDT;
+	status = acpi_tb_get_table (&address, &table_info);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
+			acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
+		acpi_gbl_RSDP,
+		ACPI_FORMAT_UINT64 (address.pointer.value)));
+
+	/* Check the RSDT or XSDT signature */
+
+	status = acpi_tb_validate_rsdt (table_info.pointer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get the number of tables defined in the RSDT or XSDT */
+
+	acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer);
+
+	/* Convert and/or copy to an XSDT structure */
+
+	status = acpi_tb_convert_to_xsdt (&table_info);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Save the table pointers and allocation info */
+
+	status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	acpi_gbl_XSDT = ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info.pointer);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
new file mode 100644
index 0000000..fede580
--- /dev/null
+++ b/drivers/acpi/tables/tbutils.c
@@ -0,0 +1,240 @@
+/******************************************************************************
+ *
+ * Module Name: tbutils - Table manipulation utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbutils")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_handle_to_object
+ *
+ * PARAMETERS:  table_id            - Id for which the function is searching
+ *              table_desc          - Pointer to return the matching table
+ *                                      descriptor.
+ *
+ * RETURN:      Search the tables to find one with a matching table_id and
+ *              return a pointer to that table descriptor.
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_tb_handle_to_object (
+	u16                             table_id,
+	struct acpi_table_desc          **return_table_desc)
+{
+	u32                             i;
+	struct acpi_table_desc          *table_desc;
+
+
+	ACPI_FUNCTION_NAME ("tb_handle_to_object");
+
+
+	for (i = 0; i < ACPI_TABLE_MAX; i++) {
+		table_desc = acpi_gbl_table_lists[i].next;
+		while (table_desc) {
+			if (table_desc->table_id == table_id) {
+				*return_table_desc = table_desc;
+				return (AE_OK);
+			}
+
+			table_desc = table_desc->next;
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
+	return (AE_BAD_PARAMETER);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_validate_table_header
+ *
+ * PARAMETERS:  table_header        - Logical pointer to the table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check an ACPI table header for validity
+ *
+ * NOTE:  Table pointers are validated as follows:
+ *          1) Table pointer must point to valid physical memory
+ *          2) Signature must be 4 ASCII chars, even if we don't recognize the
+ *             name
+ *          3) Table must be readable for length specified in the header
+ *          4) Table checksum must be valid (with the exception of the FACS
+ *              which has no checksum because it contains variable fields)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_validate_table_header (
+	struct acpi_table_header        *table_header)
+{
+	acpi_name                       signature;
+
+
+	ACPI_FUNCTION_NAME ("tb_validate_table_header");
+
+
+	/* Verify that this is a valid address */
+
+	if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Cannot read table header at %p\n", table_header));
+		return (AE_BAD_ADDRESS);
+	}
+
+	/* Ensure that the signature is 4 ASCII characters */
+
+	ACPI_MOVE_32_TO_32 (&signature, table_header->signature);
+	if (!acpi_ut_valid_acpi_name (signature)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Table signature at %p [%p] has invalid characters\n",
+			table_header, &signature));
+
+		ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
+			(char *) &signature));
+		ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
+		return (AE_BAD_SIGNATURE);
+	}
+
+	/* Validate the table length */
+
+	if (table_header->length < sizeof (struct acpi_table_header)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Invalid length in table header %p name %4.4s\n",
+			table_header, (char *) &signature));
+
+		ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
+			(u32) table_header->length));
+		ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
+		return (AE_BAD_HEADER);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_verify_table_checksum
+ *
+ * PARAMETERS:  *table_header           - ACPI table to verify
+ *
+ * RETURN:      8 bit checksum of table
+ *
+ * DESCRIPTION: Does an 8 bit checksum of table and returns status.  A correct
+ *              table should have a checksum of 0.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_verify_table_checksum (
+	struct acpi_table_header        *table_header)
+{
+	u8                              checksum;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("tb_verify_table_checksum");
+
+
+	/* Compute the checksum on the table */
+
+	checksum = acpi_tb_checksum (table_header, table_header->length);
+
+	/* Return the appropriate exception */
+
+	if (checksum) {
+		ACPI_REPORT_WARNING (("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
+			table_header->signature, (u32) table_header->checksum, (u32) checksum));
+
+		status = AE_BAD_CHECKSUM;
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_checksum
+ *
+ * PARAMETERS:  Buffer              - Buffer to checksum
+ *              Length              - Size of the buffer
+ *
+ * RETURNS      8 bit checksum of buffer
+ *
+ * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
+ *
+ ******************************************************************************/
+
+u8
+acpi_tb_checksum (
+	void                            *buffer,
+	u32                             length)
+{
+	const u8                        *limit;
+	const u8                        *rover;
+	u8                              sum = 0;
+
+
+	if (buffer && length) {
+		/*  Buffer and Length are valid   */
+
+		limit = (u8 *) buffer + length;
+
+		for (rover = buffer; rover < limit; rover++) {
+			sum = (u8) (sum + *rover);
+		}
+	}
+	return (sum);
+}
+
+
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
new file mode 100644
index 0000000..7715043
--- /dev/null
+++ b/drivers/acpi/tables/tbxface.c
@@ -0,0 +1,448 @@
+/******************************************************************************
+ *
+ * Module Name: tbxface - Public interfaces to the ACPI subsystem
+ *                         ACPI table oriented interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_load_tables
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to load the ACPI tables from the
+ *              provided RSDT
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_load_tables (void)
+{
+	struct acpi_pointer             rsdp_address;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_load_tables");
+
+
+	/* Get the RSDP */
+
+	status = acpi_os_get_root_pointer (ACPI_LOGICAL_ADDRESSING,
+			  &rsdp_address);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("acpi_load_tables: Could not get RSDP, %s\n",
+				  acpi_format_exception (status)));
+		goto error_exit;
+	}
+
+	/* Map and validate the RSDP */
+
+	acpi_gbl_table_flags = rsdp_address.pointer_type;
+
+	status = acpi_tb_verify_rsdp (&rsdp_address);
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("acpi_load_tables: RSDP Failed validation: %s\n",
+				  acpi_format_exception (status)));
+		goto error_exit;
+	}
+
+	/* Get the RSDT via the RSDP */
+
+	status = acpi_tb_get_table_rsdt ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("acpi_load_tables: Could not load RSDT: %s\n",
+				  acpi_format_exception (status)));
+		goto error_exit;
+	}
+
+	/* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */
+
+	status = acpi_tb_get_required_tables ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
+				  acpi_format_exception (status)));
+		goto error_exit;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
+
+
+	/* Load the namespace from the tables */
+
+	status = acpi_ns_load_namespace ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("acpi_load_tables: Could not load namespace: %s\n",
+				  acpi_format_exception (status)));
+		goto error_exit;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+	ACPI_REPORT_ERROR (("acpi_load_tables: Could not load tables: %s\n",
+			  acpi_format_exception (status)));
+
+	return_ACPI_STATUS (status);
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_load_table
+ *
+ * PARAMETERS:  table_ptr       - pointer to a buffer containing the entire
+ *                                table to be loaded
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to load a table from the caller's
+ *              buffer.  The buffer must contain an entire ACPI Table including
+ *              a valid header.  The header fields will be verified, and if it
+ *              is determined that the table is invalid, the call will fail.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_load_table (
+	struct acpi_table_header        *table_ptr)
+{
+	acpi_status                     status;
+	struct acpi_table_desc          table_info;
+	struct acpi_pointer             address;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_load_table");
+
+
+	if (!table_ptr) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Copy the table to a local buffer */
+
+	address.pointer_type    = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
+	address.pointer.logical = table_ptr;
+
+	status = acpi_tb_get_table_body (&address, table_ptr, &table_info);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Install the new table into the local data structures */
+
+	status = acpi_tb_install_table (&table_info);
+	if (ACPI_FAILURE (status)) {
+		/* Free table allocated by acpi_tb_get_table_body */
+
+		acpi_tb_delete_single_table (&table_info);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Convert the table to common format if necessary */
+
+	switch (table_info.type) {
+	case ACPI_TABLE_FADT:
+
+		status = acpi_tb_convert_table_fadt ();
+		break;
+
+	case ACPI_TABLE_FACS:
+
+		status = acpi_tb_build_common_facs (&table_info);
+		break;
+
+	default:
+		/* Load table into namespace if it contains executable AML */
+
+		status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
+		break;
+	}
+
+	if (ACPI_FAILURE (status)) {
+		/* Uninstall table and free the buffer */
+
+		(void) acpi_tb_uninstall_table (table_info.installed_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_unload_table
+ *
+ * PARAMETERS:  table_type    - Type of table to be unloaded
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This routine is used to force the unload of a table
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_unload_table (
+	acpi_table_type                 table_type)
+{
+	struct acpi_table_desc          *table_desc;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_unload_table");
+
+
+	/* Parameter validation */
+
+	if (table_type > ACPI_TABLE_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+
+	/* Find all tables of the requested type */
+
+	table_desc = acpi_gbl_table_lists[table_type].next;
+	while (table_desc) {
+		/*
+		 * Delete all namespace entries owned by this table.  Note that these
+		 * entries can appear anywhere in the namespace by virtue of the AML
+		 * "Scope" operator.  Thus, we need to track ownership by an ID, not
+		 * simply a position within the hierarchy
+		 */
+		acpi_ns_delete_namespace_by_owner (table_desc->table_id);
+
+		table_desc = table_desc->next;
+	}
+
+	/* Delete (or unmap) all tables of this type */
+
+	acpi_tb_delete_tables_by_type (table_type);
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_table_header
+ *
+ * PARAMETERS:  table_type      - one of the defined table types
+ *              Instance        - the non zero instance of the table, allows
+ *                                support for multiple tables of the same type
+ *                                see acpi_gbl_acpi_table_flag
+ *              out_table_header - pointer to the struct acpi_table_header if successful
+ *
+ * DESCRIPTION: This function is called to get an ACPI table header.  The caller
+ *              supplies an pointer to a data area sufficient to contain an ACPI
+ *              struct acpi_table_header structure.
+ *
+ *              The header contains a length field that can be used to determine
+ *              the size of the buffer needed to contain the entire table.  This
+ *              function is not valid for the RSD PTR table since it does not
+ *              have a standard header and is fixed length.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_table_header (
+	acpi_table_type                 table_type,
+	u32                             instance,
+	struct acpi_table_header        *out_table_header)
+{
+	struct acpi_table_header        *tbl_ptr;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_table_header");
+
+
+	if ((instance == 0)                 ||
+		(table_type == ACPI_TABLE_RSDP) ||
+		(!out_table_header)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Check the table type and instance */
+
+	if ((table_type > ACPI_TABLE_MAX)   ||
+		(ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
+		 instance > 1)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+
+	/* Get a pointer to the entire table */
+
+	status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * The function will return a NULL pointer if the table is not loaded
+	 */
+	if (tbl_ptr == NULL) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/*
+	 * Copy the header to the caller's buffer
+	 */
+	ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr,
+			 sizeof (struct acpi_table_header));
+
+	return_ACPI_STATUS (status);
+}
+
+
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_table
+ *
+ * PARAMETERS:  table_type      - one of the defined table types
+ *              Instance        - the non zero instance of the table, allows
+ *                                support for multiple tables of the same type
+ *                                see acpi_gbl_acpi_table_flag
+ *              ret_buffer      - pointer to a structure containing a buffer to
+ *                                receive the table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get an ACPI table.  The caller
+ *              supplies an out_buffer large enough to contain the entire ACPI
+ *              table.  The caller should call the acpi_get_table_header function
+ *              first to determine the buffer size needed.  Upon completion
+ *              the out_buffer->Length field will indicate the number of bytes
+ *              copied into the out_buffer->buf_ptr buffer. This table will be
+ *              a complete table including the header.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_table (
+	acpi_table_type                 table_type,
+	u32                             instance,
+	struct acpi_buffer              *ret_buffer)
+{
+	struct acpi_table_header        *tbl_ptr;
+	acpi_status                     status;
+	acpi_size                       table_length;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_table");
+
+
+	/* Parameter validation */
+
+	if (instance == 0) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_validate_buffer (ret_buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Check the table type and instance */
+
+	if ((table_type > ACPI_TABLE_MAX)   ||
+		(ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
+		 instance > 1)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+
+	/* Get a pointer to the entire table */
+
+	status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * acpi_tb_get_table_ptr will return a NULL pointer if the
+	 * table is not loaded.
+	 */
+	if (tbl_ptr == NULL) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+
+	/* Get the table length */
+
+	if (table_type == ACPI_TABLE_RSDP) {
+		/*
+		 *  RSD PTR is the only "table" without a header
+		 */
+		table_length = sizeof (struct rsdp_descriptor);
+	}
+	else {
+		table_length = (acpi_size) tbl_ptr->length;
+	}
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (ret_buffer, table_length);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Copy the table to the buffer */
+
+	ACPI_MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, table_length);
+	return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_get_table);
+
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
new file mode 100644
index 0000000..6e8072e
--- /dev/null
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -0,0 +1,606 @@
+/******************************************************************************
+ *
+ * Module Name: tbxfroot - Find the root ACPI table (RSDT)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
+
+
+#define _COMPONENT          ACPI_TABLES
+	 ACPI_MODULE_NAME    ("tbxfroot")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_find_table
+ *
+ * PARAMETERS:  Signature           - String with ACPI table signature
+ *              oem_id              - String with the table OEM ID
+ *              oem_table_id        - String with the OEM Table ID.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
+ *              Signature, OEM ID and OEM Table ID.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_find_table (
+	char                            *signature,
+	char                            *oem_id,
+	char                            *oem_table_id,
+	struct acpi_table_header        **table_ptr)
+{
+	acpi_status                     status;
+	struct acpi_table_header        *table;
+
+
+	ACPI_FUNCTION_TRACE ("tb_find_table");
+
+
+	/* Validate string lengths */
+
+	if ((ACPI_STRLEN (signature)  > ACPI_NAME_SIZE) ||
+		(ACPI_STRLEN (oem_id)     > sizeof (table->oem_id)) ||
+		(ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) {
+		return_ACPI_STATUS (AE_AML_STRING_LIMIT);
+	}
+
+	if (!ACPI_STRNCMP (signature, DSDT_SIG, ACPI_NAME_SIZE)) {
+		/*
+		 * The DSDT pointer is contained in the FADT, not the RSDT.
+		 * This code should suffice, because the only code that would perform
+		 * a "find" on the DSDT is the data_table_region() AML opcode -- in
+		 * which case, the DSDT is guaranteed to be already loaded.
+		 * If this becomes insufficient, the FADT will have to be found first.
+		 */
+		if (!acpi_gbl_DSDT) {
+			return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+		}
+
+		table = acpi_gbl_DSDT;
+	}
+	else {
+		/* Find the table */
+
+		status = acpi_get_firmware_table (signature, 1,
+				   ACPI_LOGICAL_ADDRESSING, &table);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Check oem_id and oem_table_id */
+
+	if ((oem_id[0]     && ACPI_STRNCMP (
+			 oem_id, table->oem_id, sizeof (table->oem_id))) ||
+		(oem_table_id[0] && ACPI_STRNCMP (
+				   oem_table_id, table->oem_table_id, sizeof (table->oem_table_id)))) {
+		return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", table->signature));
+	*table_ptr = table;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_firmware_table
+ *
+ * PARAMETERS:  Signature       - Any ACPI table signature
+ *              Instance        - the non zero instance of the table, allows
+ *                                support for multiple tables of the same type
+ *              Flags           - Physical/Virtual support
+ *              table_pointer   - Where a buffer containing the table is
+ *                                returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get an ACPI table. A buffer is
+ *              allocated for the table and returned in table_pointer.
+ *              This table will be a complete table including the header.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_firmware_table (
+	acpi_string                     signature,
+	u32                             instance,
+	u32                             flags,
+	struct acpi_table_header        **table_pointer)
+{
+	acpi_status                     status;
+	struct acpi_pointer             address;
+	struct acpi_table_header        *header = NULL;
+	struct acpi_table_desc          *table_info = NULL;
+	struct acpi_table_desc          *rsdt_info;
+	u32                             table_count;
+	u32                             i;
+	u32                             j;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_firmware_table");
+
+
+	/*
+	 * Ensure that at least the table manager is initialized.  We don't
+	 * require that the entire ACPI subsystem is up for this interface.
+	 * If we have a buffer, we must have a length too
+	 */
+	if ((instance == 0)     ||
+		(!signature)        ||
+		(!table_pointer)) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Ensure that we have a RSDP */
+
+	if (!acpi_gbl_RSDP) {
+		/* Get the RSDP */
+
+		status = acpi_os_get_root_pointer (flags, &address);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n"));
+			return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+		}
+
+		/* Map and validate the RSDP */
+
+		if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
+			status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor),
+					  (void *) &acpi_gbl_RSDP);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+		else {
+			acpi_gbl_RSDP = address.pointer.logical;
+		}
+
+		/* The signature and checksum must both be correct */
+
+		if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+			/* Nope, BAD Signature */
+
+			return_ACPI_STATUS (AE_BAD_SIGNATURE);
+		}
+
+		if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
+			/* Nope, BAD Checksum */
+
+			return_ACPI_STATUS (AE_BAD_CHECKSUM);
+		}
+	}
+
+	/* Get the RSDT address via the RSDP */
+
+	acpi_tb_get_rsdt_address (&address);
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
+		acpi_gbl_RSDP,
+		ACPI_FORMAT_UINT64 (address.pointer.value)));
+
+	/* Insert processor_mode flags */
+
+	address.pointer_type |= flags;
+
+	/* Get and validate the RSDT */
+
+	rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+	if (!rsdt_info) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	status = acpi_tb_get_table (&address, rsdt_info);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	status = acpi_tb_validate_rsdt (rsdt_info->pointer);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Allocate a scratch table header and table descriptor */
+
+	header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header));
+	if (!header) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc));
+	if (!table_info) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/* Get the number of table pointers within the RSDT */
+
+	table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer);
+	address.pointer_type = acpi_gbl_table_flags | flags;
+
+	/*
+	 * Search the RSDT/XSDT for the correct instance of the
+	 * requested table
+	 */
+	for (i = 0, j = 0; i < table_count; i++) {
+		/* Get the next table pointer, handle RSDT vs. XSDT */
+
+		if (acpi_gbl_RSDP->revision < 2) {
+			address.pointer.value = (ACPI_CAST_PTR (
+				RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
+		}
+		else {
+			address.pointer.value = (ACPI_CAST_PTR (
+				XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
+		}
+
+		/* Get the table header */
+
+		status = acpi_tb_get_table_header (&address, header);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+
+		/* Compare table signatures and table instance */
+
+		if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) {
+			/* An instance of the table was found */
+
+			j++;
+			if (j >= instance) {
+				/* Found the correct instance, get the entire table */
+
+				status = acpi_tb_get_table_body (&address, header, table_info);
+				if (ACPI_FAILURE (status)) {
+					goto cleanup;
+				}
+
+				*table_pointer = table_info->pointer;
+				goto cleanup;
+			}
+		}
+	}
+
+	/* Did not find the table */
+
+	status = AE_NOT_EXIST;
+
+
+cleanup:
+	acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length);
+	ACPI_MEM_FREE (rsdt_info);
+
+	if (header) {
+		ACPI_MEM_FREE (header);
+	}
+	if (table_info) {
+		ACPI_MEM_FREE (table_info);
+	}
+	return_ACPI_STATUS (status);
+}
+EXPORT_SYMBOL(acpi_get_firmware_table);
+
+
+/* TBD: Move to a new file */
+
+#if ACPI_MACHINE_WIDTH != 16
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_find_root_pointer
+ *
+ * PARAMETERS:  **rsdp_address          - Where to place the RSDP address
+ *              Flags                   - Logical/Physical addressing
+ *
+ * RETURN:      Status, Physical address of the RSDP
+ *
+ * DESCRIPTION: Find the RSDP
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_find_root_pointer (
+	u32                             flags,
+	struct acpi_pointer             *rsdp_address)
+{
+	struct acpi_table_desc          table_info;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_find_root_pointer");
+
+
+	/* Get the RSDP */
+
+	status = acpi_tb_find_rsdp (&table_info, flags);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"RSDP structure not found, %s Flags=%X\n",
+			acpi_format_exception (status), flags));
+		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+	}
+
+	rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER;
+	rsdp_address->pointer.physical = table_info.physical_address;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_scan_memory_for_rsdp
+ *
+ * PARAMETERS:  start_address       - Starting pointer for search
+ *              Length              - Maximum length to search
+ *
+ * RETURN:      Pointer to the RSDP if found, otherwise NULL.
+ *
+ * DESCRIPTION: Search a block of memory for the RSDP signature
+ *
+ ******************************************************************************/
+
+u8 *
+acpi_tb_scan_memory_for_rsdp (
+	u8                              *start_address,
+	u32                             length)
+{
+	u8                              *mem_rover;
+	u8                              *end_address;
+	u8                              checksum;
+
+
+	ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");
+
+
+	end_address = start_address + length;
+
+	/* Search from given start address for the requested length */
+
+	for (mem_rover = start_address; mem_rover < end_address;
+		 mem_rover += ACPI_RSDP_SCAN_STEP) {
+		/* The signature and checksum must both be correct */
+
+		if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+			/* No signature match, keep looking */
+
+			continue;
+		}
+
+		/* Signature matches, check the appropriate checksum */
+
+		if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) {
+			/* ACPI version 1.0 */
+
+			checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH);
+		}
+		else {
+			/* Post ACPI 1.0, use extended_checksum */
+
+			checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
+		}
+
+		if (checksum == 0) {
+			/* Checksum valid, we have found a valid RSDP */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+				"RSDP located at physical address %p\n", mem_rover));
+			return_PTR (mem_rover);
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"Found an RSDP at physical address %p, but it has a bad checksum\n",
+			mem_rover));
+	}
+
+	/* Searched entire block, no RSDP was found */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"Searched entire block, no valid RSDP was found.\n"));
+	return_PTR (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_find_rsdp
+ *
+ * PARAMETERS:  *table_info             - Where the table info is returned
+ *              Flags                   - Current memory mode (logical vs.
+ *                                        physical addressing)
+ *
+ * RETURN:      Status, RSDP physical address
+ *
+ * DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor
+ *              pointer structure.  If it is found, set *RSDP to point to it.
+ *
+ *              NOTE1: The RSDp must be either in the first 1_k of the Extended
+ *              BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
+ *              Only a 32-bit physical address is necessary.
+ *
+ *              NOTE2: This function is always available, regardless of the
+ *              initialization state of the rest of ACPI.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_find_rsdp (
+	struct acpi_table_desc          *table_info,
+	u32                             flags)
+{
+	u8                              *table_ptr;
+	u8                              *mem_rover;
+	u32                             physical_address;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("tb_find_rsdp");
+
+
+	/*
+	 * Scan supports either 1) Logical addressing or 2) Physical addressing
+	 */
+	if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
+		/*
+		 * 1a) Get the location of the EBDA
+		 */
+		status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
+				  ACPI_EBDA_PTR_LENGTH,
+				  (void *) &table_ptr);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not map memory at %8.8X for length %X\n",
+				ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
+			return_ACPI_STATUS (status);
+		}
+
+		ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
+		physical_address <<= 4;                 /* Convert segment to physical address */
+		acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
+
+		/* EBDA present? */
+
+		if (physical_address > 0x400) {
+			/*
+			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+			 */
+			status = acpi_os_map_memory ((acpi_physical_address) physical_address,
+					  ACPI_EBDA_WINDOW_SIZE,
+					  (void *) &table_ptr);
+			if (ACPI_FAILURE (status)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Could not map memory at %8.8X for length %X\n",
+					physical_address, ACPI_EBDA_WINDOW_SIZE));
+				return_ACPI_STATUS (status);
+			}
+
+			mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE);
+			acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
+
+			if (mem_rover) {
+				/* Found it, return the physical address */
+
+				physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
+
+				table_info->physical_address = (acpi_physical_address) physical_address;
+				return_ACPI_STATUS (AE_OK);
+			}
+		}
+
+		/*
+		 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
+		 */
+		status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
+				  ACPI_HI_RSDP_WINDOW_SIZE,
+				  (void *) &table_ptr);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not map memory at %8.8X for length %X\n",
+				ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
+			return_ACPI_STATUS (status);
+		}
+
+		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
+		acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
+
+		if (mem_rover) {
+			/* Found it, return the physical address */
+
+			physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
+
+			table_info->physical_address = (acpi_physical_address) physical_address;
+			return_ACPI_STATUS (AE_OK);
+		}
+	}
+
+	/*
+	 * Physical addressing
+	 */
+	else {
+		/*
+		 * 1a) Get the location of the EBDA
+		 */
+		ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
+		physical_address <<= 4;     /* Convert segment to physical address */
+
+		/* EBDA present? */
+
+		if (physical_address > 0x400) {
+			/*
+			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+			 */
+			mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address),
+					  ACPI_EBDA_WINDOW_SIZE);
+			if (mem_rover) {
+				/* Found it, return the physical address */
+
+				table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
+				return_ACPI_STATUS (AE_OK);
+			}
+		}
+
+		/*
+		 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
+		 */
+		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
+				  ACPI_HI_RSDP_WINDOW_SIZE);
+		if (mem_rover) {
+			/* Found it, return the physical address */
+
+			table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
+			return_ACPI_STATUS (AE_OK);
+		}
+	}
+
+	/* RSDP signature was not found */
+
+	return_ACPI_STATUS (AE_NOT_FOUND);
+}
+
+#endif
+
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
new file mode 100644
index 0000000..79c3a68
--- /dev/null
+++ b/drivers/acpi/thermal.c
@@ -0,0 +1,1445 @@
+/*
+ *  acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This driver fully implements the ACPI thermal policy as described in the
+ *  ACPI 2.0 Specification.
+ *
+ *  TBD: 1. Implement passive cooling hysteresis.
+ *       2. Enhance passive cooling (CPU) states/limit interface to support
+ *          concepts of 'multiple limiters', upper/lower limits, etc.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/kmod.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_THERMAL_COMPONENT		0x04000000
+#define ACPI_THERMAL_CLASS		"thermal_zone"
+#define ACPI_THERMAL_DRIVER_NAME	"ACPI Thermal Zone Driver"
+#define ACPI_THERMAL_DEVICE_NAME	"Thermal Zone"
+#define ACPI_THERMAL_FILE_STATE		"state"
+#define ACPI_THERMAL_FILE_TEMPERATURE	"temperature"
+#define ACPI_THERMAL_FILE_TRIP_POINTS	"trip_points"
+#define ACPI_THERMAL_FILE_COOLING_MODE	"cooling_mode"
+#define ACPI_THERMAL_FILE_POLLING_FREQ	"polling_frequency"
+#define ACPI_THERMAL_NOTIFY_TEMPERATURE	0x80
+#define ACPI_THERMAL_NOTIFY_THRESHOLDS	0x81
+#define ACPI_THERMAL_NOTIFY_DEVICES	0x82
+#define ACPI_THERMAL_NOTIFY_CRITICAL	0xF0
+#define ACPI_THERMAL_NOTIFY_HOT		0xF1
+#define ACPI_THERMAL_MODE_ACTIVE	0x00
+#define ACPI_THERMAL_MODE_PASSIVE	0x01
+#define ACPI_THERMAL_MODE_CRITICAL   	0xff
+#define ACPI_THERMAL_PATH_POWEROFF	"/sbin/poweroff"
+
+#define ACPI_THERMAL_MAX_ACTIVE	10
+#define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
+
+#define KELVIN_TO_CELSIUS(t)    (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
+#define CELSIUS_TO_KELVIN(t)	((t+273)*10)
+
+#define _COMPONENT		ACPI_THERMAL_COMPONENT
+ACPI_MODULE_NAME		("acpi_thermal")
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static int tzp;
+module_param(tzp, int, 0);
+MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
+
+
+static int acpi_thermal_add (struct acpi_device *device);
+static int acpi_thermal_remove (struct acpi_device *device, int type);
+static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
+static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
+static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
+static ssize_t acpi_thermal_write_trip_points (struct file*,const char __user *,size_t,loff_t *);
+static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
+static ssize_t acpi_thermal_write_cooling_mode (struct file*,const char __user *,size_t,loff_t *);
+static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
+static ssize_t acpi_thermal_write_polling(struct file*,const char __user *,size_t,loff_t *);
+
+static struct acpi_driver acpi_thermal_driver = {
+	.name =		ACPI_THERMAL_DRIVER_NAME,
+	.class =	ACPI_THERMAL_CLASS,
+	.ids =		ACPI_THERMAL_HID,
+	.ops =		{
+				.add =		acpi_thermal_add,
+				.remove =	acpi_thermal_remove,
+			},
+};
+
+struct acpi_thermal_state {
+	u8			critical:1;
+	u8			hot:1;
+	u8			passive:1;
+	u8			active:1;
+	u8			reserved:4;
+	int			active_index;
+};
+
+struct acpi_thermal_state_flags {
+	u8			valid:1;
+	u8			enabled:1;
+	u8			reserved:6;
+};
+
+struct acpi_thermal_critical {
+	struct acpi_thermal_state_flags flags;
+	unsigned long		temperature;
+};
+
+struct acpi_thermal_hot {
+	struct acpi_thermal_state_flags flags;
+	unsigned long		temperature;
+};
+
+struct acpi_thermal_passive {
+	struct acpi_thermal_state_flags flags;
+	unsigned long		temperature;
+	unsigned long		tc1;
+	unsigned long		tc2;
+	unsigned long		tsp;
+	struct acpi_handle_list	devices;
+};
+
+struct acpi_thermal_active {
+	struct acpi_thermal_state_flags flags;
+	unsigned long		temperature;
+	struct acpi_handle_list	devices;
+};
+
+struct acpi_thermal_trips {
+	struct acpi_thermal_critical critical;
+	struct acpi_thermal_hot	hot;
+	struct acpi_thermal_passive passive;
+	struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
+};
+
+struct acpi_thermal_flags {
+	u8			cooling_mode:1;		/* _SCP */
+	u8			devices:1;		/* _TZD */
+	u8			reserved:6;
+};
+
+struct acpi_thermal {
+	acpi_handle		handle;
+	acpi_bus_id		name;
+	unsigned long		temperature;
+	unsigned long		last_temperature;
+	unsigned long		polling_frequency;
+	u8			cooling_mode;
+	volatile u8		zombie;
+	struct acpi_thermal_flags flags;
+	struct acpi_thermal_state state;
+	struct acpi_thermal_trips trips;
+	struct acpi_handle_list	devices;
+	struct timer_list	timer;
+};
+
+static struct file_operations acpi_thermal_state_fops = {
+	.open		= acpi_thermal_state_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_thermal_temp_fops = {
+	.open		= acpi_thermal_temp_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_thermal_trip_fops = {
+	.open		= acpi_thermal_trip_open_fs,
+	.read		= seq_read,
+	.write		= acpi_thermal_write_trip_points,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_thermal_cooling_fops = {
+	.open		= acpi_thermal_cooling_open_fs,
+	.read		= seq_read,
+	.write		= acpi_thermal_write_cooling_mode,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_thermal_polling_fops = {
+	.open		= acpi_thermal_polling_open_fs,
+	.read		= seq_read,
+	.write		= acpi_thermal_write_polling,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+/* --------------------------------------------------------------------------
+                             Thermal Zone Management
+   -------------------------------------------------------------------------- */
+
+static int
+acpi_thermal_get_temperature (
+	struct acpi_thermal *tz)
+{
+	acpi_status		status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_get_temperature");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	tz->last_temperature = tz->temperature;
+
+	status = acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", tz->temperature));
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_get_polling_frequency (
+	struct acpi_thermal	*tz)
+{
+	acpi_status		status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_get_polling_frequency");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	status = acpi_evaluate_integer(tz->handle, "_TZP", NULL, &tz->polling_frequency);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", tz->polling_frequency));
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_set_polling (
+	struct acpi_thermal	*tz,
+	int			seconds)
+{
+	ACPI_FUNCTION_TRACE("acpi_thermal_set_polling");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	tz->polling_frequency = seconds * 10;	/* Convert value to deci-seconds */
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency set to %lu seconds\n", tz->polling_frequency));
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_set_cooling_mode (
+	struct acpi_thermal	*tz,
+	int			mode)
+{
+	acpi_status		status = AE_OK;
+	union acpi_object	arg0 = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	arg_list = {1, &arg0};
+	acpi_handle		handle = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_set_cooling_mode");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	status = acpi_get_handle(tz->handle, "_SCP", &handle);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	arg0.integer.value = mode;
+
+	status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	tz->cooling_mode = mode;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", 
+		mode?"passive":"active"));
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_get_trip_points (
+	struct acpi_thermal *tz)
+{
+	acpi_status		status = AE_OK;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_get_trip_points");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	/* Critical Shutdown (required) */
+
+	status = acpi_evaluate_integer(tz->handle, "_CRT", NULL, 
+		&tz->trips.critical.temperature);
+	if (ACPI_FAILURE(status)) {
+		tz->trips.critical.flags.valid = 0;
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n"));
+		return_VALUE(-ENODEV);
+	}
+	else {
+		tz->trips.critical.flags.valid = 1;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found critical threshold [%lu]\n", tz->trips.critical.temperature));
+	}
+
+	/* Critical Sleep (optional) */
+
+	status = acpi_evaluate_integer(tz->handle, "_HOT", NULL, &tz->trips.hot.temperature);
+	if (ACPI_FAILURE(status)) {
+		tz->trips.hot.flags.valid = 0;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n"));
+	}
+	else {
+		tz->trips.hot.flags.valid = 1;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n", tz->trips.hot.temperature));
+	}
+
+	/* Passive: Processors (optional) */
+
+	status = acpi_evaluate_integer(tz->handle, "_PSV", NULL, &tz->trips.passive.temperature);
+	if (ACPI_FAILURE(status)) {
+		tz->trips.passive.flags.valid = 0;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n"));
+	}
+	else {
+		tz->trips.passive.flags.valid = 1;
+
+		status = acpi_evaluate_integer(tz->handle, "_TC1", NULL, &tz->trips.passive.tc1);
+		if (ACPI_FAILURE(status))
+			tz->trips.passive.flags.valid = 0;
+
+		status = acpi_evaluate_integer(tz->handle, "_TC2", NULL, &tz->trips.passive.tc2);
+		if (ACPI_FAILURE(status))
+			tz->trips.passive.flags.valid = 0;
+
+		status = acpi_evaluate_integer(tz->handle, "_TSP", NULL, &tz->trips.passive.tsp);
+		if (ACPI_FAILURE(status))
+			tz->trips.passive.flags.valid = 0;
+
+		status = acpi_evaluate_reference(tz->handle, "_PSL", NULL, &tz->trips.passive.devices);
+		if (ACPI_FAILURE(status))
+			tz->trips.passive.flags.valid = 0;
+
+		if (!tz->trips.passive.flags.valid)
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid passive threshold\n"));
+		else
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found passive threshold [%lu]\n", tz->trips.passive.temperature));
+	}
+
+	/* Active: Fans, etc. (optional) */
+
+	for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) {
+
+		char name[5] = {'_','A','C',('0'+i),'\0'};
+
+		status = acpi_evaluate_integer(tz->handle, name, NULL, &tz->trips.active[i].temperature);
+		if (ACPI_FAILURE(status))
+			break;
+
+		name[2] = 'L';
+		status = acpi_evaluate_reference(tz->handle, name, NULL, &tz->trips.active[i].devices);
+		if (ACPI_SUCCESS(status)) {
+			tz->trips.active[i].flags.valid = 1;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found active threshold [%d]:[%lu]\n", i, tz->trips.active[i].temperature));
+		}
+		else
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid active threshold [%d]\n", i));
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_get_devices (
+	struct acpi_thermal	*tz)
+{
+	acpi_status		status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_get_devices");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	status = acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_call_usermode (
+	char			*path)
+{
+	char			*argv[2] = {NULL, NULL};
+	char			*envp[3] = {NULL, NULL, NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode");
+
+	if (!path)
+		return_VALUE(-EINVAL);
+
+	argv[0] = path;
+
+	/* minimal command environment */
+	envp[0] = "HOME=/";
+	envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+	
+	call_usermodehelper(argv[0], argv, envp, 0);
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_critical (
+	struct acpi_thermal	*tz)
+{
+	int			result = 0;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_critical");
+
+	if (!tz || !tz->trips.critical.flags.valid)
+		return_VALUE(-EINVAL);
+
+	if (tz->temperature >= tz->trips.critical.temperature) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Critical trip point\n"));
+		tz->trips.critical.flags.enabled = 1;
+	}
+	else if (tz->trips.critical.flags.enabled)
+		tz->trips.critical.flags.enabled = 0;
+
+	result = acpi_bus_get_device(tz->handle, &device);
+	if (result)
+		return_VALUE(result);
+
+	printk(KERN_EMERG "Critical temperature reached (%ld C), shutting down.\n", KELVIN_TO_CELSIUS(tz->temperature));
+	acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled);
+
+	acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF);
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_hot (
+	struct acpi_thermal	*tz)
+{
+	int			result = 0;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_hot");
+
+	if (!tz || !tz->trips.hot.flags.valid)
+		return_VALUE(-EINVAL);
+
+	if (tz->temperature >= tz->trips.hot.temperature) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n"));
+		tz->trips.hot.flags.enabled = 1;
+	}
+	else if (tz->trips.hot.flags.enabled)
+		tz->trips.hot.flags.enabled = 0;
+
+	result = acpi_bus_get_device(tz->handle, &device);
+	if (result)
+		return_VALUE(result);
+
+	acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled);
+
+	/* TBD: Call user-mode "sleep(S4)" function */
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_passive (
+	struct acpi_thermal	*tz)
+{
+	int			result = 0;
+	struct acpi_thermal_passive *passive = NULL;
+	int			trend = 0;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_passive");
+
+	if (!tz || !tz->trips.passive.flags.valid)
+		return_VALUE(-EINVAL);
+
+	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));
+		tz->trips.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++)
+				acpi_processor_set_thermal_limit(
+					passive->devices.handles[i], 
+					ACPI_PROCESSOR_LIMIT_DECREMENT);
+	}
+
+	/*
+	 * Below Trip?
+	 * -----------
+	 * Implement passive cooling hysteresis to slowly increase performance
+	 * and avoid thrashing around the passive trip point.  Note that we
+	 * assume symmetry.
+	 */
+	else if (tz->trips.passive.flags.enabled) {
+		for (i=0; i<passive->devices.count; i++)
+			result = acpi_processor_set_thermal_limit(
+				passive->devices.handles[i], 
+				ACPI_PROCESSOR_LIMIT_DECREMENT);
+		if (result == 1) {
+			tz->trips.passive.flags.enabled = 0;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+				"Disabling passive cooling (zone is cool)\n"));
+		}
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+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;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_active");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) {
+
+		active = &(tz->trips.active[i]);
+		if (!active || !active->flags.valid)
+			break;
+
+		/*
+		 * Above Threshold?
+		 * ----------------
+		 * If not already enabled, turn ON all cooling devices
+		 * associated with this active threshold.
+		 */
+		if (tz->temperature >= active->temperature) {
+			if (active->temperature > maxtemp)
+				tz->state.active_index = i, maxtemp = active->temperature;
+			if (!active->flags.enabled) {
+				for (j = 0; j < active->devices.count; j++) {
+					result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D0);
+					if (result) {
+						ACPI_DEBUG_PRINT((ACPI_DB_WARN, "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]));
+				}
+			}
+		}
+		/*
+		 * Below Threshold?
+		 * ----------------
+		 * Turn OFF all cooling devices associated with this
+		 * threshold.
+		 */
+		else if (active->flags.enabled) {
+			for (j = 0; j < active->devices.count; j++) {
+				result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D3);
+				if (result) {
+					ACPI_DEBUG_PRINT((ACPI_DB_WARN, "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]));
+			}
+		}
+	}
+
+	return_VALUE(0);
+}
+
+
+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_queue_for_execution(OSD_PRIORITY_GPE,  
+			acpi_thermal_check, (void *) data);
+}
+
+
+static void
+acpi_thermal_check (
+	void                    *data)
+{
+	int			result = 0;
+	struct acpi_thermal	*tz = (struct acpi_thermal *) data;
+	unsigned long		sleep_time = 0;
+	int			i = 0;
+	struct acpi_thermal_state state;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_check");
+
+	if (!tz) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
+		return_VOID;
+	}
+
+	state = tz->state;
+
+	result = acpi_thermal_get_temperature(tz);
+	if (result)
+		return_VOID;
+	
+	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.
+	 */
+	if (tz->trips.critical.flags.enabled)
+		tz->state.critical = 1;
+	if (tz->trips.hot.flags.enabled)
+		tz->state.hot = 1;
+	if (tz->trips.passive.flags.enabled)
+		tz->state.passive = 1;
+	for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++)
+		if (tz->trips.active[i].flags.enabled)
+			tz->state.active = 1;
+
+	/*
+	 * 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;
+	else if (tz->polling_frequency > 0)
+		sleep_time = tz->polling_frequency * 100;
+
+	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), (HZ * sleep_time) / 1000);
+		else {
+			tz->timer.data = (unsigned long) tz;
+			tz->timer.function = acpi_thermal_run;
+			tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
+			add_timer(&(tz->timer));
+		}
+	}
+
+	return_VOID;
+}
+
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_thermal_dir;
+
+static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_state_seq_show");
+
+	if (!tz)
+		goto end;
+
+	seq_puts(seq, "state:                   ");
+
+	if (!tz->state.critical && !tz->state.hot && !tz->state.passive && !tz->state.active)
+		seq_puts(seq, "ok\n");
+	else {
+		if (tz->state.critical)
+			seq_puts(seq, "critical ");
+		if (tz->state.hot)
+			seq_puts(seq, "hot ");
+		if (tz->state.passive)
+			seq_puts(seq, "passive ");
+		if (tz->state.active)
+			seq_printf(seq, "active[%d]", tz->state.active_index);
+		seq_puts(seq, "\n");
+	}
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
+}
+
+
+static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
+{
+	int			result = 0;
+	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_temp_seq_show");
+
+	if (!tz)
+		goto end;
+
+	result = acpi_thermal_get_temperature(tz);
+	if (result)
+		goto end;
+
+	seq_printf(seq, "temperature:             %ld C\n", 
+		KELVIN_TO_CELSIUS(tz->temperature));
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
+}
+
+
+static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;
+	int			i = 0;
+	int			j = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_trip_seq_show");
+
+	if (!tz)
+		goto end;
+
+	if (tz->trips.critical.flags.valid)
+		seq_printf(seq, "critical (S5):           %ld C\n",
+			KELVIN_TO_CELSIUS(tz->trips.critical.temperature));
+
+	if (tz->trips.hot.flags.valid)
+		seq_printf(seq, "hot (S4):                %ld C\n",
+			KELVIN_TO_CELSIUS(tz->trips.hot.temperature));
+
+	if (tz->trips.passive.flags.valid) {
+		seq_printf(seq, "passive:                 %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
+			KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
+			tz->trips.passive.tc1,
+			tz->trips.passive.tc2, 
+			tz->trips.passive.tsp);
+		for (j=0; j<tz->trips.passive.devices.count; j++) {
+
+			seq_printf(seq, "0x%p ", tz->trips.passive.devices.handles[j]);
+		}
+		seq_puts(seq, "\n");
+	}
+
+	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
+		if (!(tz->trips.active[i].flags.valid))
+			break;
+		seq_printf(seq, "active[%d]:               %ld C: devices=",
+			i, KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
+		for (j = 0; j < tz->trips.active[i].devices.count; j++) 
+			seq_printf(seq, "0x%p ",
+				tz->trips.active[i].devices.handles[j]);
+		seq_puts(seq, "\n");
+	}
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
+}
+
+static ssize_t
+acpi_thermal_write_trip_points (
+        struct file		*file,
+        const char		__user *buffer,
+        size_t			count,
+        loff_t			*ppos)
+{
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
+
+	char			*limit_string; 
+	int			num, critical, hot, passive;
+	int			*active; 
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");
+
+	limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
+	if(!limit_string)
+		return_VALUE(-ENOMEM);
+
+	memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
+
+	active = kmalloc(ACPI_THERMAL_MAX_ACTIVE *sizeof(int), GFP_KERNEL);
+	if(!active)
+		return_VALUE(-ENOMEM);
+
+	if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
+		count = -EINVAL;
+		goto end;
+	}
+	
+	if (copy_from_user(limit_string, buffer, count)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
+		count = -EFAULT;
+		goto end;
+	}
+	
+	limit_string[count] = '\0';
+
+	num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+				&critical, &hot, &passive,
+				&active[0], &active[1], &active[2], &active[3], &active[4],
+				&active[5], &active[6], &active[7], &active[8], &active[9]);
+	if(!(num >=5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
+		count = -EINVAL;
+		goto end;
+	}
+
+	tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical);
+	tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot);
+	tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive);
+	for (i = 0; i < num - 3; i++) {
+		if (!(tz->trips.active[i].flags.valid))
+			break;
+		tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);
+	}
+	
+end:
+	kfree(active);
+	kfree(limit_string);
+	return_VALUE(count);
+}
+
+
+static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_cooling_seq_show");
+
+	if (!tz)
+		goto end;
+
+	if (!tz->flags.cooling_mode) {
+		seq_puts(seq, "<setting not supported>\n");
+	}
+
+	if ( tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL )
+		seq_printf(seq, "cooling mode:	critical\n");
+	else
+		seq_printf(seq, "cooling mode:	%s\n",
+			tz->cooling_mode?"passive":"active");
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_thermal_cooling_seq_show,
+							PDE(inode)->data);
+}
+
+static ssize_t
+acpi_thermal_write_cooling_mode (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
+	int			result = 0;
+	char			mode_string[12] = {'\0'};
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode");
+
+	if (!tz || (count > sizeof(mode_string) - 1))
+		return_VALUE(-EINVAL);
+
+	if (!tz->flags.cooling_mode)
+		return_VALUE(-ENODEV);
+
+	if (copy_from_user(mode_string, buffer, count))
+		return_VALUE(-EFAULT);
+	
+	mode_string[count] = '\0';
+	
+	result = acpi_thermal_set_cooling_mode(tz, 
+		simple_strtoul(mode_string, NULL, 0));
+	if (result)
+		return_VALUE(result);
+
+	acpi_thermal_check(tz);
+
+	return_VALUE(count);
+}
+
+
+static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_polling_seq_show");
+
+	if (!tz)
+		goto end;
+
+	if (!tz->polling_frequency) {
+		seq_puts(seq, "<polling disabled>\n");
+		goto end;
+	}
+
+	seq_printf(seq, "polling frequency:       %lu seconds\n",
+		(tz->polling_frequency / 10));
+
+end:
+	return_VALUE(0);
+}
+
+static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_thermal_polling_seq_show,
+							PDE(inode)->data);
+}
+
+static ssize_t
+acpi_thermal_write_polling (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
+	int			result = 0;
+	char			polling_string[12] = {'\0'};
+	int			seconds = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_write_polling");
+
+	if (!tz || (count > sizeof(polling_string) - 1))
+		return_VALUE(-EINVAL);
+	
+	if (copy_from_user(polling_string, buffer, count))
+		return_VALUE(-EFAULT);
+	
+	polling_string[count] = '\0';
+
+	seconds = simple_strtoul(polling_string, NULL, 0);
+	
+	result = acpi_thermal_set_polling(tz, seconds);
+	if (result)
+		return_VALUE(result);
+
+	acpi_thermal_check(tz);
+
+	return_VALUE(count);
+}
+
+
+static int
+acpi_thermal_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_add_fs");
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+			acpi_thermal_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
+	}
+
+	/* 'state' [R] */
+	entry = create_proc_entry(ACPI_THERMAL_FILE_STATE,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_THERMAL_FILE_STATE));
+	else {
+		entry->proc_fops = &acpi_thermal_state_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'temperature' [R] */
+	entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
+		S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_THERMAL_FILE_TEMPERATURE));
+	else {
+		entry->proc_fops = &acpi_thermal_temp_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'trip_points' [R/W] */
+	entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_THERMAL_FILE_TRIP_POINTS));
+	else {
+		entry->proc_fops = &acpi_thermal_trip_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'cooling_mode' [R/W] */
+	entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_THERMAL_FILE_COOLING_MODE));
+	else {
+		entry->proc_fops = &acpi_thermal_cooling_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'polling_frequency' [R/W] */
+	entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_THERMAL_FILE_POLLING_FREQ));
+	else {
+		entry->proc_fops = &acpi_thermal_polling_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_remove_fs (
+	struct acpi_device	*device)
+{
+	ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs");
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
+				  acpi_device_dir(device));
+		remove_proc_entry(ACPI_THERMAL_FILE_STATE,
+				  acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+static void
+acpi_thermal_notify (
+	acpi_handle 		handle,
+	u32 			event,
+	void 			*data)
+{
+	struct acpi_thermal	*tz = (struct acpi_thermal *) data;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_notify");
+
+	if (!tz)
+		return_VOID;
+
+	if (acpi_bus_get_device(tz->handle, &device))
+		return_VOID;
+
+	switch (event) {
+	case ACPI_THERMAL_NOTIFY_TEMPERATURE:
+		acpi_thermal_check(tz);
+		break;
+	case ACPI_THERMAL_NOTIFY_THRESHOLDS:
+		acpi_thermal_get_trip_points(tz);
+		acpi_thermal_check(tz);
+		acpi_bus_generate_event(device, event, 0);
+		break;
+	case ACPI_THERMAL_NOTIFY_DEVICES:
+		if (tz->flags.devices)
+			acpi_thermal_get_devices(tz);
+		acpi_bus_generate_event(device, event, 0);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+
+static int
+acpi_thermal_get_info (
+	struct acpi_thermal	*tz)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_get_info");
+
+	if (!tz)
+		return_VALUE(-EINVAL);
+
+	/* Get temperature [_TMP] (required) */
+	result = acpi_thermal_get_temperature(tz);
+	if (result)
+		return_VALUE(result);
+
+	/* Get trip points [_CRT, _PSV, etc.] (required) */
+	result = acpi_thermal_get_trip_points(tz);
+	if (result)
+		return_VALUE(result);
+
+	/* Set the cooling mode [_SCP] to active cooling (default) */
+	result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
+	if (!result) 
+		tz->flags.cooling_mode = 1;
+	else { 
+		/* Oh,we have not _SCP method.
+		   Generally show cooling_mode by _ACx, _PSV,spec 12.2*/
+		tz->flags.cooling_mode = 0;
+		if ( tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) {
+			if ( tz->trips.passive.temperature > tz->trips.active[0].temperature )
+				tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
+			else 
+				tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
+		} else if ( !tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) {
+			tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
+		} else if ( tz->trips.active[0].flags.valid && !tz->trips.passive.flags.valid ) {
+			tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
+		} else {
+			/* _ACx and _PSV are optional, but _CRT is required */
+			tz->cooling_mode = ACPI_THERMAL_MODE_CRITICAL;
+		}
+	}
+
+	/* Get default polling frequency [_TZP] (optional) */
+	if (tzp)
+		tz->polling_frequency = tzp;
+	else
+		acpi_thermal_get_polling_frequency(tz);
+
+	/* Get devices in this thermal zone [_TZD] (optional) */
+	result = acpi_thermal_get_devices(tz);
+	if (!result)
+		tz->flags.devices = 1;
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_thermal_add (
+	struct acpi_device 		*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_thermal	*tz = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
+	if (!tz)
+		return_VALUE(-ENOMEM);
+	memset(tz, 0, sizeof(struct acpi_thermal));
+
+	tz->handle = device->handle;
+	strcpy(tz->name, device->pnp.bus_id);
+	strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
+	acpi_driver_data(device) = tz;
+
+	result = acpi_thermal_get_info(tz);
+	if (result)
+		goto end;
+
+	result = acpi_thermal_add_fs(device);
+	if (result)
+		return_VALUE(result);
+
+	init_timer(&tz->timer);
+
+	acpi_thermal_check(tz);
+
+	status = acpi_install_notify_handler(tz->handle,
+		ACPI_DEVICE_NOTIFY, acpi_thermal_notify, tz);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing notify handler\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
+		acpi_device_name(device), acpi_device_bid(device),
+		KELVIN_TO_CELSIUS(tz->temperature));
+
+end:
+	if (result) {
+		acpi_thermal_remove_fs(device);
+		kfree(tz);
+	}
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_thermal_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	acpi_status		status = AE_OK;
+	struct acpi_thermal	*tz = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	tz = (struct acpi_thermal *) 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(tz->handle,
+		ACPI_DEVICE_NOTIFY, acpi_thermal_notify);
+	if (ACPI_FAILURE(status))
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error removing notify handler\n"));
+
+	/* 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);
+
+	kfree(tz);
+	return_VALUE(0);
+}
+
+
+static int __init
+acpi_thermal_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_thermal_init");
+
+	acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
+	if (!acpi_thermal_dir)
+		return_VALUE(-ENODEV);
+	acpi_thermal_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_thermal_driver);
+	if (result < 0) {
+		remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+
+static void __exit
+acpi_thermal_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_thermal_exit");
+
+	acpi_bus_unregister_driver(&acpi_thermal_driver);
+
+	remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+
+module_init(acpi_thermal_init);
+module_exit(acpi_thermal_exit);
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
new file mode 100644
index 0000000..c84997c
--- /dev/null
+++ b/drivers/acpi/toshiba_acpi.c
@@ -0,0 +1,575 @@
+/*
+ *  toshiba_acpi.c - Toshiba Laptop ACPI Extras
+ *
+ *
+ *  Copyright (C) 2002-2004 John Belmonte
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ *  The devolpment page for this driver is located at
+ *  http://memebeam.org/toys/ToshibaAcpiDriver.
+ *
+ *  Credits:
+ *	Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse
+ *		engineering the Windows drivers
+ *	Yasushi Nagato - changes for linux kernel 2.4 -> 2.5
+ *	Rob Miller - TV out and hotkeys help
+ *
+ *
+ *  TODO
+ *
+ */
+
+#define TOSHIBA_ACPI_VERSION	"0.18"
+#define PROC_INTERFACE_VERSION	1
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_drivers.h>
+
+MODULE_AUTHOR("John Belmonte");
+MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver");
+MODULE_LICENSE("GPL");
+
+#define MY_LOGPREFIX "toshiba_acpi: "
+#define MY_ERR KERN_ERR MY_LOGPREFIX
+#define MY_NOTICE KERN_NOTICE MY_LOGPREFIX
+#define MY_INFO KERN_INFO MY_LOGPREFIX
+
+/* Toshiba ACPI method paths */
+#define METHOD_LCD_BRIGHTNESS	"\\_SB_.PCI0.VGA_.LCD_._BCM"
+#define METHOD_HCI_1		"\\_SB_.VALD.GHCI"
+#define METHOD_HCI_2		"\\_SB_.VALZ.GHCI"
+#define METHOD_VIDEO_OUT	"\\_SB_.VALX.DSSX"
+
+/* Toshiba HCI interface definitions
+ *
+ * HCI is Toshiba's "Hardware Control Interface" which is supposed to
+ * be uniform across all their models.  Ideally we would just call
+ * dedicated ACPI methods instead of using this primitive interface.
+ * However the ACPI methods seem to be incomplete in some areas (for
+ * example they allow setting, but not reading, the LCD brightness value),
+ * so this is still useful.
+ */
+
+#define HCI_WORDS			6
+
+/* operations */
+#define HCI_SET				0xff00
+#define HCI_GET				0xfe00
+
+/* return codes */
+#define HCI_SUCCESS			0x0000
+#define HCI_FAILURE			0x1000
+#define HCI_NOT_SUPPORTED		0x8000
+#define HCI_EMPTY			0x8c00
+
+/* registers */
+#define HCI_FAN				0x0004
+#define HCI_SYSTEM_EVENT		0x0016
+#define HCI_VIDEO_OUT			0x001c
+#define HCI_HOTKEY_EVENT		0x001e
+#define HCI_LCD_BRIGHTNESS		0x002a
+
+/* field definitions */
+#define HCI_LCD_BRIGHTNESS_BITS		3
+#define HCI_LCD_BRIGHTNESS_SHIFT	(16-HCI_LCD_BRIGHTNESS_BITS)
+#define HCI_LCD_BRIGHTNESS_LEVELS	(1 << HCI_LCD_BRIGHTNESS_BITS)
+#define HCI_VIDEO_OUT_LCD		0x1
+#define HCI_VIDEO_OUT_CRT		0x2
+#define HCI_VIDEO_OUT_TV		0x4
+
+/* utility
+ */
+
+static __inline__ void
+_set_bit(u32* word, u32 mask, int value)
+{
+	*word = (*word & ~mask) | (mask * value);
+}
+
+/* acpi interface wrappers
+ */
+
+static int
+is_valid_acpi_path(const char* methodName)
+{
+	acpi_handle handle;
+	acpi_status status;
+
+	status = acpi_get_handle(NULL, (char*)methodName, &handle);
+	return !ACPI_FAILURE(status);
+}
+
+static int
+write_acpi_int(const char* methodName, int val)
+{
+	struct acpi_object_list params;
+	union acpi_object in_objs[1];
+	acpi_status status;
+
+	params.count = sizeof(in_objs)/sizeof(in_objs[0]);
+	params.pointer = in_objs;
+	in_objs[0].type = ACPI_TYPE_INTEGER;
+	in_objs[0].integer.value = val;
+
+	status = acpi_evaluate_object(NULL, (char*)methodName, &params, NULL);
+	return (status == AE_OK);
+}
+
+#if 0
+static int
+read_acpi_int(const char* methodName, int* pVal)
+{
+	struct acpi_buffer results;
+	union acpi_object out_objs[1];
+	acpi_status status;
+
+	results.length = sizeof(out_objs);
+	results.pointer = out_objs;
+
+	status = acpi_evaluate_object(0, (char*)methodName, 0, &results);
+	*pVal = out_objs[0].integer.value;
+
+	return (status == AE_OK) && (out_objs[0].type == ACPI_TYPE_INTEGER);
+}
+#endif
+
+static const char*		method_hci /*= 0*/;
+
+/* Perform a raw HCI call.  Here we don't care about input or output buffer
+ * format.
+ */
+static acpi_status
+hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
+{
+	struct acpi_object_list params;
+	union acpi_object in_objs[HCI_WORDS];
+	struct acpi_buffer results;
+	union acpi_object out_objs[HCI_WORDS+1];
+	acpi_status status;
+	int i;
+
+	params.count = HCI_WORDS;
+	params.pointer = in_objs;
+	for (i = 0; i < HCI_WORDS; ++i) {
+		in_objs[i].type = ACPI_TYPE_INTEGER;
+		in_objs[i].integer.value = in[i];
+	}
+
+	results.length = sizeof(out_objs);
+	results.pointer = out_objs;
+
+	status = acpi_evaluate_object(NULL, (char*)method_hci, &params,
+		&results);
+	if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
+		for (i = 0; i < out_objs->package.count; ++i) {
+			out[i] = out_objs->package.elements[i].integer.value;
+		}
+	}
+
+	return status;
+}
+
+/* common hci tasks (get or set one value)
+ *
+ * In addition to the ACPI status, the HCI system returns a result which
+ * may be useful (such as "not supported").
+ */
+
+static acpi_status
+hci_write1(u32 reg, u32 in1, u32* result)
+{
+	u32 in[HCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 };
+	u32 out[HCI_WORDS];
+	acpi_status status = hci_raw(in, out);
+	*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
+	return status;
+}
+
+static acpi_status
+hci_read1(u32 reg, u32* out1, u32* result)
+{
+	u32 in[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 };
+	u32 out[HCI_WORDS];
+	acpi_status status = hci_raw(in, out);
+	*out1 = out[2];
+	*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
+	return status;
+}
+
+static struct proc_dir_entry*	toshiba_proc_dir /*= 0*/;
+static int			force_fan;
+static int			last_key_event;
+static int			key_event_valid;
+
+typedef struct _ProcItem
+{
+	const char* name;
+	char* (*read_func)(char*);
+	unsigned long (*write_func)(const char*, unsigned long);
+} ProcItem;
+
+/* proc file handlers
+ */
+
+static int
+dispatch_read(char* page, char** start, off_t off, int count, int* eof,
+	ProcItem* item)
+{
+	char* p = page;
+	int len;
+
+	if (off == 0)
+		p = item->read_func(p);
+
+	/* ISSUE: I don't understand this code */
+	len = (p - page);
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static int
+dispatch_write(struct file* file, const char __user * buffer,
+	unsigned long count, ProcItem* item)
+{
+	int result;
+	char* tmp_buffer;
+
+	/* Arg buffer points to userspace memory, which can't be accessed
+	 * directly.  Since we're making a copy, zero-terminate the
+	 * destination so that sscanf can be used on it safely.
+	 */
+	tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
+	if (copy_from_user(tmp_buffer, buffer, count)) {
+		result = -EFAULT;
+	}
+	else {
+		tmp_buffer[count] = 0;
+		result = item->write_func(tmp_buffer, count);
+	}
+	kfree(tmp_buffer);
+	return result;
+}
+
+static char*
+read_lcd(char* p)
+{
+	u32 hci_result;
+	u32 value;
+
+	hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result);
+	if (hci_result == HCI_SUCCESS) {
+		value = value >> HCI_LCD_BRIGHTNESS_SHIFT;
+		p += sprintf(p, "brightness:              %d\n", value);
+		p += sprintf(p, "brightness_levels:       %d\n",
+			HCI_LCD_BRIGHTNESS_LEVELS);
+	} else {
+		printk(MY_ERR "Error reading LCD brightness\n");
+	}
+
+	return p;
+}
+
+static unsigned long
+write_lcd(const char* buffer, unsigned long count)
+{
+	int value;
+	u32 hci_result;
+
+	if (sscanf(buffer, " brightness : %i", &value) == 1 &&
+			value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
+		value = value << HCI_LCD_BRIGHTNESS_SHIFT;
+		hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
+		if (hci_result != HCI_SUCCESS)
+			return -EFAULT;
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static char*
+read_video(char* p)
+{
+	u32 hci_result;
+	u32 value;
+
+	hci_read1(HCI_VIDEO_OUT, &value, &hci_result);
+	if (hci_result == HCI_SUCCESS) {
+		int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
+		int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
+		int is_tv  = (value & HCI_VIDEO_OUT_TV ) ? 1 : 0;
+		p += sprintf(p, "lcd_out:                 %d\n", is_lcd);
+		p += sprintf(p, "crt_out:                 %d\n", is_crt);
+		p += sprintf(p, "tv_out:                  %d\n", is_tv);
+	} else {
+		printk(MY_ERR "Error reading video out status\n");
+	}
+
+	return p;
+}
+
+static unsigned long
+write_video(const char* buffer, unsigned long count)
+{
+	int value;
+	int remain = count;
+	int lcd_out = -1;
+	int crt_out = -1;
+	int tv_out = -1;
+	u32 hci_result;
+	int video_out;
+
+	/* scan expression.  Multiple expressions may be delimited with ;
+	 *
+	 *  NOTE: to keep scanning simple, invalid fields are ignored
+	 */
+	while (remain) {
+		if (sscanf(buffer, " lcd_out : %i", &value) == 1)
+			lcd_out = value & 1;
+		else if (sscanf(buffer, " crt_out : %i", &value) == 1)
+			crt_out = value & 1;
+		else if (sscanf(buffer, " tv_out : %i", &value) == 1)
+			tv_out = value & 1;
+		/* advance to one character past the next ; */
+		do {
+			++buffer;
+			--remain;
+		}
+		while (remain && *(buffer-1) != ';');
+	}
+
+	hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
+	if (hci_result == HCI_SUCCESS) {
+		int new_video_out = video_out;
+		if (lcd_out != -1)
+			_set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out);
+		if (crt_out != -1)
+			_set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out);
+		if (tv_out != -1)
+			_set_bit(&new_video_out, HCI_VIDEO_OUT_TV, tv_out);
+		/* To avoid unnecessary video disruption, only write the new
+		 * video setting if something changed. */
+		if (new_video_out != video_out)
+			write_acpi_int(METHOD_VIDEO_OUT, new_video_out);
+	} else {
+		return -EFAULT;
+	}
+
+	return count;
+}
+
+static char*
+read_fan(char* p)
+{
+	u32 hci_result;
+	u32 value;
+
+	hci_read1(HCI_FAN, &value, &hci_result);
+	if (hci_result == HCI_SUCCESS) {
+		p += sprintf(p, "running:                 %d\n", (value > 0));
+		p += sprintf(p, "force_on:                %d\n", force_fan);
+	} else {
+		printk(MY_ERR "Error reading fan status\n");
+	}
+
+	return p;
+}
+
+static unsigned long
+write_fan(const char* buffer, unsigned long count)
+{
+	int value;
+	u32 hci_result;
+
+	if (sscanf(buffer, " force_on : %i", &value) == 1 &&
+			value >= 0 && value <= 1) {
+		hci_write1(HCI_FAN, value, &hci_result);
+		if (hci_result != HCI_SUCCESS)
+			return -EFAULT;
+		else
+			force_fan = value;
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static char*
+read_keys(char* p)
+{
+	u32 hci_result;
+	u32 value;
+
+	if (!key_event_valid) {
+		hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
+		if (hci_result == HCI_SUCCESS) {
+			key_event_valid = 1;
+			last_key_event = value;
+		} else if (hci_result == HCI_EMPTY) {
+			/* better luck next time */
+		} else if (hci_result == HCI_NOT_SUPPORTED) {
+			/* This is a workaround for an unresolved issue on
+			 * some machines where system events sporadically
+			 * become disabled. */
+			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
+			printk(MY_NOTICE "Re-enabled hotkeys\n");
+		} else {
+			printk(MY_ERR "Error reading hotkey status\n");
+			goto end;
+		}
+	}
+
+	p += sprintf(p, "hotkey_ready:            %d\n", key_event_valid);
+	p += sprintf(p, "hotkey:                  0x%04x\n", last_key_event);
+
+end:
+	return p;
+}
+
+static unsigned long
+write_keys(const char* buffer, unsigned long count)
+{
+	int value;
+
+	if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 &&
+			value == 0) {
+		key_event_valid = 0;
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static char*
+read_version(char* p)
+{
+	p += sprintf(p, "driver:                  %s\n", TOSHIBA_ACPI_VERSION);
+	p += sprintf(p, "proc_interface:          %d\n",
+		PROC_INTERFACE_VERSION);
+	return p;
+}
+
+/* proc and module init
+ */
+
+#define PROC_TOSHIBA		"toshiba"
+
+static ProcItem proc_items[] =
+{
+	{ "lcd"		, read_lcd	, write_lcd	},
+	{ "video"	, read_video	, write_video	},
+	{ "fan"		, read_fan	, write_fan	},
+	{ "keys"	, read_keys	, write_keys	},
+	{ "version"	, read_version	, NULL		},
+	{ NULL }
+};
+
+static acpi_status __init
+add_device(void)
+{
+	struct proc_dir_entry* proc;
+	ProcItem* item;
+
+	for (item = proc_items; item->name; ++item)
+	{
+		proc = create_proc_read_entry(item->name,
+			S_IFREG | S_IRUGO | S_IWUSR,
+			toshiba_proc_dir, (read_proc_t*)dispatch_read, item);
+		if (proc)
+			proc->owner = THIS_MODULE;
+		if (proc && item->write_func)
+			proc->write_proc = (write_proc_t*)dispatch_write;
+	}
+
+	return AE_OK;
+}
+
+static acpi_status __exit
+remove_device(void)
+{
+	ProcItem* item;
+
+	for (item = proc_items; item->name; ++item)
+		remove_proc_entry(item->name, toshiba_proc_dir);
+	return AE_OK;
+}
+
+static int __init
+toshiba_acpi_init(void)
+{
+	acpi_status status = AE_OK;
+	u32 hci_result;
+
+	if (acpi_disabled)
+		return -ENODEV;
+	/* simple device detection: look for HCI method */
+	if (is_valid_acpi_path(METHOD_HCI_1))
+		method_hci = METHOD_HCI_1;
+	else if (is_valid_acpi_path(METHOD_HCI_2))
+		method_hci = METHOD_HCI_2;
+	else
+		return -ENODEV;
+
+	printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",
+		TOSHIBA_ACPI_VERSION);
+	printk(MY_INFO "    HCI method: %s\n", method_hci);
+
+	force_fan = 0;
+	key_event_valid = 0;
+
+	/* enable event fifo */
+	hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
+
+	toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
+	if (!toshiba_proc_dir) {
+		status = AE_ERROR;
+	} else {
+		toshiba_proc_dir->owner = THIS_MODULE;
+		status = add_device();
+		if (ACPI_FAILURE(status))
+			remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
+	}
+
+	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
+}
+
+static void __exit
+toshiba_acpi_exit(void)
+{
+	remove_device();
+
+	if (toshiba_proc_dir)
+		remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
+
+	return;
+}
+
+module_init(toshiba_acpi_init);
+module_exit(toshiba_acpi_exit);
diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile
new file mode 100644
index 0000000..939c447
--- /dev/null
+++ b/drivers/acpi/utilities/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+obj-y := utalloc.o  utdebug.o   uteval.o    utinit.o  utmisc.o    utxface.o \
+	 utcopy.o   utdelete.o  utglobal.o  utmath.o  utobject.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
new file mode 100644
index 0000000..3313439
--- /dev/null
+++ b/drivers/acpi/utilities/utalloc.c
@@ -0,0 +1,988 @@
+/******************************************************************************
+ *
+ * Module Name: utalloc - local cache and memory allocation routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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>
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utalloc")
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_release_to_cache
+ *
+ * PARAMETERS:  list_id             - Memory list/cache ID
+ *              Object              - The object to be released
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Release an object to the specified cache.  If cache is full,
+ *              the object is deleted.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_release_to_cache (
+	u32                             list_id,
+	void                            *object)
+{
+	struct acpi_memory_list         *cache_info;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	cache_info = &acpi_gbl_memory_lists[list_id];
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+
+	/* If walk cache is full, just free this wallkstate object */
+
+	if (cache_info->cache_depth >= cache_info->max_cache_depth) {
+		ACPI_MEM_FREE (object);
+		ACPI_MEM_TRACKING (cache_info->total_freed++);
+	}
+
+	/* Otherwise put this object back into the cache */
+
+	else {
+		if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
+			return;
+		}
+
+		/* Mark the object as cached */
+
+		ACPI_MEMSET (object, 0xCA, cache_info->object_size);
+		ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED);
+
+		/* Put the object at the head of the cache list */
+
+		* (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
+		cache_info->list_head = object;
+		cache_info->cache_depth++;
+
+		(void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
+	}
+
+#else
+
+	/* Object cache is disabled; just free the object */
+
+	ACPI_MEM_FREE (object);
+	ACPI_MEM_TRACKING (cache_info->total_freed++);
+#endif
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_from_cache
+ *
+ * PARAMETERS:  list_id             - Memory list ID
+ *
+ * RETURN:      A requested object.  NULL if the object could not be
+ *              allocated.
+ *
+ * DESCRIPTION: Get an object from the specified cache.  If cache is empty,
+ *              the object is allocated.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_acquire_from_cache (
+	u32                             list_id)
+{
+	struct acpi_memory_list         *cache_info;
+	void                            *object;
+
+
+	ACPI_FUNCTION_NAME ("ut_acquire_from_cache");
+
+
+	cache_info = &acpi_gbl_memory_lists[list_id];
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+
+	if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
+		return (NULL);
+	}
+
+	ACPI_MEM_TRACKING (cache_info->cache_requests++);
+
+	/* Check the cache first */
+
+	if (cache_info->list_head) {
+		/* There is an object available, use it */
+
+		object = cache_info->list_head;
+		cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset])));
+
+		ACPI_MEM_TRACKING (cache_info->cache_hits++);
+		cache_info->cache_depth--;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n",
+			object, acpi_gbl_memory_lists[list_id].list_name));
+#endif
+
+		if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
+			return (NULL);
+		}
+
+		/* Clear (zero) the previously used Object */
+
+		ACPI_MEMSET (object, 0, cache_info->object_size);
+	}
+
+	else {
+		/* The cache is empty, create a new object */
+
+		/* Avoid deadlock with ACPI_MEM_CALLOCATE */
+
+		if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
+			return (NULL);
+		}
+
+		object = ACPI_MEM_CALLOCATE (cache_info->object_size);
+		ACPI_MEM_TRACKING (cache_info->total_allocated++);
+	}
+
+#else
+
+	/* Object cache is disabled; just allocate the object */
+
+	object = ACPI_MEM_CALLOCATE (cache_info->object_size);
+	ACPI_MEM_TRACKING (cache_info->total_allocated++);
+#endif
+
+	return (object);
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_generic_cache
+ *
+ * PARAMETERS:  list_id         - Memory list ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Free all objects within the requested cache.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_cache (
+	u32                             list_id)
+{
+	struct acpi_memory_list         *cache_info;
+	char                            *next;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	cache_info = &acpi_gbl_memory_lists[list_id];
+	while (cache_info->list_head) {
+		/* Delete one cached state object */
+
+		next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset])));
+		ACPI_MEM_FREE (cache_info->list_head);
+
+		cache_info->list_head = next;
+		cache_info->cache_depth--;
+	}
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_validate_buffer
+ *
+ * PARAMETERS:  Buffer              - Buffer descriptor to be validated
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_validate_buffer (
+	struct acpi_buffer              *buffer)
+{
+
+	/* Obviously, the structure pointer must be valid */
+
+	if (!buffer) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Special semantics for the length */
+
+	if ((buffer->length == ACPI_NO_BUFFER)              ||
+		(buffer->length == ACPI_ALLOCATE_BUFFER)        ||
+		(buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
+		return (AE_OK);
+	}
+
+	/* Length is valid, the buffer pointer must be also */
+
+	if (!buffer->pointer) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_initialize_buffer
+ *
+ * PARAMETERS:  Buffer              - Buffer to be validated
+ *              required_length     - Length needed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validate that the buffer is of the required length or
+ *              allocate a new buffer.  Returned buffer is always zeroed.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_initialize_buffer (
+	struct acpi_buffer              *buffer,
+	acpi_size                       required_length)
+{
+	acpi_status                     status = AE_OK;
+
+
+	switch (buffer->length) {
+	case ACPI_NO_BUFFER:
+
+		/* Set the exception and returned the required length */
+
+		status = AE_BUFFER_OVERFLOW;
+		break;
+
+
+	case ACPI_ALLOCATE_BUFFER:
+
+		/* Allocate a new buffer */
+
+		buffer->pointer = acpi_os_allocate (required_length);
+		if (!buffer->pointer) {
+			return (AE_NO_MEMORY);
+		}
+
+		/* Clear the buffer */
+
+		ACPI_MEMSET (buffer->pointer, 0, required_length);
+		break;
+
+
+	case ACPI_ALLOCATE_LOCAL_BUFFER:
+
+		/* Allocate a new buffer with local interface to allow tracking */
+
+		buffer->pointer = ACPI_MEM_CALLOCATE (required_length);
+		if (!buffer->pointer) {
+			return (AE_NO_MEMORY);
+		}
+		break;
+
+
+	default:
+
+		/* Existing buffer: Validate the size of the buffer */
+
+		if (buffer->length < required_length) {
+			status = AE_BUFFER_OVERFLOW;
+			break;
+		}
+
+		/* Clear the buffer */
+
+		ACPI_MEMSET (buffer->pointer, 0, required_length);
+		break;
+	}
+
+	buffer->length = required_length;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_allocate
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_allocate (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line)
+{
+	void                            *allocation;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
+
+
+	/* Check for an inadvertent size of zero bytes */
+
+	if (!size) {
+		_ACPI_REPORT_ERROR (module, line, component,
+				("ut_allocate: Attempt to allocate zero bytes\n"));
+		size = 1;
+	}
+
+	allocation = acpi_os_allocate (size);
+	if (!allocation) {
+		/* Report allocation error */
+
+		_ACPI_REPORT_ERROR (module, line, component,
+				("ut_allocate: Could not allocate size %X\n", (u32) size));
+
+		return_PTR (NULL);
+	}
+
+	return_PTR (allocation);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_callocate
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_callocate (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line)
+{
+	void                            *allocation;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
+
+
+	/* Check for an inadvertent size of zero bytes */
+
+	if (!size) {
+		_ACPI_REPORT_ERROR (module, line, component,
+				("ut_callocate: Attempt to allocate zero bytes\n"));
+		return_PTR (NULL);
+	}
+
+	allocation = acpi_os_allocate (size);
+	if (!allocation) {
+		/* Report allocation error */
+
+		_ACPI_REPORT_ERROR (module, line, component,
+				("ut_callocate: Could not allocate size %X\n", (u32) size));
+		return_PTR (NULL);
+	}
+
+	/* Clear the memory block */
+
+	ACPI_MEMSET (allocation, 0, size);
+	return_PTR (allocation);
+}
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+/*
+ * These procedures are used for tracking memory leaks in the subsystem, and
+ * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
+ *
+ * Each memory allocation is tracked via a doubly linked list.  Each
+ * element contains the caller's component, module name, function name, and
+ * line number.  acpi_ut_allocate and acpi_ut_callocate call
+ * acpi_ut_track_allocation to add an element to the list; deletion
+ * occurs in the body of acpi_ut_free.
+ */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_allocate_and_track
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: The subsystem's equivalent of malloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_allocate_and_track (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line)
+{
+	struct acpi_debug_mem_block     *allocation;
+	acpi_status                     status;
+
+
+	allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component,
+			  module, line);
+	if (!allocation) {
+		return (NULL);
+	}
+
+	status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
+			  ACPI_MEM_MALLOC, component, module, line);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_free (allocation);
+		return (NULL);
+	}
+
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
+
+	return ((void *) &allocation->user_space);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_callocate_and_track
+ *
+ * PARAMETERS:  Size                - Size of the allocation
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      Address of the allocated memory on success, NULL on failure.
+ *
+ * DESCRIPTION: Subsystem equivalent of calloc.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_callocate_and_track (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line)
+{
+	struct acpi_debug_mem_block     *allocation;
+	acpi_status                     status;
+
+
+	allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component,
+			  module, line);
+	if (!allocation) {
+		/* Report allocation error */
+
+		_ACPI_REPORT_ERROR (module, line, component,
+				("ut_callocate: Could not allocate size %X\n", (u32) size));
+		return (NULL);
+	}
+
+	status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
+			   ACPI_MEM_CALLOC, component, module, line);
+	if (ACPI_FAILURE (status)) {
+		acpi_os_free (allocation);
+		return (NULL);
+	}
+
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
+
+	return ((void *) &allocation->user_space);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_free_and_track
+ *
+ * PARAMETERS:  Allocation          - Address of the memory to deallocate
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Frees the memory at Allocation
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_free_and_track (
+	void                            *allocation,
+	u32                             component,
+	char                            *module,
+	u32                             line)
+{
+	struct acpi_debug_mem_block     *debug_block;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
+
+
+	if (NULL == allocation) {
+		_ACPI_REPORT_ERROR (module, line, component,
+			("acpi_ut_free: Attempt to delete a NULL address\n"));
+
+		return_VOID;
+	}
+
+	debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
+			  (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
+
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size;
+
+	status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block,
+			  component, module, line);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
+			acpi_format_exception (status)));
+	}
+
+	acpi_os_free (debug_block);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_find_allocation
+ *
+ * PARAMETERS:  list_id                 - Memory list to search
+ *              Allocation              - Address of allocated memory
+ *
+ * RETURN:      A list element if found; NULL otherwise.
+ *
+ * DESCRIPTION: Searches for an element in the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+struct acpi_debug_mem_block *
+acpi_ut_find_allocation (
+	u32                             list_id,
+	void                            *allocation)
+{
+	struct acpi_debug_mem_block     *element;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if (list_id > ACPI_MEM_LIST_MAX) {
+		return (NULL);
+	}
+
+	element = acpi_gbl_memory_lists[list_id].list_head;
+
+	/* Search for the address. */
+
+	while (element) {
+		if (element == allocation) {
+			return (element);
+		}
+
+		element = element->next;
+	}
+
+	return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_track_allocation
+ *
+ * PARAMETERS:  list_id             - Memory list to search
+ *              Allocation          - Address of allocated memory
+ *              Size                - Size of the allocation
+ *              alloc_type          - MEM_MALLOC or MEM_CALLOC
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Inserts an element into the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_track_allocation (
+	u32                             list_id,
+	struct acpi_debug_mem_block     *allocation,
+	acpi_size                       size,
+	u8                              alloc_type,
+	u32                             component,
+	char                            *module,
+	u32                             line)
+{
+	struct acpi_memory_list         *mem_list;
+	struct acpi_debug_mem_block     *element;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
+
+
+	if (list_id > ACPI_MEM_LIST_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	mem_list = &acpi_gbl_memory_lists[list_id];
+	status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Search list for this address to make sure it is not already on the list.
+	 * This will catch several kinds of problems.
+	 */
+
+	element = acpi_ut_find_allocation (list_id, allocation);
+	if (element) {
+		ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
+			allocation));
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
+
+		goto unlock_and_exit;
+	}
+
+	/* Fill in the instance data. */
+
+	allocation->size      = (u32) size;
+	allocation->alloc_type = alloc_type;
+	allocation->component = component;
+	allocation->line      = line;
+
+	ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
+	allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
+
+	/* Insert at list head */
+
+	if (mem_list->list_head) {
+		((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
+	}
+
+	allocation->next = mem_list->list_head;
+	allocation->previous = NULL;
+
+	mem_list->list_head = allocation;
+
+
+unlock_and_exit:
+	status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_remove_allocation
+ *
+ * PARAMETERS:  list_id             - Memory list to search
+ *              Allocation          - Address of allocated memory
+ *              Component           - Component type of caller
+ *              Module              - Source file name of caller
+ *              Line                - Line number of caller
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Deletes an element from the global allocation tracking list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_remove_allocation (
+	u32                             list_id,
+	struct acpi_debug_mem_block     *allocation,
+	u32                             component,
+	char                            *module,
+	u32                             line)
+{
+	struct acpi_memory_list         *mem_list;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_remove_allocation");
+
+
+	if (list_id > ACPI_MEM_LIST_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	mem_list = &acpi_gbl_memory_lists[list_id];
+	if (NULL == mem_list->list_head) {
+		/* No allocations! */
+
+		_ACPI_REPORT_ERROR (module, line, component,
+				("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Unlink */
+
+	if (allocation->previous) {
+		(allocation->previous)->next = allocation->next;
+	}
+	else {
+		mem_list->list_head = allocation->next;
+	}
+
+	if (allocation->next) {
+		(allocation->next)->previous = allocation->previous;
+	}
+
+	/* Mark the segment as deleted */
+
+	ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
+
+	status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_dump_allocation_info
+ *
+ * PARAMETERS:
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print some info about the outstanding allocations.
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+void
+acpi_ut_dump_allocation_info (
+	void)
+{
+/*
+	struct acpi_memory_list         *mem_list;
+*/
+
+	ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
+
+/*
+	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+			  ("%30s: %4d (%3d Kb)\n", "Current allocations",
+			  mem_list->current_count,
+			  ROUND_UP_TO_1K (mem_list->current_size)));
+
+	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+			  ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
+			  mem_list->max_concurrent_count,
+			  ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
+
+
+	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+			  ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
+			  running_object_count,
+			  ROUND_UP_TO_1K (running_object_size)));
+
+	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+			  ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
+			  running_alloc_count,
+			  ROUND_UP_TO_1K (running_alloc_size)));
+
+
+	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+			  ("%30s: %4d (%3d Kb)\n", "Current Nodes",
+			  acpi_gbl_current_node_count,
+			  ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
+
+	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
+			  ("%30s: %4d (%3d Kb)\n", "Max Nodes",
+			  acpi_gbl_max_concurrent_node_count,
+			  ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
+*/
+	return_VOID;
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_dump_allocations
+ *
+ * PARAMETERS:  Component           - Component(s) to dump info for.
+ *              Module              - Module to dump info for.  NULL means all.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print a list of all outstanding allocations.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_dump_allocations (
+	u32                             component,
+	char                            *module)
+{
+	struct acpi_debug_mem_block     *element;
+	union acpi_descriptor           *descriptor;
+	u32                             num_outstanding = 0;
+
+
+	ACPI_FUNCTION_TRACE ("ut_dump_allocations");
+
+
+	/*
+	 * Walk the allocation list.
+	 */
+	if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
+		return;
+	}
+
+	element = acpi_gbl_memory_lists[0].list_head;
+	while (element) {
+		if ((element->component & component) &&
+			((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
+			/* Ignore allocated objects that are in a cache */
+
+			descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
+			if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
+				acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
+						 descriptor, element->size, element->module,
+						 element->line, acpi_ut_get_descriptor_name (descriptor));
+
+				/* Most of the elements will be Operand objects. */
+
+				switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
+				case ACPI_DESC_TYPE_OPERAND:
+					acpi_os_printf ("%12.12s R%hd",
+							acpi_ut_get_type_name (descriptor->object.common.type),
+							descriptor->object.common.reference_count);
+					break;
+
+				case ACPI_DESC_TYPE_PARSER:
+					acpi_os_printf ("aml_opcode %04hX",
+							descriptor->op.asl.aml_opcode);
+					break;
+
+				case ACPI_DESC_TYPE_NAMED:
+					acpi_os_printf ("%4.4s",
+							acpi_ut_get_node_name (&descriptor->node));
+					break;
+
+				default:
+					break;
+				}
+
+				acpi_os_printf ( "\n");
+				num_outstanding++;
+			}
+		}
+		element = element->next;
+	}
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
+
+	/* Print summary */
+
+	if (!num_outstanding) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"No outstanding allocations.\n"));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"%d(%X) Outstanding allocations\n",
+			num_outstanding, num_outstanding));
+	}
+
+	return_VOID;
+}
+
+
+#endif  /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
+
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
new file mode 100644
index 0000000..0fcd98b
--- /dev/null
+++ b/drivers/acpi/utilities/utcopy.c
@@ -0,0 +1,930 @@
+/******************************************************************************
+ *
+ * Module Name: utcopy - Internal to external object translation utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utcopy")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_isimple_to_esimple
+ *
+ * PARAMETERS:  *internal_object    - Pointer to the object we are examining
+ *              *Buffer             - Where the object is returned
+ *              *space_used         - Where the data length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to place a simple object in a user
+ *              buffer.
+ *
+ *              The buffer is assumed to have sufficient space for the object.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_copy_isimple_to_esimple (
+	union acpi_operand_object       *internal_object,
+	union acpi_object               *external_object,
+	u8                              *data_space,
+	acpi_size                       *buffer_space_used)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_isimple_to_esimple");
+
+
+	*buffer_space_used = 0;
+
+	/*
+	 * Check for NULL object case (could be an uninitialized
+	 * package element)
+	 */
+	if (!internal_object) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Always clear the external object */
+
+	ACPI_MEMSET (external_object, 0, sizeof (union acpi_object));
+
+	/*
+	 * In general, the external object will be the same type as
+	 * the internal object
+	 */
+	external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
+
+	/* However, only a limited number of external types are supported */
+
+	switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
+	case ACPI_TYPE_STRING:
+
+		external_object->string.pointer = (char *) data_space;
+		external_object->string.length = internal_object->string.length;
+		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD ((acpi_size) internal_object->string.length + 1);
+
+		ACPI_MEMCPY ((void *) data_space, (void *) internal_object->string.pointer,
+				 (acpi_size) internal_object->string.length + 1);
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		external_object->buffer.pointer = data_space;
+		external_object->buffer.length = internal_object->buffer.length;
+		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (internal_object->string.length);
+
+		ACPI_MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer,
+				 internal_object->buffer.length);
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		external_object->integer.value = internal_object->integer.value;
+		break;
+
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		/*
+		 * This is an object reference.  Attempt to dereference it.
+		 */
+		switch (internal_object->reference.opcode) {
+		case AML_INT_NAMEPATH_OP:
+
+			/* For namepath, return the object handle ("reference") */
+
+		default:
+			/*
+			 * Use the object type of "Any" to indicate a reference
+			 * to object containing a handle to an ACPI named object.
+			 */
+			external_object->type = ACPI_TYPE_ANY;
+			external_object->reference.handle = internal_object->reference.node;
+			break;
+		}
+		break;
+
+
+	case ACPI_TYPE_PROCESSOR:
+
+		external_object->processor.proc_id    = internal_object->processor.proc_id;
+		external_object->processor.pblk_address = internal_object->processor.address;
+		external_object->processor.pblk_length = internal_object->processor.length;
+		break;
+
+
+	case ACPI_TYPE_POWER:
+
+		external_object->power_resource.system_level =
+				   internal_object->power_resource.system_level;
+
+		external_object->power_resource.resource_order =
+				   internal_object->power_resource.resource_order;
+		break;
+
+
+	default:
+		/*
+		 * There is no corresponding external object type
+		 */
+		return_ACPI_STATUS (AE_SUPPORT);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_ielement_to_eelement
+ *
+ * PARAMETERS:  acpi_pkg_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_ielement_to_eelement (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_pkg_info            *info = (struct acpi_pkg_info *) context;
+	acpi_size                       object_space;
+	u32                             this_index;
+	union acpi_object               *target_object;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	this_index   = state->pkg.index;
+	target_object = (union acpi_object *)
+			  &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
+
+	switch (object_type) {
+	case ACPI_COPY_TYPE_SIMPLE:
+
+		/*
+		 * This is a simple or null object
+		 */
+		status = acpi_ut_copy_isimple_to_esimple (source_object,
+				  target_object, info->free_space, &object_space);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+		break;
+
+
+	case ACPI_COPY_TYPE_PACKAGE:
+
+		/*
+		 * Build the package object
+		 */
+		target_object->type             = ACPI_TYPE_PACKAGE;
+		target_object->package.count    = source_object->package.count;
+		target_object->package.elements = ACPI_CAST_PTR (union acpi_object, info->free_space);
+
+		/*
+		 * Pass the new package object back to the package walk routine
+		 */
+		state->pkg.this_target_obj = target_object;
+
+		/*
+		 * Save space for the array of objects (Package elements)
+		 * update the buffer length counter
+		 */
+		object_space = ACPI_ROUND_UP_TO_NATIVE_WORD (
+				   (acpi_size) target_object->package.count * sizeof (union acpi_object));
+		break;
+
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+	info->free_space  += object_space;
+	info->length      += object_space;
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_ipackage_to_epackage
+ *
+ * PARAMETERS:  *internal_object    - Pointer to the object we are returning
+ *              *Buffer             - Where the object is returned
+ *              *space_used         - Where the object length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to place a package object in a user
+ *              buffer.  A package object by definition contains other objects.
+ *
+ *              The buffer is assumed to have sufficient space for the object.
+ *              The caller must have verified the buffer length needed using the
+ *              acpi_ut_get_object_size function before calling this function.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_copy_ipackage_to_epackage (
+	union acpi_operand_object       *internal_object,
+	u8                              *buffer,
+	acpi_size                       *space_used)
+{
+	union acpi_object               *external_object;
+	acpi_status                     status;
+	struct acpi_pkg_info            info;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_epackage");
+
+
+	/*
+	 * First package at head of the buffer
+	 */
+	external_object = ACPI_CAST_PTR (union acpi_object, buffer);
+
+	/*
+	 * Free space begins right after the first package
+	 */
+	info.length      = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+	info.free_space  = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+	info.object_space = 0;
+	info.num_packages = 1;
+
+	external_object->type            = ACPI_GET_OBJECT_TYPE (internal_object);
+	external_object->package.count   = internal_object->package.count;
+	external_object->package.elements = ACPI_CAST_PTR (union acpi_object, info.free_space);
+
+	/*
+	 * Leave room for an array of ACPI_OBJECTS in the buffer
+	 * and move the free space past it
+	 */
+	info.length    += (acpi_size) external_object->package.count *
+			 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+	info.free_space += external_object->package.count *
+			 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+
+	status = acpi_ut_walk_package_tree (internal_object, external_object,
+			 acpi_ut_copy_ielement_to_eelement, &info);
+
+	*space_used = info.length;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_iobject_to_eobject
+ *
+ * PARAMETERS:  *internal_object    - The internal object to be converted
+ *              *buffer_ptr         - Where the object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to build an API object to be returned to
+ *              the caller.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_iobject_to_eobject (
+	union acpi_operand_object       *internal_object,
+	struct acpi_buffer              *ret_buffer)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_eobject");
+
+
+	if (ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE) {
+		/*
+		 * Package object:  Copy all subobjects (including
+		 * nested packages)
+		 */
+		status = acpi_ut_copy_ipackage_to_epackage (internal_object,
+				  ret_buffer->pointer, &ret_buffer->length);
+	}
+	else {
+		/*
+		 * Build a simple object (no nested objects)
+		 */
+		status = acpi_ut_copy_isimple_to_esimple (internal_object,
+				  (union acpi_object *) ret_buffer->pointer,
+				  ((u8 *) ret_buffer->pointer +
+				  ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))),
+				  &ret_buffer->length);
+		/*
+		 * build simple does not include the object size in the length
+		 * so we add it in here
+		 */
+		ret_buffer->length += sizeof (union acpi_object);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_esimple_to_isimple
+ *
+ * PARAMETERS:  *external_object   - The external object to be converted
+ *              *internal_object   - Where the internal object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function copies an external object to an internal one.
+ *              NOTE: Pointers can be copied, we don't need to copy data.
+ *              (The pointers have to be valid in our address space no matter
+ *              what we do with them!)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_esimple_to_isimple (
+	union acpi_object               *external_object,
+	union acpi_operand_object       **ret_internal_object)
+{
+	union acpi_operand_object       *internal_object;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_esimple_to_isimple");
+
+
+	/*
+	 * Simple types supported are: String, Buffer, Integer
+	 */
+	switch (external_object->type) {
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
+	case ACPI_TYPE_INTEGER:
+
+		internal_object = acpi_ut_create_internal_object ((u8) external_object->type);
+		if (!internal_object) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
+		break;
+
+	default:
+		/* All other types are not supported */
+
+		return_ACPI_STATUS (AE_SUPPORT);
+	}
+
+
+	/* Must COPY string and buffer contents */
+
+	switch (external_object->type) {
+	case ACPI_TYPE_STRING:
+
+		internal_object->string.pointer =
+			ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1);
+		if (!internal_object->string.pointer) {
+			goto error_exit;
+		}
+
+		ACPI_MEMCPY (internal_object->string.pointer,
+				  external_object->string.pointer,
+				  external_object->string.length);
+
+		internal_object->string.length = external_object->string.length;
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		internal_object->buffer.pointer =
+			ACPI_MEM_CALLOCATE (external_object->buffer.length);
+		if (!internal_object->buffer.pointer) {
+			goto error_exit;
+		}
+
+		ACPI_MEMCPY (internal_object->buffer.pointer,
+				  external_object->buffer.pointer,
+				  external_object->buffer.length);
+
+		internal_object->buffer.length = external_object->buffer.length;
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+
+		internal_object->integer.value  = external_object->integer.value;
+		break;
+
+	default:
+		/* Other types can't get here */
+		break;
+	}
+
+	*ret_internal_object = internal_object;
+	return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+	acpi_ut_remove_reference (internal_object);
+	return_ACPI_STATUS (AE_NO_MEMORY);
+}
+
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+
+/* Code to convert packages that are parameters to control methods */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_epackage_to_ipackage
+ *
+ * PARAMETERS:  *internal_object   - Pointer to the object we are returning
+ *              *Buffer            - Where the object is returned
+ *              *space_used        - Where the length of the object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to place a package object in a user
+ *              buffer.  A package object by definition contains other objects.
+ *
+ *              The buffer is assumed to have sufficient space for the object.
+ *              The caller must have verified the buffer length needed using the
+ *              acpi_ut_get_object_size function before calling this function.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_copy_epackage_to_ipackage (
+	union acpi_operand_object       *internal_object,
+	u8                              *buffer,
+	u32                             *space_used)
+{
+	u8                              *free_space;
+	union acpi_object               *external_object;
+	u32                             length = 0;
+	u32                             this_index;
+	u32                             object_space = 0;
+	union acpi_operand_object       *this_internal_obj;
+	union acpi_object               *this_external_obj;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_epackage_to_ipackage");
+
+
+	/*
+	 * First package at head of the buffer
+	 */
+	external_object = (union acpi_object *)buffer;
+
+	/*
+	 * Free space begins right after the first package
+	 */
+	free_space = buffer + sizeof(union acpi_object);
+
+
+	external_object->type              = ACPI_GET_OBJECT_TYPE (internal_object);
+	external_object->package.count     = internal_object->package.count;
+	external_object->package.elements  = (union acpi_object *)free_space;
+
+	/*
+	 * Build an array of ACPI_OBJECTS in the buffer
+	 * and move the free space past it
+	 */
+	free_space += external_object->package.count * sizeof(union acpi_object);
+
+
+	/* Call walk_package */
+
+}
+
+#endif /* Future implementation */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_eobject_to_iobject
+ *
+ * PARAMETERS:  *internal_object   - The external object to be converted
+ *              *buffer_ptr     - Where the internal object is returned
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: Converts an external object to an internal object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_eobject_to_iobject (
+	union acpi_object               *external_object,
+	union acpi_operand_object       **internal_object)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_eobject_to_iobject");
+
+
+	if (external_object->type == ACPI_TYPE_PACKAGE) {
+		/*
+		 * Packages as external input to control methods are not supported,
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Packages as parameters not implemented!\n"));
+
+		return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
+	}
+
+	else {
+		/*
+		 * Build a simple object (no nested objects)
+		 */
+		status = acpi_ut_copy_esimple_to_isimple (external_object, internal_object);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_simple_object
+ *
+ * PARAMETERS:  source_desc         - The internal object to be copied
+ *              dest_desc           - New target object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Simple copy of one internal object to another.  Reference count
+ *              of the destination object is preserved.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_simple_object (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *dest_desc)
+{
+	u16                             reference_count;
+	union acpi_operand_object       *next_object;
+
+
+	/* Save fields from destination that we don't want to overwrite */
+
+	reference_count = dest_desc->common.reference_count;
+	next_object = dest_desc->common.next_object;
+
+	/* Copy the entire source object over the destination object*/
+
+	ACPI_MEMCPY ((char *) dest_desc, (char *) source_desc,
+			  sizeof (union acpi_operand_object));
+
+	/* Restore the saved fields */
+
+	dest_desc->common.reference_count = reference_count;
+	dest_desc->common.next_object = next_object;
+
+	/* Handle the objects with extra data */
+
+	switch (ACPI_GET_OBJECT_TYPE (dest_desc)) {
+	case ACPI_TYPE_BUFFER:
+
+		dest_desc->buffer.node = NULL;
+		dest_desc->common.flags = source_desc->common.flags;
+
+		/*
+		 * Allocate and copy the actual buffer if and only if:
+		 * 1) There is a valid buffer pointer
+		 * 2) The buffer is not static (not in an ACPI table) (in this case,
+		 *    the actual pointer was already copied above)
+		 */
+		if ((source_desc->buffer.pointer) &&
+			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+			dest_desc->buffer.pointer = NULL;
+
+			/* Create an actual buffer only if length > 0 */
+
+			if (source_desc->buffer.length) {
+				dest_desc->buffer.pointer =
+					ACPI_MEM_ALLOCATE (source_desc->buffer.length);
+				if (!dest_desc->buffer.pointer) {
+					return (AE_NO_MEMORY);
+				}
+
+				/* Copy the actual buffer data */
+
+				ACPI_MEMCPY (dest_desc->buffer.pointer,
+						source_desc->buffer.pointer,
+						source_desc->buffer.length);
+			}
+		}
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		/*
+		 * Allocate and copy the actual string if and only if:
+		 * 1) There is a valid string pointer
+		 * 2) The string is not static (not in an ACPI table) (in this case,
+		 *    the actual pointer was already copied above)
+		 */
+		if ((source_desc->string.pointer) &&
+			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+			dest_desc->string.pointer =
+				ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
+			if (!dest_desc->string.pointer) {
+				return (AE_NO_MEMORY);
+			}
+
+			ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer,
+					  (acpi_size) source_desc->string.length + 1);
+		}
+		break;
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+		/*
+		 * We copied the reference object, so we now must add a reference
+		 * to the object pointed to by the reference
+		 */
+		acpi_ut_add_reference (source_desc->reference.object);
+		break;
+
+	default:
+		/* Nothing to do for other simple objects */
+		break;
+	}
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_ielement_to_ielement
+ *
+ * PARAMETERS:  acpi_pkg_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy one package element to another package element
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_ielement_to_ielement (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context)
+{
+	acpi_status                     status = AE_OK;
+	u32                             this_index;
+	union acpi_operand_object       **this_target_ptr;
+	union acpi_operand_object       *target_object;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	this_index    = state->pkg.index;
+	this_target_ptr = (union acpi_operand_object **)
+			   &state->pkg.dest_object->package.elements[this_index];
+
+	switch (object_type) {
+	case ACPI_COPY_TYPE_SIMPLE:
+
+		/* A null source object indicates a (legal) null package element */
+
+		if (source_object) {
+			/*
+			 * This is a simple object, just copy it
+			 */
+			target_object = acpi_ut_create_internal_object (
+					   ACPI_GET_OBJECT_TYPE (source_object));
+			if (!target_object) {
+				return (AE_NO_MEMORY);
+			}
+
+			status = acpi_ut_copy_simple_object (source_object, target_object);
+			if (ACPI_FAILURE (status)) {
+				goto error_exit;
+			}
+
+			*this_target_ptr = target_object;
+		}
+		else {
+			/* Pass through a null element */
+
+			*this_target_ptr = NULL;
+		}
+		break;
+
+
+	case ACPI_COPY_TYPE_PACKAGE:
+
+		/*
+		 * This object is a package - go down another nesting level
+		 * Create and build the package object
+		 */
+		target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
+		if (!target_object) {
+			return (AE_NO_MEMORY);
+		}
+
+		target_object->package.count = source_object->package.count;
+		target_object->common.flags = source_object->common.flags;
+
+		/*
+		 * Create the object array
+		 */
+		target_object->package.elements =
+			ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) *
+					 sizeof (void *));
+		if (!target_object->package.elements) {
+			status = AE_NO_MEMORY;
+			goto error_exit;
+		}
+
+		/*
+		 * Pass the new package object back to the package walk routine
+		 */
+		state->pkg.this_target_obj = target_object;
+
+		/*
+		 * Store the object pointer in the parent package object
+		 */
+		*this_target_ptr = target_object;
+		break;
+
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+	return (status);
+
+error_exit:
+	acpi_ut_remove_reference (target_object);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_ipackage_to_ipackage
+ *
+ * PARAMETERS:  *source_obj     - Pointer to the source package object
+ *              *dest_obj       - Where the internal object is returned
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: This function is called to copy an internal package object
+ *              into another internal package object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_ipackage_to_ipackage (
+	union acpi_operand_object       *source_obj,
+	union acpi_operand_object       *dest_obj,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage");
+
+
+	dest_obj->common.type   = ACPI_GET_OBJECT_TYPE (source_obj);
+	dest_obj->common.flags  = source_obj->common.flags;
+	dest_obj->package.count = source_obj->package.count;
+
+	/*
+	 * Create the object array and walk the source package tree
+	 */
+	dest_obj->package.elements = ACPI_MEM_CALLOCATE (
+			   ((acpi_size) source_obj->package.count + 1) *
+			   sizeof (void *));
+	if (!dest_obj->package.elements) {
+		ACPI_REPORT_ERROR (
+			("aml_build_copy_internal_package_object: Package allocation failure\n"));
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * Copy the package element-by-element by walking the package "tree".
+	 * This handles nested packages of arbitrary depth.
+	 */
+	status = acpi_ut_walk_package_tree (source_obj, dest_obj,
+			 acpi_ut_copy_ielement_to_ielement, walk_state);
+	if (ACPI_FAILURE (status)) {
+		/* On failure, delete the destination package object */
+
+		acpi_ut_remove_reference (dest_obj);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_iobject_to_iobject
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *              source_desc         - The internal object to be copied
+ *              dest_desc           - Where the copied object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Copy an internal object to a new internal object
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_copy_iobject_to_iobject (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       **dest_desc,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("ut_copy_iobject_to_iobject");
+
+
+	/* Create the top level object */
+
+	*dest_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (source_desc));
+	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) {
+		status = acpi_ut_copy_ipackage_to_ipackage (source_desc, *dest_desc,
+				  walk_state);
+	}
+	else {
+		status = acpi_ut_copy_simple_object (source_desc, *dest_desc);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
new file mode 100644
index 0000000..985c5d0
--- /dev/null
+++ b/drivers/acpi/utilities/utdebug.c
@@ -0,0 +1,624 @@
+/******************************************************************************
+ *
+ * Module Name: utdebug - Debug print routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utdebug")
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+static u32   acpi_gbl_prev_thread_id = 0xFFFFFFFF;
+static char     *acpi_gbl_fn_entry_str = "----Entry";
+static char     *acpi_gbl_fn_exit_str = "----Exit-";
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_init_stack_ptr_trace
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Save the current stack pointer
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_init_stack_ptr_trace (
+	void)
+{
+	u32                         current_sp;
+
+
+	acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF (&current_sp, NULL);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_track_stack_ptr
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Save the current stack pointer
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_track_stack_ptr (
+	void)
+{
+	acpi_size                   current_sp;
+
+
+	current_sp = ACPI_PTR_DIFF (&current_sp, NULL);
+
+	if (current_sp < acpi_gbl_lowest_stack_pointer) {
+		acpi_gbl_lowest_stack_pointer = current_sp;
+	}
+
+	if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) {
+		acpi_gbl_deepest_nesting = acpi_gbl_nesting_level;
+	}
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_debug_print
+ *
+ * PARAMETERS:  debug_level         - Requested debug print level
+ *              proc_name           - Caller's procedure name
+ *              module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              component_id        - Caller's component ID (for error output)
+ *
+ *              Format              - Printf format field
+ *              ...                 - Optional printf arguments
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message with prefix consisting of the module name,
+ *              line number, and component ID.
+ *
+ ****************************************************************************/
+
+void  ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print (
+	u32                             requested_debug_level,
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	char                            *format,
+	...)
+{
+	u32                             thread_id;
+	va_list                 args;
+
+
+	/*
+	 * Stay silent if the debug level or component ID is disabled
+	 */
+	if (!(requested_debug_level & acpi_dbg_level) ||
+		!(dbg_info->component_id & acpi_dbg_layer)) {
+		return;
+	}
+
+	/*
+	 * Thread tracking and context switch notification
+	 */
+	thread_id = acpi_os_get_thread_id ();
+
+	if (thread_id != acpi_gbl_prev_thread_id) {
+		if (ACPI_LV_THREADS & acpi_dbg_level) {
+			acpi_os_printf ("\n**** Context Switch from TID %X to TID %X ****\n\n",
+				acpi_gbl_prev_thread_id, thread_id);
+		}
+
+		acpi_gbl_prev_thread_id = thread_id;
+	}
+
+	/*
+	 * Display the module name, current line number, thread ID (if requested),
+	 * current procedure nesting level, and the current procedure name
+	 */
+	acpi_os_printf ("%8s-%04ld ", dbg_info->module_name, line_number);
+
+	if (ACPI_LV_THREADS & acpi_dbg_level) {
+		acpi_os_printf ("[%04lX] ", thread_id);
+	}
+
+	acpi_os_printf ("[%02ld] %-22.22s: ", acpi_gbl_nesting_level, dbg_info->proc_name);
+
+	va_start (args, format);
+	acpi_os_vprintf (format, args);
+}
+EXPORT_SYMBOL(acpi_ut_debug_print);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_debug_print_raw
+ *
+ * PARAMETERS:  requested_debug_level - Requested debug print level
+ *              line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *              Format              - Printf format field
+ *              ...                 - Optional printf arguments
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print message with no headers.  Has same interface as
+ *              debug_print so that the same macros can be used.
+ *
+ ****************************************************************************/
+
+void  ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print_raw (
+	u32                             requested_debug_level,
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	char                            *format,
+	...)
+{
+	va_list                 args;
+
+
+	if (!(requested_debug_level & acpi_dbg_level) ||
+		!(dbg_info->component_id & acpi_dbg_layer)) {
+		return;
+	}
+
+	va_start (args, format);
+	acpi_os_vprintf (format, args);
+}
+EXPORT_SYMBOL(acpi_ut_debug_print_raw);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_trace
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info)
+{
+
+	acpi_gbl_nesting_level++;
+	acpi_ut_track_stack_ptr ();
+
+	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+			"%s\n", acpi_gbl_fn_entry_str);
+}
+EXPORT_SYMBOL(acpi_ut_trace);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_trace_ptr
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *              Pointer             - Pointer to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace_ptr (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	void                            *pointer)
+{
+	acpi_gbl_nesting_level++;
+	acpi_ut_track_stack_ptr ();
+
+	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+			"%s %p\n", acpi_gbl_fn_entry_str, pointer);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_trace_str
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *              String              - Additional string to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace_str (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	char                            *string)
+{
+
+	acpi_gbl_nesting_level++;
+	acpi_ut_track_stack_ptr ();
+
+	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+			"%s %s\n", acpi_gbl_fn_entry_str, string);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_trace_u32
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *              Integer             - Integer to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_trace_u32 (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	u32                             integer)
+{
+
+	acpi_gbl_nesting_level++;
+	acpi_ut_track_stack_ptr ();
+
+	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+			"%s %08X\n", acpi_gbl_fn_entry_str, integer);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_exit
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info)
+{
+
+	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+			"%s\n", acpi_gbl_fn_exit_str);
+
+	acpi_gbl_nesting_level--;
+}
+EXPORT_SYMBOL(acpi_ut_exit);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_status_exit
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *              Status              - Exit status code
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level. Prints exit status also.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_status_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	acpi_status                     status)
+{
+
+	if (ACPI_SUCCESS (status)) {
+		acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+				"%s %s\n", acpi_gbl_fn_exit_str,
+				acpi_format_exception (status));
+	}
+	else {
+		acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+				"%s ****Exception****: %s\n", acpi_gbl_fn_exit_str,
+				acpi_format_exception (status));
+	}
+
+	acpi_gbl_nesting_level--;
+}
+EXPORT_SYMBOL(acpi_ut_status_exit);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_value_exit
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *              Value               - Value to be printed with exit msg
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level. Prints exit value also.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_value_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	acpi_integer                    value)
+{
+
+	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+			"%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str,
+			ACPI_FORMAT_UINT64 (value));
+
+	acpi_gbl_nesting_level--;
+}
+EXPORT_SYMBOL(acpi_ut_value_exit);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_ptr_exit
+ *
+ * PARAMETERS:  line_number         - Caller's line number
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
+ *              Value               - Value to be printed with exit msg
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
+ *              set in debug_level. Prints exit value also.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_ptr_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	u8                              *ptr)
+{
+
+	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+			"%s %p\n", acpi_gbl_fn_exit_str, ptr);
+
+	acpi_gbl_nesting_level--;
+}
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_dump_buffer
+ *
+ * PARAMETERS:  Buffer              - Buffer to dump
+ *              Count               - Amount to dump, in bytes
+ *              Display             - BYTE, WORD, DWORD, or QWORD display
+ *              component_iD        - Caller's component ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii.
+ *
+ ****************************************************************************/
+
+void
+acpi_ut_dump_buffer (
+	u8                              *buffer,
+	u32                             count,
+	u32                             display,
+	u32                             component_id)
+{
+	acpi_native_uint                i = 0;
+	acpi_native_uint                j;
+	u32                             temp32;
+	u8                              buf_char;
+
+
+	/* Only dump the buffer if tracing is enabled */
+
+	if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
+		(component_id & acpi_dbg_layer))) {
+		return;
+	}
+
+	if ((count < 4) || (count & 0x01)) {
+		display = DB_BYTE_DISPLAY;
+	}
+
+	acpi_os_printf ("\nOffset Value\n");
+
+	/*
+	 * Nasty little dump buffer routine!
+	 */
+	while (i < count) {
+		/* Print current offset */
+
+		acpi_os_printf ("%05X  ", (u32) i);
+
+		/* Print 16 hex chars */
+
+		for (j = 0; j < 16;) {
+			if (i + j >= count) {
+				acpi_os_printf ("\n");
+				return;
+			}
+
+			/* Make sure that the s8 doesn't get sign-extended! */
+
+			switch (display) {
+			/* Default is BYTE display */
+
+			default:
+
+				acpi_os_printf ("%02X ",
+						*((u8 *) &buffer[i + j]));
+				j += 1;
+				break;
+
+
+			case DB_WORD_DISPLAY:
+
+				ACPI_MOVE_16_TO_32 (&temp32, &buffer[i + j]);
+				acpi_os_printf ("%04X ", temp32);
+				j += 2;
+				break;
+
+
+			case DB_DWORD_DISPLAY:
+
+				ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
+				acpi_os_printf ("%08X ", temp32);
+				j += 4;
+				break;
+
+
+			case DB_QWORD_DISPLAY:
+
+				ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
+				acpi_os_printf ("%08X", temp32);
+
+				ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j + 4]);
+				acpi_os_printf ("%08X ", temp32);
+				j += 8;
+				break;
+			}
+		}
+
+		/*
+		 * Print the ASCII equivalent characters
+		 * But watch out for the bad unprintable ones...
+		 */
+		for (j = 0; j < 16; j++) {
+			if (i + j >= count) {
+				acpi_os_printf ("\n");
+				return;
+			}
+
+			buf_char = buffer[i + j];
+			if ((buf_char > 0x1F && buf_char < 0x2E) ||
+				(buf_char > 0x2F && buf_char < 0x61) ||
+				(buf_char > 0x60 && buf_char < 0x7F)) {
+				acpi_os_printf ("%c", buf_char);
+			}
+			else {
+				acpi_os_printf (".");
+			}
+		}
+
+		/* Done with that line. */
+
+		acpi_os_printf ("\n");
+		i += 16;
+	}
+
+	return;
+}
+
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
new file mode 100644
index 0000000..9a52ad5
--- /dev/null
+++ b/drivers/acpi/utilities/utdelete.c
@@ -0,0 +1,700 @@
+/*******************************************************************************
+ *
+ * Module Name: utdelete - object deletion and reference count utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/amlcode.h>
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utdelete")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_internal_obj
+ *
+ * PARAMETERS:  *Object        - Pointer to the list to be deleted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Low level object deletion, after reference counts have been
+ *              updated (All reference counts, including sub-objects!)
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_internal_obj (
+	union acpi_operand_object       *object)
+{
+	void                            *obj_pointer = NULL;
+	union acpi_operand_object       *handler_desc;
+	union acpi_operand_object       *second_desc;
+	union acpi_operand_object       *next_desc;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);
+
+
+	if (!object) {
+		return_VOID;
+	}
+
+	/*
+	 * 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)) {
+	case ACPI_TYPE_STRING:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
+			object, object->string.pointer));
+
+		/* Free the actual string buffer */
+
+		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
+			/* But only if it is NOT a pointer into an ACPI table */
+
+			obj_pointer = object->string.pointer;
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
+			object, object->buffer.pointer));
+
+		/* Free the actual buffer */
+
+		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
+			/* But only if it is NOT a pointer into an ACPI table */
+
+			obj_pointer = object->buffer.pointer;
+		}
+		break;
+
+
+	case ACPI_TYPE_PACKAGE:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
+			object->package.count));
+
+		/*
+		 * Elements of the package are not handled here, they are deleted
+		 * separately
+		 */
+
+		/* Free the (variable length) element pointer array */
+
+		obj_pointer = object->package.elements;
+		break;
+
+
+	case ACPI_TYPE_DEVICE:
+
+		if (object->device.gpe_block) {
+			(void) acpi_ev_delete_gpe_block (object->device.gpe_block);
+		}
+
+		/* Walk the handler list for this device */
+
+		handler_desc = object->device.handler;
+		while (handler_desc) {
+			next_desc = handler_desc->address_space.next;
+			acpi_ut_remove_reference (handler_desc);
+			handler_desc = next_desc;
+		}
+		break;
+
+
+	case ACPI_TYPE_MUTEX:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n",
+			object, object->mutex.semaphore));
+
+		acpi_ex_unlink_mutex (object);
+		(void) acpi_os_delete_semaphore (object->mutex.semaphore);
+		break;
+
+
+	case ACPI_TYPE_EVENT:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n",
+			object, object->event.semaphore));
+
+		(void) acpi_os_delete_semaphore (object->event.semaphore);
+		object->event.semaphore = NULL;
+		break;
+
+
+	case ACPI_TYPE_METHOD:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", object));
+
+		/* Delete the method semaphore if it exists */
+
+		if (object->method.semaphore) {
+			(void) acpi_os_delete_semaphore (object->method.semaphore);
+			object->method.semaphore = NULL;
+		}
+		break;
+
+
+	case ACPI_TYPE_REGION:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", object));
+
+		second_desc = acpi_ns_get_secondary_object (object);
+		if (second_desc) {
+			/*
+			 * Free the region_context if and only if the handler is one of the
+			 * default handlers -- and therefore, we created the context object
+			 * locally, it was not created by an external caller.
+			 */
+			handler_desc = object->region.handler;
+			if (handler_desc) {
+				if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+					obj_pointer = second_desc->extra.region_context;
+				}
+
+				acpi_ut_remove_reference (handler_desc);
+			}
+
+			/* Now we can free the Extra object */
+
+			acpi_ut_delete_object_desc (second_desc);
+		}
+		break;
+
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", object));
+
+		second_desc = acpi_ns_get_secondary_object (object);
+		if (second_desc) {
+			acpi_ut_delete_object_desc (second_desc);
+		}
+		break;
+
+
+	default:
+		break;
+	}
+
+	/* Free any allocated memory (pointer within the object) found above */
+
+	if (obj_pointer) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
+				obj_pointer));
+		ACPI_MEM_FREE (obj_pointer);
+	}
+
+	/* Now the object can be safely deleted */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
+			object, acpi_ut_get_object_type_name (object)));
+
+	acpi_ut_delete_object_desc (object);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_internal_object_list
+ *
+ * PARAMETERS:  *obj_list       - Pointer to the list to be deleted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: This function deletes an internal object list, including both
+ *              simple objects and package objects
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_internal_object_list (
+	union acpi_operand_object       **obj_list)
+{
+	union acpi_operand_object       **internal_obj;
+
+
+	ACPI_FUNCTION_TRACE ("ut_delete_internal_object_list");
+
+
+	/* Walk the null-terminated internal list */
+
+	for (internal_obj = obj_list; *internal_obj; internal_obj++) {
+		acpi_ut_remove_reference (*internal_obj);
+	}
+
+	/* Free the combined parameter pointer list and object array */
+
+	ACPI_MEM_FREE (obj_list);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_update_ref_count
+ *
+ * PARAMETERS:  *Object         - Object whose ref count is to be updated
+ *              Action          - What to do
+ *
+ * RETURN:      New ref count
+ *
+ * DESCRIPTION: Modify the ref count and return it.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_update_ref_count (
+	union acpi_operand_object       *object,
+	u32                             action)
+{
+	u16                             count;
+	u16                             new_count;
+
+
+	ACPI_FUNCTION_NAME ("ut_update_ref_count");
+
+
+	if (!object) {
+		return;
+	}
+
+	count = object->common.reference_count;
+	new_count = count;
+
+	/*
+	 * Perform the reference count action (increment, decrement, or force delete)
+	 */
+	switch (action) {
+
+	case REF_INCREMENT:
+
+		new_count++;
+		object->common.reference_count = new_count;
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n",
+			object, new_count));
+		break;
+
+
+	case REF_DECREMENT:
+
+		if (count < 1) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
+				object, new_count));
+
+			new_count = 0;
+		}
+		else {
+			new_count--;
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n",
+				object, new_count));
+		}
+
+		if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
+				object, new_count));
+		}
+
+		object->common.reference_count = new_count;
+		if (new_count == 0) {
+			acpi_ut_delete_internal_obj (object);
+		}
+
+		break;
+
+
+	case REF_FORCE_DELETE:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n",
+			object, count));
+
+		new_count = 0;
+		object->common.reference_count = new_count;
+		acpi_ut_delete_internal_obj (object);
+		break;
+
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", action));
+		break;
+	}
+
+	/*
+	 * Sanity check the reference count, for debug purposes only.
+	 * (A deleted object will have a huge reference count)
+	 */
+	if (count > ACPI_MAX_REFERENCE_COUNT) {
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
+			"**** Warning **** Large Reference Count (%X) in object %p\n\n",
+			count, object));
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_update_object_reference
+ *
+ * PARAMETERS:  *Object             - Increment ref count for this object
+ *                                    and all sub-objects
+ *              Action              - Either REF_INCREMENT or REF_DECREMENT or
+ *                                    REF_FORCE_DELETE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Increment the object reference count
+ *
+ * Object references are incremented when:
+ * 1) An object is attached to a Node (namespace object)
+ * 2) An object is copied (all subobjects must be incremented)
+ *
+ * Object references are decremented when:
+ * 1) An object is detached from an Node
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_update_object_reference (
+	union acpi_operand_object       *object,
+	u16                             action)
+{
+	acpi_status                     status;
+	u32                             i;
+	union acpi_generic_state         *state_list = NULL;
+	union acpi_generic_state         *state;
+	union acpi_operand_object        *tmp;
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object);
+
+
+	/* Ignore a null object ptr */
+
+	if (!object) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Make sure that this isn't a namespace handle */
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	state = acpi_ut_create_update_state (object, action);
+
+	while (state) {
+		object = state->update.object;
+		action = state->update.value;
+		acpi_ut_delete_generic_state (state);
+
+		/*
+		 * All sub-objects must have their reference count incremented also.
+		 * Different object types have different subobjects.
+		 */
+		switch (ACPI_GET_OBJECT_TYPE (object)) {
+		case ACPI_TYPE_DEVICE:
+
+			tmp = object->device.system_notify;
+			if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+				object->device.system_notify = NULL;
+			acpi_ut_update_ref_count (tmp, action);
+
+			tmp = object->device.device_notify;
+			if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
+				object->device.device_notify = NULL;
+			acpi_ut_update_ref_count (tmp, action);
+
+			break;
+
+
+		case ACPI_TYPE_PACKAGE:
+
+			/*
+			 * We must update all the sub-objects of the package
+			 * (Each of whom may have their own sub-objects, etc.
+			 */
+			for (i = 0; i < object->package.count; i++) {
+				/*
+				 * Push each element onto the stack for later processing.
+				 * Note: There can be null elements within the package,
+				 * these are simply ignored
+				 */
+				status = acpi_ut_create_update_state_and_push (
+						 object->package.elements[i], action, &state_list);
+				if (ACPI_FAILURE (status)) {
+					goto error_exit;
+				}
+
+				tmp = object->package.elements[i];
+				if (tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
+					object->package.elements[i] = NULL;
+			}
+			break;
+
+
+		case ACPI_TYPE_BUFFER_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->buffer_field.buffer_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				goto error_exit;
+			}
+
+			tmp = object->buffer_field.buffer_obj;
+			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
+				object->buffer_field.buffer_obj = NULL;
+			break;
+
+
+		case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->field.region_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				goto error_exit;
+			}
+
+			tmp = object->field.region_obj;
+			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
+				object->field.region_obj = NULL;
+		   break;
+
+
+		case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->bank_field.bank_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				goto error_exit;
+			}
+
+			tmp = object->bank_field.bank_obj;
+			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
+				object->bank_field.bank_obj = NULL;
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->bank_field.region_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				goto error_exit;
+			}
+
+			tmp = object->bank_field.region_obj;
+			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
+				object->bank_field.region_obj = NULL;
+			break;
+
+
+		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->index_field.index_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				goto error_exit;
+			}
+
+			tmp = object->index_field.index_obj;
+			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
+				object->index_field.index_obj = NULL;
+
+			status = acpi_ut_create_update_state_and_push (
+					 object->index_field.data_obj, action, &state_list);
+			if (ACPI_FAILURE (status)) {
+				goto error_exit;
+			}
+
+			tmp = object->index_field.data_obj;
+			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
+				object->index_field.data_obj = NULL;
+			break;
+
+
+		case ACPI_TYPE_LOCAL_REFERENCE:
+
+			/*
+			 * The target of an Index (a package, string, or buffer) must track
+			 * changes to the ref count of the index.
+			 */
+			if (object->reference.opcode == AML_INDEX_OP) {
+				status = acpi_ut_create_update_state_and_push (
+						 object->reference.object, action, &state_list);
+				if (ACPI_FAILURE (status)) {
+					goto error_exit;
+				}
+			}
+			break;
+
+
+		case ACPI_TYPE_REGION:
+		default:
+
+			/* No subobjects */
+			break;
+		}
+
+		/*
+		 * Now we can update the count in the main object.  This can only
+		 * happen after we update the sub-objects in case this causes the
+		 * main object to be deleted.
+		 */
+		acpi_ut_update_ref_count (object, action);
+
+		/* Move on to the next object to be updated */
+
+		state = acpi_ut_pop_generic_state (&state_list);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+
+	ACPI_REPORT_ERROR (("Could not update object reference count, %s\n",
+		acpi_format_exception (status)));
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_add_reference
+ *
+ * PARAMETERS:  *Object        - Object whose reference count is to be
+ *                                  incremented
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add one reference to an ACPI object
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_add_reference (
+	union acpi_operand_object       *object)
+{
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);
+
+
+	/* Ensure that we have a valid object */
+
+	if (!acpi_ut_valid_internal_object (object)) {
+		return_VOID;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+		"Obj %p Current Refs=%X [To Be Incremented]\n",
+		object, object->common.reference_count));
+
+	/* Increment the reference count */
+
+	(void) acpi_ut_update_object_reference (object, REF_INCREMENT);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_remove_reference
+ *
+ * PARAMETERS:  *Object        - Object whose ref count will be decremented
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Decrement the reference count of an ACPI internal object
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_remove_reference (
+	union acpi_operand_object       *object)
+{
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);
+
+
+	/*
+	 * Allow a NULL pointer to be passed in, just ignore it.  This saves
+	 * each caller from having to check.  Also, ignore NS nodes.
+	 *
+	 */
+	if (!object ||
+		(ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED)) {
+		return_VOID;
+	}
+
+	/* Ensure that we have a valid object */
+
+	if (!acpi_ut_valid_internal_object (object)) {
+		return_VOID;
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+		"Obj %p Current Refs=%X [To Be Decremented]\n",
+		object, object->common.reference_count));
+
+	/*
+	 * Decrement the reference count, and only actually delete the object
+	 * if the reference count becomes 0.  (Must also decrement the ref count
+	 * of all subobjects!)
+	 */
+	(void) acpi_ut_update_object_reference (object, REF_DECREMENT);
+	return_VOID;
+}
+
+
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
new file mode 100644
index 0000000..ead27d2
--- /dev/null
+++ b/drivers/acpi/utilities/uteval.c
@@ -0,0 +1,696 @@
+/******************************************************************************
+ *
+ * Module Name: uteval - Object evaluation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("uteval")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_osi_implementation
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Implementation of _OSI predefined control method
+ *              Supported = _OSI (String)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_osi_implementation (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *string_desc;
+	union acpi_operand_object       *return_desc;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("ut_osi_implementation");
+
+
+	/* Validate the string input argument */
+
+	string_desc = walk_state->arguments[0].object;
+	if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+	/* Create a return object (Default value = 0) */
+
+	return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!return_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Compare input string to table of supported strings */
+
+	for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
+		if (!ACPI_STRCMP (string_desc->string.pointer,
+				   (char *) acpi_gbl_valid_osi_strings[i])) {
+			/* This string is supported */
+
+			return_desc->integer.value = 0xFFFFFFFF;
+			break;
+		}
+	}
+
+	walk_state->return_desc = return_desc;
+	return_ACPI_STATUS (AE_CTRL_TERMINATE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_evaluate_object
+ *
+ * PARAMETERS:  prefix_node         - Starting node
+ *              Path                - Path to object from starting node
+ *              expected_return_types - Bitmap of allowed return types
+ *              return_desc         - Where a return value is stored
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Evaluates a namespace object and verifies the type of the
+ *              return object.  Common code that simplifies accessing objects
+ *              that have required return objects of fixed types.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_evaluate_object (
+	struct acpi_namespace_node      *prefix_node,
+	char                            *path,
+	u32                             expected_return_btypes,
+	union acpi_operand_object       **return_desc)
+{
+	struct acpi_parameter_info      info;
+	acpi_status                     status;
+	u32                             return_btype;
+
+
+	ACPI_FUNCTION_TRACE ("ut_evaluate_object");
+
+
+	info.node = prefix_node;
+	info.parameters = NULL;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
+	/* Evaluate the object/method */
+
+	status = acpi_ns_evaluate_relative (path, &info);
+	if (ACPI_FAILURE (status)) {
+		if (status == AE_NOT_FOUND) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
+				acpi_ut_get_node_name (prefix_node), path));
+		}
+		else {
+			ACPI_REPORT_METHOD_ERROR ("Method execution failed",
+				prefix_node, path, status);
+		}
+
+		return_ACPI_STATUS (status);
+	}
+
+	/* Did we get a return object? */
+
+	if (!info.return_object) {
+		if (expected_return_btypes) {
+			ACPI_REPORT_METHOD_ERROR ("No object was returned from",
+				prefix_node, path, AE_NOT_EXIST);
+
+			return_ACPI_STATUS (AE_NOT_EXIST);
+		}
+
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Map the return object type to the bitmapped type */
+
+	switch (ACPI_GET_OBJECT_TYPE (info.return_object)) {
+	case ACPI_TYPE_INTEGER:
+		return_btype = ACPI_BTYPE_INTEGER;
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		return_btype = ACPI_BTYPE_BUFFER;
+		break;
+
+	case ACPI_TYPE_STRING:
+		return_btype = ACPI_BTYPE_STRING;
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+		return_btype = ACPI_BTYPE_PACKAGE;
+		break;
+
+	default:
+		return_btype = 0;
+		break;
+	}
+
+	if ((acpi_gbl_enable_interpreter_slack) &&
+		(!expected_return_btypes)) {
+		/*
+		 * We received a return object, but one was not expected.  This can
+		 * happen frequently if the "implicit return" feature is enabled.
+		 * Just delete the return object and return AE_OK.
+		 */
+		acpi_ut_remove_reference (info.return_object);
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Is the return object one of the expected types? */
+
+	if (!(expected_return_btypes & return_btype)) {
+		ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
+			prefix_node, path, AE_TYPE);
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Type returned from %s was incorrect: %s, expected Btypes: %X\n",
+			path, acpi_ut_get_object_type_name (info.return_object),
+			expected_return_btypes));
+
+		/* On error exit, we must delete the return object */
+
+		acpi_ut_remove_reference (info.return_object);
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+	/* Object type is OK, return it */
+
+	*return_desc = info.return_object;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_evaluate_numeric_object
+ *
+ * PARAMETERS:  *object_name        - Object name to be evaluated
+ *              device_node         - Node for the device
+ *              *Address            - Where the value is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Evaluates a numeric namespace object for a selected device
+ *              and stores result in *Address.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_evaluate_numeric_object (
+	char                            *object_name,
+	struct acpi_namespace_node      *device_node,
+	acpi_integer                    *address)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object");
+
+
+	status = acpi_ut_evaluate_object (device_node, object_name,
+			 ACPI_BTYPE_INTEGER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get the returned Integer */
+
+	*address = obj_desc->integer.value;
+
+	/* On exit, we must delete the return object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_copy_id_string
+ *
+ * PARAMETERS:  Destination         - Where to copy the string
+ *              Source              - Source string
+ *              max_length          - Length of the destination buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
+ *              Performs removal of a leading asterisk if present -- workaround
+ *              for a known issue on a bunch of machines.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_copy_id_string (
+	char                            *destination,
+	char                            *source,
+	acpi_size                       max_length)
+{
+
+
+	/*
+	 * Workaround for ID strings that have a leading asterisk. This construct
+	 * is not allowed by the ACPI specification  (ID strings must be
+	 * alphanumeric), but enough existing machines have this embedded in their
+	 * ID strings that the following code is useful.
+	 */
+	if (*source == '*') {
+		source++;
+	}
+
+	/* Do the actual copy */
+
+	ACPI_STRNCPY (destination, source, max_length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_execute_HID
+ *
+ * PARAMETERS:  device_node         - Node for the device
+ *              *Hid                - Where the HID is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes the _HID control method that returns the hardware
+ *              ID of the device.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_HID (
+	struct acpi_namespace_node      *device_node,
+	struct acpi_device_id           *hid)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_execute_HID");
+
+
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID,
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+		/* Convert the Numeric HID to string */
+
+		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
+	}
+	else {
+		/* Copy the String HID from the returned object */
+
+		acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
+				sizeof (hid->value));
+	}
+
+	/* On exit, we must delete the return object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_translate_one_cid
+ *
+ * PARAMETERS:  obj_desc            - _CID object, must be integer or string
+ *              one_cid             - Where the CID string is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return a numeric or string _CID value as a string.
+ *              (Compatible ID)
+ *
+ *              NOTE:  Assumes a maximum _CID string length of
+ *                     ACPI_MAX_CID_LENGTH.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_translate_one_cid (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_compatible_id       *one_cid)
+{
+
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_INTEGER:
+
+		/* Convert the Numeric CID to string */
+
+		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
+		return (AE_OK);
+
+	case ACPI_TYPE_STRING:
+
+		if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
+			return (AE_AML_STRING_LIMIT);
+		}
+
+		/* Copy the String CID from the returned object */
+
+		acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
+				ACPI_MAX_CID_LENGTH);
+		return (AE_OK);
+
+	default:
+
+		return (AE_TYPE);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_execute_CID
+ *
+ * PARAMETERS:  device_node         - Node for the device
+ *              *Cid                - Where the CID is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes the _CID control method that returns one or more
+ *              compatible hardware IDs for the device.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_CID (
+	struct acpi_namespace_node      *device_node,
+	struct acpi_compatible_id_list **return_cid_list)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+	u32                             count;
+	u32                             size;
+	struct acpi_compatible_id_list *cid_list;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("ut_execute_CID");
+
+
+	/* Evaluate the _CID method for this device */
+
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
+			 &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Get the number of _CIDs returned */
+
+	count = 1;
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+		count = obj_desc->package.count;
+	}
+
+	/* Allocate a worst-case buffer for the _CIDs */
+
+	size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
+			   sizeof (struct acpi_compatible_id_list));
+
+	cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
+	if (!cid_list) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Init CID list */
+
+	cid_list->count = count;
+	cid_list->size = size;
+
+	/*
+	 *  A _CID can return either a single compatible ID or a package of compatible
+	 *  IDs.  Each compatible ID can be one of the following:
+	 *  -- Number (32 bit compressed EISA ID) or
+	 *  -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
+	 */
+
+	/* 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) {
+		/* Translate each package element */
+
+		for (i = 0; i < count; i++) {
+			status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
+					  &cid_list->id[i]);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+		}
+	}
+	else {
+		/* Only one CID, translate to a string */
+
+		status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
+	}
+
+	/* Cleanup on error */
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (cid_list);
+	}
+	else {
+		*return_cid_list = cid_list;
+	}
+
+	/* On exit, we must delete the _CID return object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_execute_UID
+ *
+ * PARAMETERS:  device_node         - Node for the device
+ *              *Uid                - Where the UID is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes the _UID control method that returns the hardware
+ *              ID of the device.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_UID (
+	struct acpi_namespace_node      *device_node,
+	struct acpi_device_id           *uid)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_execute_UID");
+
+
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID,
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+		/* Convert the Numeric UID to string */
+
+		acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
+	}
+	else {
+		/* Copy the String UID from the returned object */
+
+		acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
+				sizeof (uid->value));
+	}
+
+	/* On exit, we must delete the return object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_execute_STA
+ *
+ * PARAMETERS:  device_node         - Node for the device
+ *              *Flags              - Where the status flags are returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes _STA for selected device and stores results in
+ *              *Flags.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_STA (
+	struct acpi_namespace_node      *device_node,
+	u32                             *flags)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_execute_STA");
+
+
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA,
+			 ACPI_BTYPE_INTEGER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		if (AE_NOT_FOUND == status) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"_STA on %4.4s was not found, assuming device is present\n",
+				acpi_ut_get_node_name (device_node)));
+
+			*flags = 0x0F;
+			status = AE_OK;
+		}
+
+		return_ACPI_STATUS (status);
+	}
+
+	/* Extract the status flags */
+
+	*flags = (u32) obj_desc->integer.value;
+
+	/* On exit, we must delete the return object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_execute_Sxds
+ *
+ * PARAMETERS:  device_node         - Node for the device
+ *              *Flags              - Where the status flags are returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Executes _STA for selected device and stores results in
+ *              *Flags.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_execute_sxds (
+	struct acpi_namespace_node      *device_node,
+	u8                              *highest)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
+
+
+	for (i = 0; i < 4; i++) {
+		highest[i] = 0xFF;
+		status = acpi_ut_evaluate_object (device_node,
+				 (char *) acpi_gbl_highest_dstate_names[i],
+				 ACPI_BTYPE_INTEGER, &obj_desc);
+		if (ACPI_FAILURE (status)) {
+			if (status != AE_NOT_FOUND) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+					"%s on Device %4.4s, %s\n",
+					(char *) acpi_gbl_highest_dstate_names[i],
+					acpi_ut_get_node_name (device_node),
+					acpi_format_exception (status)));
+
+				return_ACPI_STATUS (status);
+			}
+		}
+		else {
+			/* Extract the Dstate value */
+
+			highest[i] = (u8) obj_desc->integer.value;
+
+			/* Delete the return object */
+
+			acpi_ut_remove_reference (obj_desc);
+		}
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
new file mode 100644
index 0000000..25b0f8a
--- /dev/null
+++ b/drivers/acpi/utilities/utglobal.c
@@ -0,0 +1,935 @@
+/******************************************************************************
+ *
+ * Module Name: utglobal - Global variables for the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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.
+ */
+
+#define DEFINE_ACPI_GLOBALS
+
+#include <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utglobal")
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_format_exception
+ *
+ * PARAMETERS:  Status       - The acpi_status code to be formatted
+ *
+ * RETURN:      A string containing the exception  text
+ *
+ * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
+ *
+ ******************************************************************************/
+
+const char *
+acpi_format_exception (
+	acpi_status                     status)
+{
+	const char                      *exception = "UNKNOWN_STATUS_CODE";
+	acpi_status                     sub_status;
+
+
+	ACPI_FUNCTION_NAME ("format_exception");
+
+
+	sub_status = (status & ~AE_CODE_MASK);
+
+	switch (status & AE_CODE_MASK) {
+	case AE_CODE_ENVIRONMENTAL:
+
+		if (sub_status <= AE_CODE_ENV_MAX) {
+			exception = acpi_gbl_exception_names_env [sub_status];
+			break;
+		}
+		goto unknown;
+
+	case AE_CODE_PROGRAMMER:
+
+		if (sub_status <= AE_CODE_PGM_MAX) {
+			exception = acpi_gbl_exception_names_pgm [sub_status -1];
+			break;
+		}
+		goto unknown;
+
+	case AE_CODE_ACPI_TABLES:
+
+		if (sub_status <= AE_CODE_TBL_MAX) {
+			exception = acpi_gbl_exception_names_tbl [sub_status -1];
+			break;
+		}
+		goto unknown;
+
+	case AE_CODE_AML:
+
+		if (sub_status <= AE_CODE_AML_MAX) {
+			exception = acpi_gbl_exception_names_aml [sub_status -1];
+			break;
+		}
+		goto unknown;
+
+	case AE_CODE_CONTROL:
+
+		if (sub_status <= AE_CODE_CTRL_MAX) {
+			exception = acpi_gbl_exception_names_ctrl [sub_status -1];
+			break;
+		}
+		goto unknown;
+
+	default:
+		goto unknown;
+	}
+
+
+	return ((const char *) exception);
+
+unknown:
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown exception code: 0x%8.8X\n", status));
+	return ((const char *) exception);
+}
+
+
+/******************************************************************************
+ *
+ * Static global variable initialization.
+ *
+ ******************************************************************************/
+
+/*
+ * We want the debug switches statically initialized so they
+ * are already set when the debugger is entered.
+ */
+
+/* Debug switch - level and trace mask */
+u32                                 acpi_dbg_level = ACPI_DEBUG_DEFAULT;
+EXPORT_SYMBOL(acpi_dbg_level);
+
+/* Debug switch - layer (component) mask */
+
+u32                                 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
+EXPORT_SYMBOL(acpi_dbg_layer);
+u32                                 acpi_gbl_nesting_level = 0;
+
+
+/* Debugger globals */
+
+u8                                  acpi_gbl_db_terminate_threads = FALSE;
+u8                                  acpi_gbl_abort_method = FALSE;
+u8                                  acpi_gbl_method_executing = FALSE;
+
+/* System flags */
+
+u32                                 acpi_gbl_startup_flags = 0;
+
+/* System starts uninitialized */
+
+u8                                  acpi_gbl_shutdown = TRUE;
+
+const u8                            acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
+
+const char                          *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] =
+{
+	"\\_S0_",
+	"\\_S1_",
+	"\\_S2_",
+	"\\_S3_",
+	"\\_S4_",
+	"\\_S5_"
+};
+
+const char                          *acpi_gbl_highest_dstate_names[4] =
+{
+	"_S1D",
+	"_S2D",
+	"_S3D",
+	"_S4D"
+};
+
+/*
+ * Strings supported by the _OSI predefined (internal) method.
+ * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS.
+ */
+const char                          *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] =
+{
+	/* Operating System Vendor Strings */
+
+	"Linux",
+	"Windows 2000",
+	"Windows 2001",
+	"Windows 2001.1",
+	"Windows 2001 SP0",
+	"Windows 2001 SP1",
+	"Windows 2001 SP2",
+	"Windows 2001 SP3",
+	"Windows 2001 SP4",
+
+	/* Feature Group Strings */
+
+	"Extended Address Space Descriptor"
+};
+
+
+/******************************************************************************
+ *
+ * Namespace globals
+ *
+ ******************************************************************************/
+
+
+/*
+ * Predefined ACPI Names (Built-in to the Interpreter)
+ *
+ * NOTES:
+ * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
+ *    during the initialization sequence.
+ * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
+ *    perform a Notify() operation on it.
+ */
+const struct acpi_predefined_names      acpi_gbl_pre_defined_names[] =
+{ {"_GPE",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
+	{"_PR_",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
+	{"_SB_",    ACPI_TYPE_DEVICE,           NULL},
+	{"_SI_",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
+	{"_TZ_",    ACPI_TYPE_THERMAL,          NULL},
+	{"_REV",    ACPI_TYPE_INTEGER,          (char *) ACPI_CA_SUPPORT_LEVEL},
+	{"_OS_",    ACPI_TYPE_STRING,           ACPI_OS_NAME},
+	{"_GL_",    ACPI_TYPE_MUTEX,            (char *) 1},
+
+#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+	{"_OSI",    ACPI_TYPE_METHOD,           (char *) 1},
+#endif
+	{NULL,      ACPI_TYPE_ANY,              NULL}              /* Table terminator */
+};
+
+
+/*
+ * Properties of the ACPI Object Types, both internal and external.
+ * The table is indexed by values of acpi_object_type
+ */
+const u8                                acpi_gbl_ns_properties[] =
+{
+	ACPI_NS_NORMAL,                     /* 00 Any              */
+	ACPI_NS_NORMAL,                     /* 01 Number           */
+	ACPI_NS_NORMAL,                     /* 02 String           */
+	ACPI_NS_NORMAL,                     /* 03 Buffer           */
+	ACPI_NS_NORMAL,                     /* 04 Package          */
+	ACPI_NS_NORMAL,                     /* 05 field_unit       */
+	ACPI_NS_NEWSCOPE,                   /* 06 Device           */
+	ACPI_NS_NORMAL,                     /* 07 Event            */
+	ACPI_NS_NEWSCOPE,                   /* 08 Method           */
+	ACPI_NS_NORMAL,                     /* 09 Mutex            */
+	ACPI_NS_NORMAL,                     /* 10 Region           */
+	ACPI_NS_NEWSCOPE,                   /* 11 Power            */
+	ACPI_NS_NEWSCOPE,                   /* 12 Processor        */
+	ACPI_NS_NEWSCOPE,                   /* 13 Thermal          */
+	ACPI_NS_NORMAL,                     /* 14 buffer_field     */
+	ACPI_NS_NORMAL,                     /* 15 ddb_handle       */
+	ACPI_NS_NORMAL,                     /* 16 Debug Object     */
+	ACPI_NS_NORMAL,                     /* 17 def_field        */
+	ACPI_NS_NORMAL,                     /* 18 bank_field       */
+	ACPI_NS_NORMAL,                     /* 19 index_field      */
+	ACPI_NS_NORMAL,                     /* 20 Reference        */
+	ACPI_NS_NORMAL,                     /* 21 Alias            */
+	ACPI_NS_NORMAL,                     /* 22 method_alias     */
+	ACPI_NS_NORMAL,                     /* 23 Notify           */
+	ACPI_NS_NORMAL,                     /* 24 Address Handler  */
+	ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL,   /* 25 Resource Desc    */
+	ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL,   /* 26 Resource Field   */
+	ACPI_NS_NEWSCOPE,                   /* 27 Scope            */
+	ACPI_NS_NORMAL,                     /* 28 Extra            */
+	ACPI_NS_NORMAL,                     /* 29 Data             */
+	ACPI_NS_NORMAL                      /* 30 Invalid          */
+};
+
+
+/* Hex to ASCII conversion table */
+
+static const char                   acpi_gbl_hex_to_ascii[] =
+			  {'0','1','2','3','4','5','6','7',
+					 '8','9','A','B','C','D','E','F'};
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_hex_to_ascii_char
+ *
+ * PARAMETERS:  Integer             - Contains the hex digit
+ *              Position            - bit position of the digit within the
+ *                                    integer
+ *
+ * RETURN:      Ascii character
+ *
+ * DESCRIPTION: Convert a hex digit to an ascii character
+ *
+ ****************************************************************************/
+
+char
+acpi_ut_hex_to_ascii_char (
+	acpi_integer                    integer,
+	u32                             position)
+{
+
+	return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
+}
+
+
+/******************************************************************************
+ *
+ * Table name globals
+ *
+ * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes.
+ * it is NOT an exhaustive list of all possible ACPI tables.  All ACPI tables
+ * that are not used by the subsystem are simply ignored.
+ *
+ * Do NOT add any table to this list that is not consumed directly by this
+ * subsystem.
+ *
+ ******************************************************************************/
+
+struct acpi_table_list              acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
+
+struct acpi_table_support           acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
+{
+	/***********    Name,   Signature, Global typed pointer     Signature size,      Type                  How many allowed?,    Contains valid AML? */
+
+	/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL,                    sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT     | ACPI_TABLE_SINGLE},
+	/* DSDT 1 */ {DSDT_SIG,  DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE   | ACPI_TABLE_EXECUTABLE},
+	/* FADT 2 */ {FADT_SIG,  FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY  | ACPI_TABLE_SINGLE},
+	/* FACS 3 */ {FACS_SIG,  FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
+	/* PSDT 4 */ {PSDT_SIG,  PSDT_SIG, NULL,                    sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY  | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
+	/* SSDT 5 */ {SSDT_SIG,  SSDT_SIG, NULL,                    sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY  | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
+	/* XSDT 6 */ {XSDT_SIG,  XSDT_SIG, NULL,                    sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT     | ACPI_TABLE_SINGLE},
+};
+
+
+/******************************************************************************
+ *
+ * Event and Hardware globals
+ *
+ ******************************************************************************/
+
+struct acpi_bit_register_info       acpi_gbl_bit_register_info[ACPI_NUM_BITREG] =
+{
+	/* Name                                     Parent Register             Register Bit Position                   Register Bit Mask       */
+
+	/* ACPI_BITREG_TIMER_STATUS         */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_TIMER_STATUS,          ACPI_BITMASK_TIMER_STATUS},
+	/* ACPI_BITREG_BUS_MASTER_STATUS    */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_BUS_MASTER_STATUS,     ACPI_BITMASK_BUS_MASTER_STATUS},
+	/* ACPI_BITREG_GLOBAL_LOCK_STATUS   */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_GLOBAL_LOCK_STATUS,    ACPI_BITMASK_GLOBAL_LOCK_STATUS},
+	/* ACPI_BITREG_POWER_BUTTON_STATUS  */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_POWER_BUTTON_STATUS,   ACPI_BITMASK_POWER_BUTTON_STATUS},
+	/* ACPI_BITREG_SLEEP_BUTTON_STATUS  */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_SLEEP_BUTTON_STATUS,   ACPI_BITMASK_SLEEP_BUTTON_STATUS},
+	/* ACPI_BITREG_RT_CLOCK_STATUS      */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_RT_CLOCK_STATUS,       ACPI_BITMASK_RT_CLOCK_STATUS},
+	/* ACPI_BITREG_WAKE_STATUS          */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_WAKE_STATUS,           ACPI_BITMASK_WAKE_STATUS},
+	/* ACPI_BITREG_PCIEXP_WAKE_STATUS   */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_PCIEXP_WAKE_STATUS,    ACPI_BITMASK_PCIEXP_WAKE_STATUS},
+
+	/* ACPI_BITREG_TIMER_ENABLE         */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_TIMER_ENABLE,          ACPI_BITMASK_TIMER_ENABLE},
+	/* ACPI_BITREG_GLOBAL_LOCK_ENABLE   */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE,    ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
+	/* ACPI_BITREG_POWER_BUTTON_ENABLE  */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_POWER_BUTTON_ENABLE,   ACPI_BITMASK_POWER_BUTTON_ENABLE},
+	/* ACPI_BITREG_SLEEP_BUTTON_ENABLE  */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE,   ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
+	/* ACPI_BITREG_RT_CLOCK_ENABLE      */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_RT_CLOCK_ENABLE,       ACPI_BITMASK_RT_CLOCK_ENABLE},
+	/* ACPI_BITREG_WAKE_ENABLE          */   {ACPI_REGISTER_PM1_ENABLE,   0,                                      0},
+	/* ACPI_BITREG_PCIEXP_WAKE_DISABLE  */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE,   ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
+
+	/* ACPI_BITREG_SCI_ENABLE           */   {ACPI_REGISTER_PM1_CONTROL,  ACPI_BITPOSITION_SCI_ENABLE,            ACPI_BITMASK_SCI_ENABLE},
+	/* ACPI_BITREG_BUS_MASTER_RLD       */   {ACPI_REGISTER_PM1_CONTROL,  ACPI_BITPOSITION_BUS_MASTER_RLD,        ACPI_BITMASK_BUS_MASTER_RLD},
+	/* 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_ENABLE         */   {ACPI_REGISTER_PM1_CONTROL,  ACPI_BITPOSITION_SLEEP_ENABLE,          ACPI_BITMASK_SLEEP_ENABLE},
+
+	/* ACPI_BITREG_ARB_DIS              */   {ACPI_REGISTER_PM2_CONTROL,  ACPI_BITPOSITION_ARB_DISABLE,           ACPI_BITMASK_ARB_DISABLE}
+};
+
+
+struct acpi_fixed_event_info        acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
+{
+	/* ACPI_EVENT_PMTIMER       */  {ACPI_BITREG_TIMER_STATUS,          ACPI_BITREG_TIMER_ENABLE,        ACPI_BITMASK_TIMER_STATUS,          ACPI_BITMASK_TIMER_ENABLE},
+	/* ACPI_EVENT_GLOBAL        */  {ACPI_BITREG_GLOBAL_LOCK_STATUS,    ACPI_BITREG_GLOBAL_LOCK_ENABLE,  ACPI_BITMASK_GLOBAL_LOCK_STATUS,    ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
+	/* ACPI_EVENT_POWER_BUTTON  */  {ACPI_BITREG_POWER_BUTTON_STATUS,   ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS,   ACPI_BITMASK_POWER_BUTTON_ENABLE},
+	/* ACPI_EVENT_SLEEP_BUTTON  */  {ACPI_BITREG_SLEEP_BUTTON_STATUS,   ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS,   ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
+	/* ACPI_EVENT_RTC           */  {ACPI_BITREG_RT_CLOCK_STATUS,       ACPI_BITREG_RT_CLOCK_ENABLE,     ACPI_BITMASK_RT_CLOCK_STATUS,       ACPI_BITMASK_RT_CLOCK_ENABLE},
+};
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_region_name
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a Space ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+/* Region type decoding */
+
+const char                *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] =
+{
+/*! [Begin] no source code translation (keep these ASL Keywords as-is) */
+	"SystemMemory",
+	"SystemIO",
+	"PCI_Config",
+	"EmbeddedControl",
+	"SMBus",
+	"CMOS",
+	"PCIBARTarget",
+	"DataTable"
+/*! [End] no source code translation !*/
+};
+
+
+char *
+acpi_ut_get_region_name (
+	u8                              space_id)
+{
+
+	if (space_id >= ACPI_USER_REGION_BEGIN)
+	{
+		return ("user_defined_region");
+	}
+
+	else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS)
+	{
+		return ("invalid_space_id");
+	}
+
+	return ((char *) acpi_gbl_region_types[space_id]);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_event_name
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a Event ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+/* Event type decoding */
+
+static const char                *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] =
+{
+	"PM_Timer",
+	"global_lock",
+	"power_button",
+	"sleep_button",
+	"real_time_clock",
+};
+
+
+char *
+acpi_ut_get_event_name (
+	u32                             event_id)
+{
+
+	if (event_id > ACPI_EVENT_MAX)
+	{
+		return ("invalid_event_iD");
+	}
+
+	return ((char *) acpi_gbl_event_types[event_id]);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_type_name
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a Type ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+/*
+ * Elements of acpi_gbl_ns_type_names below must match
+ * one-to-one with values of acpi_object_type
+ *
+ * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when
+ * stored in a table it really means that we have thus far seen no evidence to
+ * indicate what type is actually going to be stored for this entry.
+ */
+static const char                   acpi_gbl_bad_type[] = "UNDEFINED";
+#define TYPE_NAME_LENGTH    12                           /* Maximum length of each string */
+
+static const char                   *acpi_gbl_ns_type_names[] = /* printable names of ACPI types */
+{
+	/* 00 */ "Untyped",
+	/* 01 */ "Integer",
+	/* 02 */ "String",
+	/* 03 */ "Buffer",
+	/* 04 */ "Package",
+	/* 05 */ "field_unit",
+	/* 06 */ "Device",
+	/* 07 */ "Event",
+	/* 08 */ "Method",
+	/* 09 */ "Mutex",
+	/* 10 */ "Region",
+	/* 11 */ "Power",
+	/* 12 */ "Processor",
+	/* 13 */ "Thermal",
+	/* 14 */ "buffer_field",
+	/* 15 */ "ddb_handle",
+	/* 16 */ "debug_object",
+	/* 17 */ "region_field",
+	/* 18 */ "bank_field",
+	/* 19 */ "index_field",
+	/* 20 */ "Reference",
+	/* 21 */ "Alias",
+	/* 22 */ "method_alias",
+	/* 23 */ "Notify",
+	/* 24 */ "addr_handler",
+	/* 25 */ "resource_desc",
+	/* 26 */ "resource_fld",
+	/* 27 */ "Scope",
+	/* 28 */ "Extra",
+	/* 29 */ "Data",
+	/* 30 */ "Invalid"
+};
+
+
+char *
+acpi_ut_get_type_name (
+	acpi_object_type                type)
+{
+
+	if (type > ACPI_TYPE_INVALID)
+	{
+		return ((char *) acpi_gbl_bad_type);
+	}
+
+	return ((char *) acpi_gbl_ns_type_names[type]);
+}
+
+
+char *
+acpi_ut_get_object_type_name (
+	union acpi_operand_object       *obj_desc)
+{
+
+	if (!obj_desc)
+	{
+		return ("[NULL Object Descriptor]");
+	}
+
+	return (acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)));
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_node_name
+ *
+ * PARAMETERS:  Object               - A namespace node
+ *
+ * RETURN:      Pointer to a string
+ *
+ * DESCRIPTION: Validate the node and return the node's ACPI name.
+ *
+ ****************************************************************************/
+
+char *
+acpi_ut_get_node_name (
+	void                            *object)
+{
+	struct acpi_namespace_node      *node = (struct acpi_namespace_node *) object;
+
+
+	/* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
+
+	if (!object)
+	{
+		return ("NULL");
+	}
+
+	/* Check for Root node */
+
+	if ((object == ACPI_ROOT_OBJECT) ||
+		(object == acpi_gbl_root_node))
+	{
+		return ("\"\\\" ");
+	}
+
+	/* Descriptor must be a namespace node */
+
+	if (node->descriptor != ACPI_DESC_TYPE_NAMED)
+	{
+		return ("####");
+	}
+
+	/* Name must be a valid ACPI name */
+
+	if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii))
+	{
+		return ("????");
+	}
+
+	/* Return the name */
+
+	return (node->name.ascii);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_descriptor_name
+ *
+ * PARAMETERS:  Object               - An ACPI object
+ *
+ * RETURN:      Pointer to a string
+ *
+ * DESCRIPTION: Validate object and return the descriptor type
+ *
+ ****************************************************************************/
+
+static const char                   *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */
+{
+	/* 00 */ "Invalid",
+	/* 01 */ "Cached",
+	/* 02 */ "State-Generic",
+	/* 03 */ "State-Update",
+	/* 04 */ "State-Package",
+	/* 05 */ "State-Control",
+	/* 06 */ "State-root_parse_scope",
+	/* 07 */ "State-parse_scope",
+	/* 08 */ "State-walk_scope",
+	/* 09 */ "State-Result",
+	/* 10 */ "State-Notify",
+	/* 11 */ "State-Thread",
+	/* 12 */ "Walk",
+	/* 13 */ "Parser",
+	/* 14 */ "Operand",
+	/* 15 */ "Node"
+};
+
+
+char *
+acpi_ut_get_descriptor_name (
+	void                            *object)
+{
+
+	if (!object)
+	{
+		return ("NULL OBJECT");
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX)
+	{
+		return ((char *) acpi_gbl_bad_type);
+	}
+
+	return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]);
+
+}
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+/*
+ * Strings and procedures used for debug only
+ */
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_mutex_name
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
+ *
+ ****************************************************************************/
+
+char *
+acpi_ut_get_mutex_name (
+	u32                             mutex_id)
+{
+
+	if (mutex_id > MAX_MUTEX)
+	{
+		return ("Invalid Mutex ID");
+	}
+
+	return (acpi_gbl_mutex_names[mutex_id]);
+}
+
+#endif
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_valid_object_type
+ *
+ * PARAMETERS:  Type            - Object type to be validated
+ *
+ * RETURN:      TRUE if valid object type
+ *
+ * DESCRIPTION: Validate an object type
+ *
+ ****************************************************************************/
+
+u8
+acpi_ut_valid_object_type (
+	acpi_object_type                type)
+{
+
+	if (type > ACPI_TYPE_LOCAL_MAX)
+	{
+		/* Note: Assumes all TYPEs are contiguous (external/local) */
+
+		return (FALSE);
+	}
+
+	return (TRUE);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_allocate_owner_id
+ *
+ * PARAMETERS:  id_type         - Type of ID (method or table)
+ *
+ * DESCRIPTION: Allocate a table or method owner id
+ *
+ ***************************************************************************/
+
+acpi_owner_id
+acpi_ut_allocate_owner_id (
+	u32                             id_type)
+{
+	acpi_owner_id                   owner_id = 0xFFFF;
+
+
+	ACPI_FUNCTION_TRACE ("ut_allocate_owner_id");
+
+
+	if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES)))
+	{
+		return (0);
+	}
+
+	switch (id_type)
+	{
+	case ACPI_OWNER_TYPE_TABLE:
+
+		owner_id = acpi_gbl_next_table_owner_id;
+		acpi_gbl_next_table_owner_id++;
+
+		/* Check for wraparound */
+
+		if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID)
+		{
+			acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
+			ACPI_REPORT_WARNING (("Table owner ID wraparound\n"));
+		}
+		break;
+
+
+	case ACPI_OWNER_TYPE_METHOD:
+
+		owner_id = acpi_gbl_next_method_owner_id;
+		acpi_gbl_next_method_owner_id++;
+
+		if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID)
+		{
+			/* Check for wraparound */
+
+			acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
+	return_VALUE (owner_id);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_init_globals
+ *
+ * PARAMETERS:  none
+ *
+ * DESCRIPTION: Init library globals.  All globals that require specific
+ *              initialization should be initialized here!
+ *
+ ***************************************************************************/
+
+void
+acpi_ut_init_globals (
+	void)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ut_init_globals");
+
+
+	/* Memory allocation and cache lists */
+
+	ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS);
+
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].link_offset      = (u16) ACPI_PTR_DIFF (&(((union acpi_generic_state *) NULL)->common.next), NULL);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].link_offset     = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].link_offset    = (u16) ACPI_PTR_DIFF (&(((union acpi_operand_object *) NULL)->cache.next), NULL);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].link_offset       = (u16) ACPI_PTR_DIFF (&(((struct acpi_walk_state *) NULL)->next), NULL);
+
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].object_size     = sizeof (struct acpi_namespace_node);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].object_size      = sizeof (union acpi_generic_state);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].object_size     = sizeof (struct acpi_parse_obj_common);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].object_size = sizeof (struct acpi_parse_obj_named);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size    = sizeof (union acpi_operand_object);
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size       = sizeof (struct acpi_walk_state);
+
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth  = ACPI_MAX_STATE_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = ACPI_MAX_PARSE_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = ACPI_MAX_EXTPARSE_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = ACPI_MAX_OBJECT_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth   = ACPI_MAX_WALK_CACHE_DEPTH;
+
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].list_name    = "Global Memory Allocation");
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].list_name    = "Namespace Nodes");
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].list_name     = "State Object Cache");
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].list_name    = "Parse Node Cache");
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].list_name = "Extended Parse Node Cache");
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].list_name   = "Operand Object Cache");
+	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].list_name      = "Tree Walk Node Cache");
+
+	/* ACPI table structure */
+
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
+	{
+		acpi_gbl_table_lists[i].next        = NULL;
+		acpi_gbl_table_lists[i].count       = 0;
+	}
+
+	/* Mutex locked flags */
+
+	for (i = 0; i < NUM_MUTEX; i++)
+	{
+		acpi_gbl_mutex_info[i].mutex        = NULL;
+		acpi_gbl_mutex_info[i].owner_id     = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_mutex_info[i].use_count    = 0;
+	}
+
+	/* GPE support */
+
+	acpi_gbl_gpe_xrupt_list_head        = NULL;
+	acpi_gbl_gpe_fadt_blocks[0]         = NULL;
+	acpi_gbl_gpe_fadt_blocks[1]         = NULL;
+
+	/* Global notify handlers */
+
+	acpi_gbl_system_notify.handler      = NULL;
+	acpi_gbl_device_notify.handler      = NULL;
+	acpi_gbl_exception_handler          = NULL;
+	acpi_gbl_init_handler               = NULL;
+
+	/* Global "typed" ACPI table pointers */
+
+	acpi_gbl_RSDP                       = NULL;
+	acpi_gbl_XSDT                       = NULL;
+	acpi_gbl_FACS                       = NULL;
+	acpi_gbl_FADT                       = NULL;
+	acpi_gbl_DSDT                       = NULL;
+
+	/* Global Lock support */
+
+	acpi_gbl_global_lock_acquired       = FALSE;
+	acpi_gbl_global_lock_thread_count   = 0;
+	acpi_gbl_global_lock_handle         = 0;
+
+	/* Miscellaneous variables */
+
+	acpi_gbl_table_flags                = ACPI_PHYSICAL_POINTER;
+	acpi_gbl_rsdp_original_location     = 0;
+	acpi_gbl_cm_single_step             = FALSE;
+	acpi_gbl_db_terminate_threads       = FALSE;
+	acpi_gbl_shutdown                   = FALSE;
+	acpi_gbl_ns_lookup_count            = 0;
+	acpi_gbl_ps_find_count              = 0;
+	acpi_gbl_acpi_hardware_present      = TRUE;
+	acpi_gbl_next_table_owner_id        = ACPI_FIRST_TABLE_ID;
+	acpi_gbl_next_method_owner_id       = ACPI_FIRST_METHOD_ID;
+	acpi_gbl_debugger_configuration     = DEBUGGER_THREADING;
+	acpi_gbl_db_output_flags            = ACPI_DB_CONSOLE_OUTPUT;
+
+	/* Hardware oriented */
+
+	acpi_gbl_events_initialized         = FALSE;
+	acpi_gbl_system_awake_and_running   = TRUE;
+
+	/* Namespace */
+
+	acpi_gbl_root_node                  = NULL;
+
+	acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
+	acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED;
+	acpi_gbl_root_node_struct.type      = ACPI_TYPE_DEVICE;
+	acpi_gbl_root_node_struct.child     = NULL;
+	acpi_gbl_root_node_struct.peer      = NULL;
+	acpi_gbl_root_node_struct.object    = NULL;
+	acpi_gbl_root_node_struct.flags     = ANOBJ_END_OF_PEER_LIST;
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+	acpi_gbl_lowest_stack_pointer       = ACPI_SIZE_MAX;
+#endif
+
+	return_VOID;
+}
+
+
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
new file mode 100644
index 0000000..bdbadaf
--- /dev/null
+++ b/drivers/acpi/utilities/utinit.c
@@ -0,0 +1,266 @@
+/******************************************************************************
+ *
+ * Module Name: utinit - Common ACPI subsystem initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utinit")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_fadt_register_error
+ *
+ * PARAMETERS:  *register_name          - Pointer to string identifying register
+ *              Value                   - Actual register contents value
+ *              acpi_test_spec_section  - TDS section containing assertion
+ *              acpi_assertion          - Assertion number being tested
+ *
+ * RETURN:      AE_BAD_VALUE
+ *
+ * DESCRIPTION: Display failure message and link failure to TDS assertion
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_fadt_register_error (
+	char                            *register_name,
+	u32                             value,
+	acpi_size                       offset)
+{
+
+	ACPI_REPORT_WARNING (
+		("Invalid FADT value %s=%X at offset %X FADT=%p\n",
+		register_name, value, (u32) offset, acpi_gbl_FADT));
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_validate_fadt
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validate various ACPI registers in the FADT
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_validate_fadt (
+	void)
+{
+
+	/*
+	 * Verify Fixed ACPI Description Table fields,
+	 * but don't abort on any problems, just display error
+	 */
+	if (acpi_gbl_FADT->pm1_evt_len < 4) {
+		acpi_ut_fadt_register_error ("PM1_EVT_LEN",
+				  (u32) acpi_gbl_FADT->pm1_evt_len,
+				  ACPI_FADT_OFFSET (pm1_evt_len));
+	}
+
+	if (!acpi_gbl_FADT->pm1_cnt_len) {
+		acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0,
+				  ACPI_FADT_OFFSET (pm1_cnt_len));
+	}
+
+	if (!acpi_gbl_FADT->xpm1a_evt_blk.address) {
+		acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0,
+				  ACPI_FADT_OFFSET (xpm1a_evt_blk.address));
+	}
+
+	if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) {
+		acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0,
+				  ACPI_FADT_OFFSET (xpm1a_cnt_blk.address));
+	}
+
+	if (!acpi_gbl_FADT->xpm_tmr_blk.address) {
+		acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0,
+				  ACPI_FADT_OFFSET (xpm_tmr_blk.address));
+	}
+
+	if ((acpi_gbl_FADT->xpm2_cnt_blk.address &&
+		!acpi_gbl_FADT->pm2_cnt_len)) {
+		acpi_ut_fadt_register_error ("PM2_CNT_LEN",
+				  (u32) acpi_gbl_FADT->pm2_cnt_len,
+				  ACPI_FADT_OFFSET (pm2_cnt_len));
+	}
+
+	if (acpi_gbl_FADT->pm_tm_len < 4) {
+		acpi_ut_fadt_register_error ("PM_TM_LEN",
+				  (u32) acpi_gbl_FADT->pm_tm_len,
+				  ACPI_FADT_OFFSET (pm_tm_len));
+	}
+
+	/* Length of GPE blocks must be a multiple of 2 */
+
+	if (acpi_gbl_FADT->xgpe0_blk.address &&
+		(acpi_gbl_FADT->gpe0_blk_len & 1)) {
+		acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN",
+				  (u32) acpi_gbl_FADT->gpe0_blk_len,
+				  ACPI_FADT_OFFSET (gpe0_blk_len));
+	}
+
+	if (acpi_gbl_FADT->xgpe1_blk.address &&
+		(acpi_gbl_FADT->gpe1_blk_len & 1)) {
+		acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN",
+				  (u32) acpi_gbl_FADT->gpe1_blk_len,
+				  ACPI_FADT_OFFSET (gpe1_blk_len));
+	}
+
+	return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_terminate
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: free global memory
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_terminate (void)
+{
+	struct acpi_gpe_block_info      *gpe_block;
+	struct acpi_gpe_block_info      *next_gpe_block;
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info;
+	struct acpi_gpe_xrupt_info      *next_gpe_xrupt_info;
+
+
+	ACPI_FUNCTION_TRACE ("ut_terminate");
+
+
+	/* Free global tables, etc. */
+
+
+	/* Free global GPE blocks and related info structures */
+
+	gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
+	while (gpe_xrupt_info) {
+		gpe_block = gpe_xrupt_info->gpe_block_list_head;
+		while (gpe_block) {
+			next_gpe_block = gpe_block->next;
+			ACPI_MEM_FREE (gpe_block->event_info);
+			ACPI_MEM_FREE (gpe_block->register_info);
+			ACPI_MEM_FREE (gpe_block);
+
+			gpe_block = next_gpe_block;
+		}
+		next_gpe_xrupt_info = gpe_xrupt_info->next;
+		ACPI_MEM_FREE (gpe_xrupt_info);
+		gpe_xrupt_info = next_gpe_xrupt_info;
+	}
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_subsystem_shutdown
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Shutdown the various subsystems.  Don't delete the mutex
+ *              objects here -- because the AML debugger may be still running.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_subsystem_shutdown (void)
+{
+
+	ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown");
+
+	/* Just exit if subsystem is already shutdown */
+
+	if (acpi_gbl_shutdown) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "ACPI Subsystem is already terminated\n"));
+		return_VOID;
+	}
+
+	/* Subsystem appears active, go ahead and shut it down */
+
+	acpi_gbl_shutdown = TRUE;
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n"));
+
+	/* Close the acpi_event Handling */
+
+	acpi_ev_terminate ();
+
+	/* Close the Namespace */
+
+	acpi_ns_terminate ();
+
+	/* Close the globals */
+
+	acpi_ut_terminate ();
+
+	/* Purge the local caches */
+
+	(void) acpi_purge_cached_objects ();
+
+	/* Debug only - display leftover memory allocation, if any */
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+	acpi_ut_dump_allocations (ACPI_UINT32_MAX, NULL);
+#endif
+
+	return_VOID;
+}
+
+
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
new file mode 100644
index 0000000..2525c1a
--- /dev/null
+++ b/drivers/acpi/utilities/utmath.c
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ *
+ * Module Name: utmath - Integer math support routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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>
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utmath")
+
+/*
+ * Support for double-precision integer divide.  This code is included here
+ * in order to support kernel environments where the double-precision math
+ * library is not available.
+ */
+
+#ifndef ACPI_USE_NATIVE_DIVIDE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_short_divide
+ *
+ * PARAMETERS:  Dividend            - 64-bit dividend
+ *              Divisor             - 32-bit divisor
+ *              out_quotient        - Pointer to where the quotient is returned
+ *              out_remainder       - Pointer to where the remainder is returned
+ *
+ * RETURN:      Status (Checks for divide-by-zero)
+ *
+ * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
+ *              divide and modulo.  The result is a 64-bit quotient and a
+ *              32-bit remainder.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_short_divide (
+	acpi_integer                    dividend,
+	u32                             divisor,
+	acpi_integer                    *out_quotient,
+	u32                             *out_remainder)
+{
+	union uint64_overlay            dividend_ovl;
+	union uint64_overlay            quotient;
+	u32                             remainder32;
+
+
+	ACPI_FUNCTION_TRACE ("ut_short_divide");
+
+
+	/* Always check for a zero divisor */
+
+	if (divisor == 0) {
+		ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n"));
+		return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+	}
+
+	dividend_ovl.full = dividend;
+
+	/*
+	 * The quotient is 64 bits, the remainder is always 32 bits,
+	 * and is generated by the second divide.
+	 */
+	ACPI_DIV_64_BY_32 (0, dividend_ovl.part.hi, divisor,
+			  quotient.part.hi, remainder32);
+	ACPI_DIV_64_BY_32 (remainder32, dividend_ovl.part.lo, divisor,
+			  quotient.part.lo, remainder32);
+
+	/* Return only what was requested */
+
+	if (out_quotient) {
+		*out_quotient = quotient.full;
+	}
+	if (out_remainder) {
+		*out_remainder = remainder32;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_divide
+ *
+ * PARAMETERS:  in_dividend         - Dividend
+ *              in_divisor          - Divisor
+ *              out_quotient        - Pointer to where the quotient is returned
+ *              out_remainder       - Pointer to where the remainder is returned
+ *
+ * RETURN:      Status (Checks for divide-by-zero)
+ *
+ * DESCRIPTION: Perform a divide and modulo.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_divide (
+	acpi_integer                    in_dividend,
+	acpi_integer                    in_divisor,
+	acpi_integer                    *out_quotient,
+	acpi_integer                    *out_remainder)
+{
+	union uint64_overlay            dividend;
+	union uint64_overlay            divisor;
+	union uint64_overlay            quotient;
+	union uint64_overlay            remainder;
+	union uint64_overlay            normalized_dividend;
+	union uint64_overlay            normalized_divisor;
+	u32                             partial1;
+	union uint64_overlay            partial2;
+	union uint64_overlay            partial3;
+
+
+	ACPI_FUNCTION_TRACE ("ut_divide");
+
+
+	/* Always check for a zero divisor */
+
+	if (in_divisor == 0) {
+		ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n"));
+		return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+	}
+
+	divisor.full  = in_divisor;
+	dividend.full = in_dividend;
+	if (divisor.part.hi == 0) {
+		/*
+		 * 1) Simplest case is where the divisor is 32 bits, we can
+		 * just do two divides
+		 */
+		remainder.part.hi = 0;
+
+		/*
+		 * The quotient is 64 bits, the remainder is always 32 bits,
+		 * and is generated by the second divide.
+		 */
+		ACPI_DIV_64_BY_32 (0, dividend.part.hi, divisor.part.lo,
+				  quotient.part.hi, partial1);
+		ACPI_DIV_64_BY_32 (partial1, dividend.part.lo, divisor.part.lo,
+				  quotient.part.lo, remainder.part.lo);
+	}
+
+	else {
+		/*
+		 * 2) The general case where the divisor is a full 64 bits
+		 * is more difficult
+		 */
+		quotient.part.hi   = 0;
+		normalized_dividend = dividend;
+		normalized_divisor = divisor;
+
+		/* Normalize the operands (shift until the divisor is < 32 bits) */
+
+		do {
+			ACPI_SHIFT_RIGHT_64 (normalized_divisor.part.hi,
+					 normalized_divisor.part.lo);
+			ACPI_SHIFT_RIGHT_64 (normalized_dividend.part.hi,
+					 normalized_dividend.part.lo);
+
+		} while (normalized_divisor.part.hi != 0);
+
+		/* Partial divide */
+
+		ACPI_DIV_64_BY_32 (normalized_dividend.part.hi,
+				  normalized_dividend.part.lo,
+				  normalized_divisor.part.lo,
+				  quotient.part.lo, partial1);
+
+		/*
+		 * The quotient is always 32 bits, and simply requires adjustment.
+		 * The 64-bit remainder must be generated.
+		 */
+		partial1      = quotient.part.lo * divisor.part.hi;
+		partial2.full = (acpi_integer) quotient.part.lo * divisor.part.lo;
+		partial3.full = (acpi_integer) partial2.part.hi + partial1;
+
+		remainder.part.hi = partial3.part.lo;
+		remainder.part.lo = partial2.part.lo;
+
+		if (partial3.part.hi == 0) {
+			if (partial3.part.lo >= dividend.part.hi) {
+				if (partial3.part.lo == dividend.part.hi) {
+					if (partial2.part.lo > dividend.part.lo) {
+						quotient.part.lo--;
+						remainder.full -= divisor.full;
+					}
+				}
+				else {
+					quotient.part.lo--;
+					remainder.full -= divisor.full;
+				}
+			}
+
+			remainder.full    = remainder.full - dividend.full;
+			remainder.part.hi = (u32) -((s32) remainder.part.hi);
+			remainder.part.lo = (u32) -((s32) remainder.part.lo);
+
+			if (remainder.part.lo) {
+				remainder.part.hi--;
+			}
+		}
+	}
+
+	/* Return only what was requested */
+
+	if (out_quotient) {
+		*out_quotient = quotient.full;
+	}
+	if (out_remainder) {
+		*out_remainder = remainder.full;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+#else
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_short_divide, acpi_ut_divide
+ *
+ * DESCRIPTION: Native versions of the ut_divide functions. Use these if either
+ *              1) The target is a 64-bit platform and therefore 64-bit
+ *                 integer math is supported directly by the machine.
+ *              2) The target is a 32-bit or 16-bit platform, and the
+ *                 double-precision integer math library is available to
+ *                 perform the divide.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_short_divide (
+	acpi_integer                    in_dividend,
+	u32                             divisor,
+	acpi_integer                    *out_quotient,
+	u32                             *out_remainder)
+{
+
+	ACPI_FUNCTION_TRACE ("ut_short_divide");
+
+
+	/* Always check for a zero divisor */
+
+	if (divisor == 0) {
+		ACPI_REPORT_ERROR (("acpi_ut_short_divide: Divide by zero\n"));
+		return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+	}
+
+	/* Return only what was requested */
+
+	if (out_quotient) {
+		*out_quotient = in_dividend / divisor;
+	}
+	if (out_remainder) {
+		*out_remainder = (u32) in_dividend % divisor;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+acpi_status
+acpi_ut_divide (
+	acpi_integer                    in_dividend,
+	acpi_integer                    in_divisor,
+	acpi_integer                    *out_quotient,
+	acpi_integer                    *out_remainder)
+{
+	ACPI_FUNCTION_TRACE ("ut_divide");
+
+
+	/* Always check for a zero divisor */
+
+	if (in_divisor == 0) {
+		ACPI_REPORT_ERROR (("acpi_ut_divide: Divide by zero\n"));
+		return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
+	}
+
+
+	/* Return only what was requested */
+
+	if (out_quotient) {
+		*out_quotient = in_dividend / in_divisor;
+	}
+	if (out_remainder) {
+		*out_remainder = in_dividend % in_divisor;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+#endif
+
+
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
new file mode 100644
index 0000000..f659854
--- /dev/null
+++ b/drivers/acpi/utilities/utmisc.c
@@ -0,0 +1,1516 @@
+/*******************************************************************************
+ *
+ * Module Name: utmisc - common utility procedures
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utmisc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_print_string
+ *
+ * PARAMETERS:  String          - Null terminated ASCII string
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
+ *              sequences.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_print_string (
+	char                            *string,
+	u8                              max_length)
+{
+	u32                             i;
+
+
+	if (!string) {
+		acpi_os_printf ("<\"NULL STRING PTR\">");
+		return;
+	}
+
+	acpi_os_printf ("\"");
+	for (i = 0; string[i] && (i < max_length); i++) {
+		/* Escape sequences */
+
+		switch (string[i]) {
+		case 0x07:
+			acpi_os_printf ("\\a");      /* BELL */
+			break;
+
+		case 0x08:
+			acpi_os_printf ("\\b");     /* BACKSPACE */
+			break;
+
+		case 0x0C:
+			acpi_os_printf ("\\f");     /* FORMFEED */
+			break;
+
+		case 0x0A:
+			acpi_os_printf ("\\n");     /* LINEFEED */
+			break;
+
+		case 0x0D:
+			acpi_os_printf ("\\r");     /* CARRIAGE RETURN*/
+			break;
+
+		case 0x09:
+			acpi_os_printf ("\\t");     /* HORIZONTAL TAB */
+			break;
+
+		case 0x0B:
+			acpi_os_printf ("\\v");     /* VERTICAL TAB */
+			break;
+
+		case '\'':                      /* Single Quote */
+		case '\"':                      /* Double Quote */
+		case '\\':                      /* Backslash */
+			acpi_os_printf ("\\%c", (int) string[i]);
+			break;
+
+		default:
+
+			/* Check for printable character or hex escape */
+
+			if (ACPI_IS_PRINT (string[i]))
+			{
+				/* This is a normal character */
+
+				acpi_os_printf ("%c", (int) string[i]);
+			}
+			else
+			{
+				/* All others will be Hex escapes */
+
+				acpi_os_printf ("\\x%2.2X", (s32) string[i]);
+			}
+			break;
+		}
+	}
+	acpi_os_printf ("\"");
+
+	if (i == max_length && string[i]) {
+		acpi_os_printf ("...");
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_dword_byte_swap
+ *
+ * PARAMETERS:  Value           - Value to be converted
+ *
+ * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
+ *
+ ******************************************************************************/
+
+u32
+acpi_ut_dword_byte_swap (
+	u32                             value)
+{
+	union {
+		u32                         value;
+		u8                          bytes[4];
+	} out;
+
+	union {
+		u32                         value;
+		u8                          bytes[4];
+	} in;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	in.value = value;
+
+	out.bytes[0] = in.bytes[3];
+	out.bytes[1] = in.bytes[2];
+	out.bytes[2] = in.bytes[1];
+	out.bytes[3] = in.bytes[0];
+
+	return (out.value);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_set_integer_width
+ *
+ * PARAMETERS:  Revision            From DSDT header
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set the global integer bit width based upon the revision
+ *              of the DSDT.  For Revision 1 and 0, Integers are 32 bits.
+ *              For Revision 2 and above, Integers are 64 bits.  Yes, this
+ *              makes a difference.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_set_integer_width (
+	u8                              revision)
+{
+
+	if (revision <= 1) {
+		acpi_gbl_integer_bit_width = 32;
+		acpi_gbl_integer_nybble_width = 8;
+		acpi_gbl_integer_byte_width = 4;
+	}
+	else {
+		acpi_gbl_integer_bit_width = 64;
+		acpi_gbl_integer_nybble_width = 16;
+		acpi_gbl_integer_byte_width = 8;
+	}
+}
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_display_init_pathname
+ *
+ * PARAMETERS:  obj_handle          - Handle whose pathname will be displayed
+ *              Path                - Additional path string to be appended.
+ *                                      (NULL if no extra path)
+ *
+ * RETURN:      acpi_status
+ *
+ * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_display_init_pathname (
+	u8                              type,
+	struct acpi_namespace_node      *obj_handle,
+	char                            *path)
+{
+	acpi_status                     status;
+	struct acpi_buffer              buffer;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Only print the path if the appropriate debug level is enabled */
+
+	if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+		return;
+	}
+
+	/* Get the full pathname to the node */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_ns_handle_to_pathname (obj_handle, &buffer);
+	if (ACPI_FAILURE (status)) {
+		return;
+	}
+
+	/* Print what we're doing */
+
+	switch (type) {
+	case ACPI_TYPE_METHOD:
+		acpi_os_printf ("Executing  ");
+		break;
+
+	default:
+		acpi_os_printf ("Initializing ");
+		break;
+	}
+
+	/* Print the object type and pathname */
+
+	acpi_os_printf ("%-12s %s", acpi_ut_get_type_name (type), (char *) buffer.pointer);
+
+	/* Extra path is used to append names like _STA, _INI, etc. */
+
+	if (path) {
+		acpi_os_printf (".%s", path);
+	}
+	acpi_os_printf ("\n");
+
+	ACPI_MEM_FREE (buffer.pointer);
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_valid_acpi_name
+ *
+ * PARAMETERS:  Character           - The character to be examined
+ *
+ * RETURN:      1 if Character may appear in a name, else 0
+ *
+ * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
+ *              1) Upper case alpha
+ *              2) numeric
+ *              3) underscore
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_acpi_name (
+	u32                             name)
+{
+	char                            *name_ptr = (char *) &name;
+	char                            character;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	for (i = 0; i < ACPI_NAME_SIZE; i++) {
+		character = *name_ptr;
+		name_ptr++;
+
+		if (!((character == '_') ||
+			  (character >= 'A' && character <= 'Z') ||
+			  (character >= '0' && character <= '9'))) {
+			return (FALSE);
+		}
+	}
+
+	return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_valid_acpi_character
+ *
+ * PARAMETERS:  Character           - The character to be examined
+ *
+ * RETURN:      1 if Character may appear in a name, else 0
+ *
+ * DESCRIPTION: Check for a printable character
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_acpi_character (
+	char                            character)
+{
+
+	ACPI_FUNCTION_ENTRY ();
+
+	return ((u8)   ((character == '_') ||
+			   (character >= 'A' && character <= 'Z') ||
+			   (character >= '0' && character <= '9')));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_strtoul64
+ *
+ * PARAMETERS:  String          - Null terminated string
+ *              Base            - Radix of the string: 10, 16, or ACPI_ANY_BASE
+ *              ret_integer     - Where the converted integer is returned
+ *
+ * RETURN:      Status and Converted value
+ *
+ * DESCRIPTION: Convert a string into an unsigned value.
+ *              NOTE: Does not support Octal strings, not needed.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_strtoul64 (
+	char                            *string,
+	u32                             base,
+	acpi_integer                    *ret_integer)
+{
+	u32                             this_digit = 0;
+	acpi_integer                    return_value = 0;
+	acpi_integer                    quotient;
+
+
+	ACPI_FUNCTION_TRACE ("ut_stroul64");
+
+
+	if ((!string) || !(*string)) {
+		goto error_exit;
+	}
+
+	switch (base) {
+	case ACPI_ANY_BASE:
+	case 10:
+	case 16:
+		break;
+
+	default:
+		/* Invalid Base */
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Skip over any white space in the buffer */
+
+	while (ACPI_IS_SPACE (*string) || *string == '\t') {
+		string++;
+	}
+
+	/*
+	 * If the input parameter Base is zero, then we need to
+	 * determine if it is decimal or hexadecimal:
+	 */
+	if (base == 0) {
+		if ((*string == '0') &&
+			(ACPI_TOLOWER (*(string + 1)) == 'x')) {
+			base = 16;
+			string += 2;
+		}
+		else {
+			base = 10;
+		}
+	}
+
+	/*
+	 * For hexadecimal base, skip over the leading
+	 * 0 or 0x, if they are present.
+	 */
+	if ((base == 16) &&
+		(*string == '0') &&
+		(ACPI_TOLOWER (*(string + 1)) == 'x')) {
+		string += 2;
+	}
+
+	/* Any string left? */
+
+	if (!(*string)) {
+		goto error_exit;
+	}
+
+	/* Main loop: convert the string to a 64-bit integer */
+
+	while (*string) {
+		if (ACPI_IS_DIGIT (*string)) {
+			/* Convert ASCII 0-9 to Decimal value */
+
+			this_digit = ((u8) *string) - '0';
+		}
+		else {
+			if (base == 10) {
+				/* Digit is out of range */
+
+				goto error_exit;
+			}
+
+			this_digit = (u8) ACPI_TOUPPER (*string);
+			if (ACPI_IS_XDIGIT ((char) this_digit)) {
+				/* Convert ASCII Hex char to value */
+
+				this_digit = this_digit - 'A' + 10;
+			}
+			else {
+				/*
+				 * We allow non-hex chars, just stop now, same as end-of-string.
+				 * See ACPI spec, string-to-integer conversion.
+				 */
+				break;
+			}
+		}
+
+		/* Divide the digit into the correct position */
+
+		(void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit),
+				 base, &quotient, NULL);
+		if (return_value > quotient) {
+			goto error_exit;
+		}
+
+		return_value *= base;
+		return_value += this_digit;
+		string++;
+	}
+
+	/* All done, normal exit */
+
+	*ret_integer = return_value;
+	return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+	/* Base was set/validated above */
+
+	if (base == 10) {
+		return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
+	}
+	else {
+		return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_strupr
+ *
+ * PARAMETERS:  src_string      - The source string to convert to
+ *
+ * RETURN:      src_string
+ *
+ * DESCRIPTION: Convert string to uppercase
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+char *
+acpi_ut_strupr (
+	char                            *src_string)
+{
+	char                            *string;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Walk entire string, uppercasing the letters */
+
+	for (string = src_string; *string; ) {
+		*string = (char) ACPI_TOUPPER (*string);
+		string++;
+	}
+
+	return (src_string);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_mutex_initialize
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create the system mutex objects.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_mutex_initialize (
+	void)
+{
+	u32                             i;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ut_mutex_initialize");
+
+
+	/*
+	 * Create each of the predefined mutex objects
+	 */
+	for (i = 0; i < NUM_MUTEX; i++) {
+		status = acpi_ut_create_mutex (i);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_mutex_terminate
+ *
+ * PARAMETERS:  None.
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete all of the system mutex objects.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_mutex_terminate (
+	void)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE ("ut_mutex_terminate");
+
+
+	/*
+	 * Delete each predefined mutex object
+	 */
+	for (i = 0; i < NUM_MUTEX; i++) {
+		(void) acpi_ut_delete_mutex (i);
+	}
+
+	acpi_os_delete_lock (acpi_gbl_gpe_lock);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_mutex
+ *
+ * PARAMETERS:  mutex_iD        - ID of the mutex to be created
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_create_mutex (
+	acpi_mutex_handle               mutex_id)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id);
+
+
+	if (mutex_id > MAX_MUTEX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	if (!acpi_gbl_mutex_info[mutex_id].mutex) {
+		status = acpi_os_create_semaphore (1, 1,
+				  &acpi_gbl_mutex_info[mutex_id].mutex);
+		acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_mutex_info[mutex_id].use_count = 0;
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_mutex
+ *
+ * PARAMETERS:  mutex_iD        - ID of the mutex to be deleted
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_delete_mutex (
+	acpi_mutex_handle               mutex_id)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id);
+
+
+	if (mutex_id > MAX_MUTEX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex);
+
+	acpi_gbl_mutex_info[mutex_id].mutex = NULL;
+	acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_mutex
+ *
+ * PARAMETERS:  mutex_iD        - ID of the mutex to be acquired
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_acquire_mutex (
+	acpi_mutex_handle               mutex_id)
+{
+	acpi_status                     status;
+	u32                             this_thread_id;
+
+
+	ACPI_FUNCTION_NAME ("ut_acquire_mutex");
+
+
+	if (mutex_id > MAX_MUTEX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	this_thread_id = acpi_os_get_thread_id ();
+
+#ifdef ACPI_MUTEX_DEBUG
+	{
+		u32                             i;
+		/*
+		 * Mutex debug code, for internal debugging only.
+		 *
+		 * Deadlock prevention.  Check if this thread owns any mutexes of value
+		 * greater than or equal to this one.  If so, the thread has violated
+		 * the mutex ordering rule.  This indicates a coding error somewhere in
+		 * the ACPI subsystem code.
+		 */
+		for (i = mutex_id; i < MAX_MUTEX; i++) {
+			if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+				if (i == mutex_id) {
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+							"Mutex [%s] already acquired by this thread [%X]\n",
+							acpi_ut_get_mutex_name (mutex_id), this_thread_id));
+
+					return (AE_ALREADY_ACQUIRED);
+				}
+
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
+						this_thread_id, acpi_ut_get_mutex_name (i),
+						acpi_ut_get_mutex_name (mutex_id)));
+
+				return (AE_ACQUIRE_DEADLOCK);
+			}
+		}
+	}
+#endif
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
+			 "Thread %X attempting to acquire Mutex [%s]\n",
+			 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+
+	status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
+			   1, ACPI_WAIT_FOREVER);
+	if (ACPI_SUCCESS (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
+				 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+
+		acpi_gbl_mutex_info[mutex_id].use_count++;
+		acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
+				 this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+				 acpi_format_exception (status)));
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_release_mutex
+ *
+ * PARAMETERS:  mutex_iD        - ID of the mutex to be released
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release a mutex object.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_release_mutex (
+	acpi_mutex_handle               mutex_id)
+{
+	acpi_status                     status;
+	u32                             i;
+	u32                             this_thread_id;
+
+
+	ACPI_FUNCTION_NAME ("ut_release_mutex");
+
+
+	this_thread_id = acpi_os_get_thread_id ();
+	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
+		"Thread %X releasing Mutex [%s]\n", this_thread_id,
+		acpi_ut_get_mutex_name (mutex_id)));
+
+	if (mutex_id > MAX_MUTEX) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * Mutex must be acquired in order to release it!
+	 */
+	if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Mutex [%s] is not acquired, cannot release\n",
+				acpi_ut_get_mutex_name (mutex_id)));
+
+		return (AE_NOT_ACQUIRED);
+	}
+
+	/*
+	 * Deadlock prevention.  Check if this thread owns any mutexes of value
+	 * greater than this one.  If so, the thread has violated the mutex
+	 * ordering rule.  This indicates a coding error somewhere in
+	 * the ACPI subsystem code.
+	 */
+	for (i = mutex_id; i < MAX_MUTEX; i++) {
+		if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+			if (i == mutex_id) {
+				continue;
+			}
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Invalid release order: owns [%s], releasing [%s]\n",
+					acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
+
+			return (AE_RELEASE_DEADLOCK);
+		}
+	}
+
+	/* Mark unlocked FIRST */
+
+	acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+	status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
+				 this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+				 acpi_format_exception (status)));
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
+				 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_update_state_and_push
+ *
+ * PARAMETERS:  *Object         - Object to be added to the new state
+ *              Action          - Increment/Decrement
+ *              state_list      - List the state will be added to
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_create_update_state_and_push (
+	union acpi_operand_object       *object,
+	u16                             action,
+	union acpi_generic_state        **state_list)
+{
+	union acpi_generic_state         *state;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Ignore null objects; these are expected */
+
+	if (!object) {
+		return (AE_OK);
+	}
+
+	state = acpi_ut_create_update_state (object, action);
+	if (!state) {
+		return (AE_NO_MEMORY);
+	}
+
+	acpi_ut_push_generic_state (state_list, state);
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_pkg_state_and_push
+ *
+ * PARAMETERS:  *Object         - Object to be added to the new state
+ *              Action          - Increment/Decrement
+ *              state_list      - List the state will be added to
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create a new state and push it
+ *
+ ******************************************************************************/
+#ifdef ACPI_FUTURE_USAGE
+acpi_status
+acpi_ut_create_pkg_state_and_push (
+	void                            *internal_object,
+	void                            *external_object,
+	u16                             index,
+	union acpi_generic_state        **state_list)
+{
+	union acpi_generic_state         *state;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	state = acpi_ut_create_pkg_state (internal_object, external_object, index);
+	if (!state) {
+		return (AE_NO_MEMORY);
+	}
+
+	acpi_ut_push_generic_state (state_list, state);
+	return (AE_OK);
+}
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_push_generic_state
+ *
+ * PARAMETERS:  list_head           - Head of the state stack
+ *              State               - State object to push
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Push a state object onto a state stack
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_push_generic_state (
+	union acpi_generic_state        **list_head,
+	union acpi_generic_state        *state)
+{
+	ACPI_FUNCTION_TRACE ("ut_push_generic_state");
+
+
+	/* Push the state object onto the front of the list (stack) */
+
+	state->common.next = *list_head;
+	*list_head = state;
+
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_pop_generic_state
+ *
+ * PARAMETERS:  list_head           - Head of the state stack
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop a state object from a state stack
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_pop_generic_state (
+	union acpi_generic_state        **list_head)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_TRACE ("ut_pop_generic_state");
+
+
+	/* Remove the state object at the head of the list (stack) */
+
+	state = *list_head;
+	if (state) {
+		/* Update the list head */
+
+		*list_head = state->common.next;
+	}
+
+	return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_generic_state
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
+ *              the global state cache;  If none available, create a new one.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_generic_state (void)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE);
+
+	/* Initialize */
+
+	if (state) {
+		state->common.data_type = ACPI_DESC_TYPE_STATE;
+	}
+
+	return (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_thread_state
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Thread State
+ *
+ * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
+ *              to track per-thread info during method execution
+ *
+ ******************************************************************************/
+
+struct acpi_thread_state *
+acpi_ut_create_thread_state (
+	void)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_TRACE ("ut_create_thread_state");
+
+
+	/* Create the generic state object */
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return_PTR (NULL);
+	}
+
+	/* Init fields specific to the update struct */
+
+	state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD;
+	state->thread.thread_id = acpi_os_get_thread_id ();
+
+	return_PTR ((struct acpi_thread_state *) state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_update_state
+ *
+ * PARAMETERS:  Object              - Initial Object to be installed in the
+ *                                    state
+ *              Action              - Update action to be performed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
+ *              to update reference counts and delete complex objects such
+ *              as packages.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_update_state (
+	union acpi_operand_object       *object,
+	u16                             action)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object);
+
+
+	/* Create the generic state object */
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return_PTR (NULL);
+	}
+
+	/* Init fields specific to the update struct */
+
+	state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE;
+	state->update.object = object;
+	state->update.value  = action;
+
+	return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_pkg_state
+ *
+ * PARAMETERS:  Object              - Initial Object to be installed in the
+ *                                    state
+ *              Action              - Update action to be performed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a "Package State"
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_pkg_state (
+	void                            *internal_object,
+	void                            *external_object,
+	u16                             index)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object);
+
+
+	/* Create the generic state object */
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return_PTR (NULL);
+	}
+
+	/* Init fields specific to the update struct */
+
+	state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE;
+	state->pkg.source_object = (union acpi_operand_object *) internal_object;
+	state->pkg.dest_object  = external_object;
+	state->pkg.index        = index;
+	state->pkg.num_packages = 1;
+
+	return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_control_state
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
+ *              to support nested IF/WHILE constructs in the AML.
+ *
+ ******************************************************************************/
+
+union acpi_generic_state *
+acpi_ut_create_control_state (
+	void)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_TRACE ("ut_create_control_state");
+
+
+	/* Create the generic state object */
+
+	state = acpi_ut_create_generic_state ();
+	if (!state) {
+		return_PTR (NULL);
+	}
+
+	/* Init fields specific to the control struct */
+
+	state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL;
+	state->common.state     = ACPI_CONTROL_CONDITIONAL_EXECUTING;
+
+	return_PTR (state);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_generic_state
+ *
+ * PARAMETERS:  State               - The state object to be deleted
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Put a state object back into the global state cache.  The object
+ *              is not actually freed at this time.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_state (
+	union acpi_generic_state        *state)
+{
+	ACPI_FUNCTION_TRACE ("ut_delete_generic_state");
+
+
+	acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state);
+	return_VOID;
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_generic_state_cache
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Purge the global state object cache.  Used during subsystem
+ *              termination.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_generic_state_cache (
+	void)
+{
+	ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache");
+
+
+	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE);
+	return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_walk_package_tree
+ *
+ * PARAMETERS:  obj_desc        - The Package object on which to resolve refs
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk through a package
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_walk_package_tree (
+	union acpi_operand_object       *source_object,
+	void                            *target_object,
+	acpi_pkg_callback               walk_callback,
+	void                            *context)
+{
+	acpi_status                     status = AE_OK;
+	union acpi_generic_state        *state_list = NULL;
+	union acpi_generic_state        *state;
+	u32                             this_index;
+	union acpi_operand_object       *this_source_obj;
+
+
+	ACPI_FUNCTION_TRACE ("ut_walk_package_tree");
+
+
+	state = acpi_ut_create_pkg_state (source_object, target_object, 0);
+	if (!state) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	while (state) {
+		/* Get one element of the package */
+
+		this_index    = state->pkg.index;
+		this_source_obj = (union acpi_operand_object *)
+				  state->pkg.source_object->package.elements[this_index];
+
+		/*
+		 * Check for:
+		 * 1) An uninitialized package element.  It is completely
+		 *    legal to declare a package and leave it uninitialized
+		 * 2) Not an internal object - can be a namespace node instead
+		 * 3) Any type other than a package.  Packages are handled in else
+		 *    case below.
+		 */
+		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)) {
+			status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
+					 state, context);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			state->pkg.index++;
+			while (state->pkg.index >= state->pkg.source_object->package.count) {
+				/*
+				 * We've handled all of the objects at this level,  This means
+				 * that we have just completed a package.  That package may
+				 * have contained one or more packages itself.
+				 *
+				 * Delete this state and pop the previous state (package).
+				 */
+				acpi_ut_delete_generic_state (state);
+				state = acpi_ut_pop_generic_state (&state_list);
+
+				/* Finished when there are no more states */
+
+				if (!state) {
+					/*
+					 * We have handled all of the objects in the top level
+					 * package just add the length of the package objects
+					 * and exit
+					 */
+					return_ACPI_STATUS (AE_OK);
+				}
+
+				/*
+				 * Go back up a level and move the index past the just
+				 * completed package object.
+				 */
+				state->pkg.index++;
+			}
+		}
+		else {
+			/* This is a subobject of type package */
+
+			status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
+					  state, context);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			/*
+			 * Push the current state and create a new one
+			 * The callback above returned a new target package object.
+			 */
+			acpi_ut_push_generic_state (&state_list, state);
+			state = acpi_ut_create_pkg_state (this_source_obj,
+					   state->pkg.this_target_obj, 0);
+			if (!state) {
+				return_ACPI_STATUS (AE_NO_MEMORY);
+			}
+		}
+	}
+
+	/* We should never get here */
+
+	return_ACPI_STATUS (AE_AML_INTERNAL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_generate_checksum
+ *
+ * PARAMETERS:  Buffer          - Buffer to be scanned
+ *              Length          - number of bytes to examine
+ *
+ * RETURN:      checksum
+ *
+ * DESCRIPTION: Generate a checksum on a raw buffer
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_generate_checksum (
+	u8                              *buffer,
+	u32                             length)
+{
+	u32                             i;
+	signed char                     sum = 0;
+
+
+	for (i = 0; i < length; i++) {
+		sum = (signed char) (sum + buffer[i]);
+	}
+
+	return ((u8) (0 - sum));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_resource_end_tag
+ *
+ * PARAMETERS:  obj_desc        - The resource template buffer object
+ *
+ * RETURN:      Pointer to the end tag
+ *
+ * DESCRIPTION: Find the END_TAG resource descriptor in a resource template
+ *
+ ******************************************************************************/
+
+
+u8 *
+acpi_ut_get_resource_end_tag (
+	union acpi_operand_object       *obj_desc)
+{
+	u8                              buffer_byte;
+	u8                              *buffer;
+	u8                              *end_buffer;
+
+
+	buffer    = obj_desc->buffer.pointer;
+	end_buffer = buffer + obj_desc->buffer.length;
+
+	while (buffer < end_buffer) {
+		buffer_byte = *buffer;
+		if (buffer_byte & ACPI_RDESC_TYPE_MASK) {
+			/* Large Descriptor - Length is next 2 bytes */
+
+			buffer += ((*(buffer+1) | (*(buffer+2) << 8)) + 3);
+		}
+		else {
+			/* Small Descriptor.  End Tag will be found here */
+
+			if ((buffer_byte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) {
+				/* Found the end tag descriptor, all done. */
+
+				return (buffer);
+			}
+
+			/* Length is in the header */
+
+			buffer += ((buffer_byte & 0x07) + 1);
+		}
+	}
+
+	/* End tag not found */
+
+	return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_report_error
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_report_error (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id)
+{
+
+
+	acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_report_warning
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print warning message
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_report_warning (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id)
+{
+
+	acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_report_info
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print information message
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_report_info (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id)
+{
+
+	acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number);
+}
+
+
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
new file mode 100644
index 0000000..9ee40a4
--- /dev/null
+++ b/drivers/acpi/utilities/utobject.c
@@ -0,0 +1,671 @@
+/******************************************************************************
+ *
+ * Module Name: utobject - ACPI object create/delete/size/cache routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/amlcode.h>
+
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utobject")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_internal_object_dbg
+ *
+ * PARAMETERS:  module_name         - Source file name of caller
+ *              line_number         - Line number of caller
+ *              component_id        - Component type of caller
+ *              Type                - ACPI Type of the new object
+ *
+ * RETURN:      Object              - The new object.  Null on failure
+ *
+ * DESCRIPTION: Create and initialize a new internal object.
+ *
+ * NOTE:        We always allocate the worst-case object descriptor because
+ *              these objects are cached, and we want them to be
+ *              one-size-satisifies-any-request.  This in itself may not be
+ *              the most memory efficient, but the efficiency of the object
+ *              cache should more than make up for this!
+ *
+ ******************************************************************************/
+
+union acpi_operand_object    *
+acpi_ut_create_internal_object_dbg (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id,
+	acpi_object_type                type)
+{
+	union acpi_operand_object       *object;
+	union acpi_operand_object       *second_object;
+
+
+	ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg", acpi_ut_get_type_name (type));
+
+
+	/* Allocate the raw object descriptor */
+
+	object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id);
+	if (!object) {
+		return_PTR (NULL);
+	}
+
+	switch (type) {
+	case ACPI_TYPE_REGION:
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		/* These types require a secondary object */
+
+		second_object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id);
+		if (!second_object) {
+			acpi_ut_delete_object_desc (object);
+			return_PTR (NULL);
+		}
+
+		second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
+		second_object->common.reference_count = 1;
+
+		/* Link the second object to the first */
+
+		object->common.next_object = second_object;
+		break;
+
+	default:
+		/* All others have no secondary object */
+		break;
+	}
+
+	/* Save the object type in the object descriptor */
+
+	object->common.type = (u8) type;
+
+	/* Init the reference count */
+
+	object->common.reference_count = 1;
+
+	/* Any per-type initialization should go here */
+
+	return_PTR (object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_buffer_object
+ *
+ * PARAMETERS:  buffer_size            - Size of buffer to be created
+ *
+ * RETURN:      Pointer to a new Buffer object
+ *
+ * DESCRIPTION: Create a fully initialized buffer object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ut_create_buffer_object (
+	acpi_size                       buffer_size)
+{
+	union acpi_operand_object       *buffer_desc;
+	u8                              *buffer = NULL;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);
+
+
+	/* Create a new Buffer object */
+
+	buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
+	if (!buffer_desc) {
+		return_PTR (NULL);
+	}
+
+	/* Create an actual buffer only if size > 0 */
+
+	if (buffer_size > 0) {
+		/* Allocate the actual buffer */
+
+		buffer = ACPI_MEM_CALLOCATE (buffer_size);
+		if (!buffer) {
+			ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
+				(u32) buffer_size));
+			acpi_ut_remove_reference (buffer_desc);
+			return_PTR (NULL);
+		}
+	}
+
+	/* Complete buffer object initialization */
+
+	buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
+	buffer_desc->buffer.pointer = buffer;
+	buffer_desc->buffer.length = (u32) buffer_size;
+
+	/* Return the new buffer descriptor */
+
+	return_PTR (buffer_desc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_string_object
+ *
+ * PARAMETERS:  string_size            - Size of string to be created.  Does not
+ *                                       include NULL terminator, this is added
+ *                                       automatically.
+ *
+ * RETURN:      Pointer to a new String object
+ *
+ * DESCRIPTION: Create a fully initialized string object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ut_create_string_object (
+	acpi_size                       string_size)
+{
+	union acpi_operand_object       *string_desc;
+	char                            *string;
+
+
+	ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size);
+
+
+	/* Create a new String object */
+
+	string_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+	if (!string_desc) {
+		return_PTR (NULL);
+	}
+
+	/*
+	 * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
+	 * NOTE: Zero-length strings are NULL terminated
+	 */
+	string = ACPI_MEM_CALLOCATE (string_size + 1);
+	if (!string) {
+		ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n",
+			(u32) string_size));
+		acpi_ut_remove_reference (string_desc);
+		return_PTR (NULL);
+	}
+
+	/* Complete string object initialization */
+
+	string_desc->string.pointer = string;
+	string_desc->string.length = (u32) string_size;
+
+	/* Return the new string descriptor */
+
+	return_PTR (string_desc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_valid_internal_object
+ *
+ * PARAMETERS:  Object              - Object to be validated
+ *
+ * RETURN:      Validate a pointer to be an union acpi_operand_object
+ *
+ ******************************************************************************/
+
+u8
+acpi_ut_valid_internal_object (
+	void                            *object)
+{
+
+	ACPI_FUNCTION_NAME ("ut_valid_internal_object");
+
+
+	/* Check for a null pointer */
+
+	if (!object) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+		return (FALSE);
+	}
+
+	/* Check the descriptor type field */
+
+	switch (ACPI_GET_DESCRIPTOR_TYPE (object)) {
+	case ACPI_DESC_TYPE_OPERAND:
+
+		/* The object appears to be a valid union acpi_operand_object    */
+
+		return (TRUE);
+
+	default:
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+				"%p is not not an ACPI operand obj [%s]\n",
+				object, acpi_ut_get_descriptor_name (object)));
+		break;
+	}
+
+	return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_allocate_object_desc_dbg
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              component_id        - Caller's component ID (for error output)
+ *
+ * RETURN:      Pointer to newly allocated object descriptor.  Null on error
+ *
+ * DESCRIPTION: Allocate a new object descriptor.  Gracefully handle
+ *              error conditions.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ut_allocate_object_desc_dbg (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id)
+{
+	union acpi_operand_object       *object;
+
+
+	ACPI_FUNCTION_TRACE ("ut_allocate_object_desc_dbg");
+
+
+	object = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_OPERAND);
+	if (!object) {
+		_ACPI_REPORT_ERROR (module_name, line_number, component_id,
+				  ("Could not allocate an object descriptor\n"));
+
+		return_PTR (NULL);
+	}
+
+	/* Mark the descriptor type */
+
+	ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
+			object, (u32) sizeof (union acpi_operand_object)));
+
+	return_PTR (object);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_object_desc
+ *
+ * PARAMETERS:  Object          - An Acpi internal object to be deleted
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_object_desc (
+	union acpi_operand_object       *object)
+{
+	ACPI_FUNCTION_TRACE_PTR ("ut_delete_object_desc", object);
+
+
+	/* Object must be an union acpi_operand_object    */
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"%p is not an ACPI Operand object [%s]\n", object,
+				acpi_ut_get_descriptor_name (object)));
+		return_VOID;
+	}
+
+	acpi_ut_release_to_cache (ACPI_MEM_LIST_OPERAND, object);
+
+	return_VOID;
+}
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_delete_object_cache
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Purge the global state object cache.  Used during subsystem
+ *              termination.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_delete_object_cache (
+	void)
+{
+	ACPI_FUNCTION_TRACE ("ut_delete_object_cache");
+
+
+	acpi_ut_delete_generic_cache (ACPI_MEM_LIST_OPERAND);
+	return_VOID;
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_simple_object_size
+ *
+ * PARAMETERS:  *internal_object    - Pointer to the object we are examining
+ *              *obj_length         - Where the length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ *              contain a simple object for return to an external user.
+ *
+ *              The length includes the object structure plus any additional
+ *              needed space.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_simple_object_size (
+	union acpi_operand_object       *internal_object,
+	acpi_size                       *obj_length)
+{
+	acpi_size                       length;
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_get_simple_object_size", internal_object);
+
+
+	/* Handle a null object (Could be a uninitialized package element -- which is legal) */
+
+	if (!internal_object) {
+		*obj_length = 0;
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Start with the length of the Acpi object */
+
+	length = sizeof (union acpi_object);
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_NAMED) {
+		/* Object is a named object (reference), just return the length */
+
+		*obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length);
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * The final length depends on the object type
+	 * Strings and Buffers are packed right up against the parent object and
+	 * must be accessed bytewise or there may be alignment problems on
+	 * certain processors
+	 */
+	switch (ACPI_GET_OBJECT_TYPE (internal_object)) {
+	case ACPI_TYPE_STRING:
+
+		length += (acpi_size) internal_object->string.length + 1;
+		break;
+
+
+	case ACPI_TYPE_BUFFER:
+
+		length += (acpi_size) internal_object->buffer.length;
+		break;
+
+
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_PROCESSOR:
+	case ACPI_TYPE_POWER:
+
+		/*
+		 * No extra data for these types
+		 */
+		break;
+
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		switch (internal_object->reference.opcode) {
+		case AML_INT_NAMEPATH_OP:
+
+			/*
+			 * Get the actual length of the full pathname to this object.
+			 * The reference will be converted to the pathname to the object
+			 */
+			length += ACPI_ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node));
+			break;
+
+		default:
+
+			/*
+			 * No other reference opcodes are supported.
+			 * Notably, Locals and Args are not supported, but this may be
+			 * required eventually.
+			 */
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Unsupported Reference opcode=%X in object %p\n",
+				internal_object->reference.opcode, internal_object));
+			status = AE_TYPE;
+			break;
+		}
+		break;
+
+
+	default:
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n",
+			ACPI_GET_OBJECT_TYPE (internal_object), internal_object));
+		status = AE_TYPE;
+		break;
+	}
+
+	/*
+	 * Account for the space required by the object rounded up to the next
+	 * multiple of the machine word size.  This keeps each object aligned
+	 * on a machine word boundary. (preventing alignment faults on some
+	 * machines.)
+	 */
+	*obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD (length);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_element_length
+ *
+ * PARAMETERS:  acpi_pkg_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get the length of one package element.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_element_length (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context)
+{
+	acpi_status                     status = AE_OK;
+	struct acpi_pkg_info            *info = (struct acpi_pkg_info *) context;
+	acpi_size                       object_space;
+
+
+	switch (object_type) {
+	case ACPI_COPY_TYPE_SIMPLE:
+
+		/*
+		 * Simple object - just get the size (Null object/entry is handled
+		 * here also) and sum it into the running package length
+		 */
+		status = acpi_ut_get_simple_object_size (source_object, &object_space);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+
+		info->length += object_space;
+		break;
+
+
+	case ACPI_COPY_TYPE_PACKAGE:
+
+		/* Package object - nothing much to do here, let the walk handle it */
+
+		info->num_packages++;
+		state->pkg.this_target_obj = NULL;
+		break;
+
+
+	default:
+
+		/* No other types allowed */
+
+		return (AE_BAD_PARAMETER);
+	}
+
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_package_object_size
+ *
+ * PARAMETERS:  *internal_object    - Pointer to the object we are examining
+ *              *obj_length         - Where the length is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ *              contain a package object for return to an external user.
+ *
+ *              This is moderately complex since a package contains other
+ *              objects including packages.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_package_object_size (
+	union acpi_operand_object       *internal_object,
+	acpi_size                       *obj_length)
+{
+	acpi_status                     status;
+	struct acpi_pkg_info            info;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ut_get_package_object_size", internal_object);
+
+
+	info.length      = 0;
+	info.object_space = 0;
+	info.num_packages = 1;
+
+	status = acpi_ut_walk_package_tree (internal_object, NULL,
+			 acpi_ut_get_element_length, &info);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * We have handled all of the objects in all levels of the package.
+	 * just add the length of the package objects themselves.
+	 * Round up to the next machine word.
+	 */
+	info.length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object)) *
+			  (acpi_size) info.num_packages;
+
+	/* Return the total package length */
+
+	*obj_length = info.length;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_object_size
+ *
+ * PARAMETERS:  *internal_object    - Pointer to the object we are examining
+ *              *obj_length         - Where the length will be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to determine the space required to
+ *              contain an object for return to an API user.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_object_size(
+	union acpi_operand_object       *internal_object,
+	acpi_size                       *obj_length)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	if ((ACPI_GET_DESCRIPTOR_TYPE (internal_object) == ACPI_DESC_TYPE_OPERAND) &&
+		(ACPI_GET_OBJECT_TYPE (internal_object) == ACPI_TYPE_PACKAGE)) {
+		status = acpi_ut_get_package_object_size (internal_object, obj_length);
+	}
+	else {
+		status = acpi_ut_get_simple_object_size (internal_object, obj_length);
+	}
+
+	return (status);
+}
+
+
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
new file mode 100644
index 0000000..97a91f3
--- /dev/null
+++ b/drivers/acpi/utilities/utxface.c
@@ -0,0 +1,525 @@
+/******************************************************************************
+ *
+ * Module Name: utxface - External interfaces for "global" ACPI functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * 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 <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acdebug.h>
+
+#define _COMPONENT          ACPI_UTILITIES
+	 ACPI_MODULE_NAME    ("utxface")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_subsystem
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initializes all global variables.  This is the first function
+ *              called, so any early initialization belongs here.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_initialize_subsystem (
+	void)
+{
+	acpi_status                     status;
+
+	ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem");
+
+
+	ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ());
+
+
+	/* Initialize all globals used by the subsystem */
+
+	acpi_ut_init_globals ();
+
+	/* Initialize the OS-Dependent layer */
+
+	status = acpi_os_initialize ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("OSD failed to initialize, %s\n",
+			acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	/* Create the default mutex objects */
+
+	status = acpi_ut_mutex_initialize ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Global mutex creation failure, %s\n",
+			acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Initialize the namespace manager and
+	 * the root of the namespace tree
+	 */
+
+	status = acpi_ns_root_initialize ();
+	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n",
+			acpi_format_exception (status)));
+		return_ACPI_STATUS (status);
+	}
+
+
+	/* If configured, initialize the AML debugger */
+
+	ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ());
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_enable_subsystem
+ *
+ * PARAMETERS:  Flags           - Init/enable Options
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes the subsystem initialization including hardware.
+ *              Puts system into ACPI mode if it isn't already.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enable_subsystem (
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enable_subsystem");
+
+
+	/*
+	 * We must initialize the hardware before we can enable ACPI.
+	 * The values from the FADT are validated here.
+	 */
+	if (!(flags & ACPI_NO_HARDWARE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n"));
+
+		status = acpi_hw_initialize ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Enable ACPI mode */
+
+	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
+
+		acpi_gbl_original_mode = acpi_hw_get_mode();
+
+		status = acpi_enable ();
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "acpi_enable failed.\n"));
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Install the default op_region handlers. These are installed unless
+	 * other handlers have already been installed via the
+	 * install_address_space_handler interface.
+	 */
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+
+		status = acpi_ev_install_region_handlers ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Initialize ACPI Event handling (Fixed and General Purpose)
+	 *
+	 * NOTE: We must have the hardware AND events initialized before we can execute
+	 * ANY control methods SAFELY.  Any control method can require ACPI hardware
+	 * support, so the hardware MUST be initialized before execution!
+	 */
+	if (!(flags & ACPI_NO_EVENT_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n"));
+
+		status = acpi_ev_initialize_events ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/* Install the SCI handler and Global Lock handler */
+
+	if (!(flags & ACPI_NO_HANDLER_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n"));
+
+		status = acpi_ev_install_xrupt_handlers ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_objects
+ *
+ * PARAMETERS:  Flags           - Init/enable Options
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes namespace initialization by initializing device
+ *              objects and executing AML code for Regions, buffers, etc.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_initialize_objects (
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_initialize_objects");
+
+
+	/*
+	 * Run all _REG methods
+	 *
+	 * NOTE: Any objects accessed
+	 * by the _REG methods will be automatically initialized, even if they
+	 * contain executable AML (see call to acpi_ns_initialize_objects below).
+	 */
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n"));
+
+		status = acpi_ev_initialize_op_regions ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Initialize the objects that remain uninitialized.  This
+	 * runs the executable AML that may be part of the declaration of these
+	 * objects: operation_regions, buffer_fields, Buffers, and Packages.
+	 */
+	if (!(flags & ACPI_NO_OBJECT_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n"));
+
+		status = acpi_ns_initialize_objects ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Initialize all device objects in the namespace
+	 * This runs the _STA and _INI methods.
+	 */
+	if (!(flags & ACPI_NO_DEVICE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+
+		status = acpi_ns_initialize_devices ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Empty the caches (delete the cached objects) on the assumption that
+	 * the table load filled them up more than they will be at runtime --
+	 * thus wasting non-paged memory.
+	 */
+	status = acpi_purge_cached_objects ();
+
+	acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_terminate
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Shutdown the ACPI subsystem.  Release all resources.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_terminate (void)
+{
+	acpi_status                 status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_terminate");
+
+
+	/* Terminate the AML Debugger if present */
+
+	ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
+
+	/* Shutdown and free all resources */
+
+	acpi_ut_subsystem_shutdown ();
+
+
+	/* Free the mutex objects */
+
+	acpi_ut_mutex_terminate ();
+
+
+#ifdef ACPI_DEBUGGER
+
+	/* Shut down the debugger */
+
+	acpi_db_terminate ();
+#endif
+
+	/* Now we can shutdown the OS-dependent layer */
+
+	status = acpi_os_terminate ();
+	return_ACPI_STATUS (status);
+}
+
+
+#ifdef ACPI_FUTURE_USAGE
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_subsystem_status
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status of the ACPI subsystem
+ *
+ * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
+ *              before making any other calls, to ensure the subsystem initial-
+ *              ized successfully.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_subsystem_status (void)
+{
+	if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
+		return (AE_OK);
+	}
+	else {
+		return (AE_ERROR);
+	}
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_system_info
+ *
+ * PARAMETERS:  out_buffer      - a pointer to a buffer to receive the
+ *                                resources for the device
+ *              buffer_length   - the number of bytes available in the buffer
+ *
+ * RETURN:      Status          - the status of the call
+ *
+ * DESCRIPTION: This function is called to get information about the current
+ *              state of the ACPI subsystem.  It will return system information
+ *              in the out_buffer.
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the value of out_buffer is undefined.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_system_info (
+	struct acpi_buffer              *out_buffer)
+{
+	struct acpi_system_info         *info_ptr;
+	u32                             i;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_get_system_info");
+
+
+	/* Parameter validation */
+
+	status = acpi_ut_validate_buffer (out_buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (out_buffer, sizeof (struct acpi_system_info));
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Populate the return buffer
+	 */
+	info_ptr = (struct acpi_system_info *) out_buffer->pointer;
+
+	info_ptr->acpi_ca_version   = ACPI_CA_VERSION;
+
+	/* System flags (ACPI capabilities) */
+
+	info_ptr->flags             = ACPI_SYS_MODE_ACPI;
+
+	/* Timer resolution - 24 or 32 bits  */
+
+	if (!acpi_gbl_FADT) {
+		info_ptr->timer_resolution = 0;
+	}
+	else if (acpi_gbl_FADT->tmr_val_ext == 0) {
+		info_ptr->timer_resolution = 24;
+	}
+	else {
+		info_ptr->timer_resolution = 32;
+	}
+
+	/* Clear the reserved fields */
+
+	info_ptr->reserved1         = 0;
+	info_ptr->reserved2         = 0;
+
+	/* Current debug levels */
+
+	info_ptr->debug_layer       = acpi_dbg_layer;
+	info_ptr->debug_level       = acpi_dbg_level;
+
+	/* Current status of the ACPI tables, per table type */
+
+	info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES;
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+		info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+EXPORT_SYMBOL(acpi_get_system_info);
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_install_initialization_handler
+ *
+ * PARAMETERS:  Handler             - Callback procedure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install an initialization handler
+ *
+ * TBD: When a second function is added, must save the Function also.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_install_initialization_handler (
+	acpi_init_handler               handler,
+	u32                             function)
+{
+
+	if (!handler) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (acpi_gbl_init_handler) {
+		return (AE_ALREADY_EXISTS);
+	}
+
+	acpi_gbl_init_handler = handler;
+	return AE_OK;
+}
+
+#endif  /*  ACPI_FUTURE_USAGE  */
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_purge_cached_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Empty all caches (delete the cached objects)
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_purge_cached_objects (void)
+{
+	ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects");
+
+
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+	acpi_ut_delete_generic_state_cache ();
+	acpi_ut_delete_object_cache ();
+	acpi_ds_delete_walk_state_cache ();
+	acpi_ps_delete_parse_cache ();
+#endif
+
+	return_ACPI_STATUS (AE_OK);
+}
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
new file mode 100644
index 0000000..1ce2047
--- /dev/null
+++ b/drivers/acpi/utils.c
@@ -0,0 +1,423 @@
+/*
+ *  acpi_utils.c - ACPI Utility Functions ($Revision: 10 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define _COMPONENT		ACPI_BUS_COMPONENT
+ACPI_MODULE_NAME		("acpi_utils")
+
+
+/* --------------------------------------------------------------------------
+                            Object Evaluation Helpers
+   -------------------------------------------------------------------------- */
+
+#ifdef ACPI_DEBUG_OUTPUT
+#define acpi_util_eval_error(h,p,s) {\
+	char prefix[80] = {'\0'};\
+	struct acpi_buffer buffer = {sizeof(prefix), prefix};\
+	acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\
+		(char *) prefix, p, acpi_format_exception(s))); }
+#else
+#define acpi_util_eval_error(h,p,s)
+#endif
+
+
+acpi_status
+acpi_extract_package (
+	union acpi_object	*package,
+	struct acpi_buffer	*format,
+	struct acpi_buffer	*buffer)
+{
+	u32			size_required = 0;
+	u32			tail_offset = 0;
+	char			*format_string = NULL;
+	u32			format_count = 0;
+	u32			i = 0;
+	u8			*head = NULL;
+	u8			*tail = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_extract_package");
+
+	if (!package || (package->type != ACPI_TYPE_PACKAGE) || (package->package.count < 1)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'package' argument\n"));
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	if (!format || !format->pointer || (format->length < 1)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'format' argument\n"));
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	if (!buffer) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'buffer' argument\n"));
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	format_count = (format->length/sizeof(char)) - 1;
+	if (format_count > package->package.count) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count));
+		return_ACPI_STATUS(AE_BAD_DATA);
+	}
+
+	format_string = (char*)format->pointer;
+
+	/*
+	 * Calculate size_required.
+	 */
+	for (i=0; i<format_count; i++) {
+
+		union acpi_object *element = &(package->package.elements[i]);
+
+		if (!element) {
+			return_ACPI_STATUS(AE_BAD_DATA);
+		}
+
+		switch (element->type) {
+
+		case ACPI_TYPE_INTEGER:
+			switch (format_string[i]) {
+			case 'N':
+				size_required += sizeof(acpi_integer);
+				tail_offset += sizeof(acpi_integer);
+				break;
+			case 'S':
+				size_required += sizeof(char*) + sizeof(acpi_integer) + sizeof(char);
+				tail_offset += sizeof(char*);
+				break;
+			default:
+				ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d]: got number, expecing [%c].\n", i, format_string[i]));
+				return_ACPI_STATUS(AE_BAD_DATA);
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_STRING:
+		case ACPI_TYPE_BUFFER:
+			switch (format_string[i]) {
+			case 'S':
+				size_required += sizeof(char*) + (element->string.length * sizeof(char)) + sizeof(char);
+				tail_offset += sizeof(char*);
+				break;
+			case 'B':
+				size_required += sizeof(u8*) + (element->buffer.length * sizeof(u8));
+				tail_offset += sizeof(u8*);
+				break;
+			default:
+				ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d] got string/buffer, expecing [%c].\n", i, format_string[i]));
+				return_ACPI_STATUS(AE_BAD_DATA);
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+		default:
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%d\n", i));
+			/* TBD: handle nested packages... */
+			return_ACPI_STATUS(AE_SUPPORT);
+			break;
+		}
+	}
+
+	/*
+	 * Validate output buffer.
+	 */
+	if (buffer->length < size_required) {
+		buffer->length = size_required;
+		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
+	}
+	else if (buffer->length != size_required || !buffer->pointer) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	head = buffer->pointer;
+	tail = buffer->pointer + tail_offset;
+
+	/*
+	 * Extract package data.
+	 */
+	for (i=0; i<format_count; i++) {
+
+		u8 **pointer = NULL;
+		union acpi_object *element = &(package->package.elements[i]);
+
+		if (!element) {
+			return_ACPI_STATUS(AE_BAD_DATA);
+		}
+
+		switch (element->type) {
+
+		case ACPI_TYPE_INTEGER:
+			switch (format_string[i]) {
+			case 'N':
+				*((acpi_integer*)head) = element->integer.value;
+				head += sizeof(acpi_integer);
+				break;
+			case 'S':
+				pointer = (u8**)head;
+				*pointer = tail;
+				*((acpi_integer*)tail) = element->integer.value;
+				head += sizeof(acpi_integer*);
+				tail += sizeof(acpi_integer);
+				/* NULL terminate string */
+				*tail = (char)0;
+				tail += sizeof(char);
+				break;
+			default:
+				/* Should never get here */
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_STRING:
+		case ACPI_TYPE_BUFFER:
+			switch (format_string[i]) {
+			case 'S':
+				pointer = (u8**)head;
+				*pointer = tail;
+				memcpy(tail, element->string.pointer, element->string.length);
+				head += sizeof(char*);
+				tail += element->string.length * sizeof(char);
+				/* NULL terminate string */
+				*tail = (char)0;
+				tail += sizeof(char);
+				break;
+			case 'B':
+				pointer = (u8**)head;
+				*pointer = tail;
+				memcpy(tail, element->buffer.pointer, element->buffer.length);
+				head += sizeof(u8*);
+				tail += element->buffer.length * sizeof(u8);
+				break;
+			default:
+				/* Should never get here */
+				break;
+			}
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+			/* TBD: handle nested packages... */
+		default:
+			/* Should never get here */
+			break;
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+EXPORT_SYMBOL(acpi_extract_package);
+
+
+acpi_status
+acpi_evaluate_integer (
+	acpi_handle		handle,
+	acpi_string		pathname,
+	struct acpi_object_list	*arguments,
+	unsigned long		*data)
+{
+	acpi_status             status = AE_OK;
+	union acpi_object	*element;
+	struct acpi_buffer	buffer = {0,NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_evaluate_integer");
+
+	if (!data)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	element = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if(!element)
+		return_ACPI_STATUS(AE_NO_MEMORY);
+
+	memset(element, 0, sizeof(union acpi_object));
+	buffer.length = sizeof(union acpi_object);
+	buffer.pointer = element;
+	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_util_eval_error(handle, pathname, status);
+		return_ACPI_STATUS(status);
+	}
+
+	if (element->type != ACPI_TYPE_INTEGER) {
+		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
+		return_ACPI_STATUS(AE_BAD_DATA);
+	}
+
+	*data = element->integer.value;
+	kfree(element);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data));
+
+	return_ACPI_STATUS(AE_OK);
+}
+EXPORT_SYMBOL(acpi_evaluate_integer);
+
+
+#if 0
+acpi_status
+acpi_evaluate_string (
+	acpi_handle		handle,
+	acpi_string		pathname,
+	acpi_object_list	*arguments,
+	acpi_string		*data)
+{
+	acpi_status             status = AE_OK;
+	acpi_object             *element = NULL;
+	acpi_buffer		buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+
+	ACPI_FUNCTION_TRACE("acpi_evaluate_string");
+
+	if (!data)
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_util_eval_error(handle, pathname, status);
+		return_ACPI_STATUS(status);
+	}
+
+	element = (acpi_object *) buffer.pointer;
+
+	if ((element->type != ACPI_TYPE_STRING) 
+		|| (element->type != ACPI_TYPE_BUFFER)
+		|| !element->string.length) {
+		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
+		return_ACPI_STATUS(AE_BAD_DATA);
+	}
+
+	*data = kmalloc(element->string.length + 1, GFP_KERNEL);
+	if (!data) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n"));
+		return_VALUE(-ENOMEM);
+	}
+	memset(*data, 0, element->string.length + 1);
+
+	memcpy(*data, element->string.pointer, element->string.length);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data));
+
+	acpi_os_free(buffer.pointer);
+
+	return_ACPI_STATUS(AE_OK);
+}
+#endif
+
+
+acpi_status
+acpi_evaluate_reference (
+	acpi_handle		handle,
+	acpi_string		pathname,
+	struct acpi_object_list	*arguments,
+	struct acpi_handle_list	*list)
+{
+	acpi_status		status = AE_OK;
+	union acpi_object	*package = NULL;
+	union acpi_object	*element = NULL;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	u32			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_evaluate_reference");
+
+	if (!list) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	/* Evaluate object. */
+
+	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
+	if (ACPI_FAILURE(status))
+		goto end;
+
+	package = (union acpi_object *) buffer.pointer;
+
+	if ((buffer.length == 0) || !package) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"No return object (len %X ptr %p)\n", 
+			(unsigned)buffer.length, package));
+		status = AE_BAD_DATA;
+		acpi_util_eval_error(handle, pathname, status);
+		goto end;
+	}
+	if (package->type != ACPI_TYPE_PACKAGE) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Expecting a [Package], found type %X\n", 
+			package->type));
+		status = AE_BAD_DATA;
+		acpi_util_eval_error(handle, pathname, status);
+		goto end;
+	}
+	if (!package->package.count) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"[Package] has zero elements (%p)\n", 
+			package));
+		status = AE_BAD_DATA;
+		acpi_util_eval_error(handle, pathname, status);
+		goto end;
+	}
+
+	if (package->package.count > ACPI_MAX_HANDLES) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+	list->count = package->package.count;
+
+	/* Extract package data. */
+
+	for (i = 0; i < list->count; i++) {
+
+		element = &(package->package.elements[i]);
+
+		if (element->type != ACPI_TYPE_ANY) {
+			status = AE_BAD_DATA;
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				"Expecting a [Reference] package element, found type %X\n",
+				element->type));
+			acpi_util_eval_error(handle, pathname, status);
+			break;
+		}
+
+		/* Get the  acpi_handle. */
+
+		list->handles[i] = element->reference.handle;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n",
+			list->handles[i]));
+	}
+
+end:
+	if (ACPI_FAILURE(status)) {
+		list->count = 0;
+		//kfree(list->handles);
+	}
+
+	acpi_os_free(buffer.pointer);
+
+	return_ACPI_STATUS(status);
+}
+EXPORT_SYMBOL(acpi_evaluate_reference);
+
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
new file mode 100644
index 0000000..71fa101
--- /dev/null
+++ b/drivers/acpi/video.c
@@ -0,0 +1,1989 @@
+/*
+ *  video.c - ACPI Video Driver ($Revision:$)
+ *
+ *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
+ *  Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_VIDEO_COMPONENT		0x08000000
+#define ACPI_VIDEO_CLASS		"video"
+#define ACPI_VIDEO_DRIVER_NAME		"ACPI Video Driver"
+#define ACPI_VIDEO_BUS_NAME		"Video Bus"
+#define ACPI_VIDEO_DEVICE_NAME		"Video Device"
+#define ACPI_VIDEO_NOTIFY_SWITCH	0x80
+#define ACPI_VIDEO_NOTIFY_PROBE		0x81
+#define ACPI_VIDEO_NOTIFY_CYCLE		0x82
+#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT	0x83
+#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT	0x84
+
+#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS	0x82
+#define	ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS	0x83
+#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS	0x84
+#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS	0x85
+#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF		0x86
+
+
+#define ACPI_VIDEO_HEAD_INVALID		(~0u - 1)
+#define ACPI_VIDEO_HEAD_END		(~0u)
+
+
+#define _COMPONENT		ACPI_VIDEO_COMPONENT
+ACPI_MODULE_NAME		("acpi_video")
+
+MODULE_AUTHOR("Bruno Ducrot");
+MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static int acpi_video_bus_add (struct acpi_device *device);
+static int acpi_video_bus_remove (struct acpi_device *device, int type);
+static int acpi_video_bus_match (struct acpi_device *device, struct acpi_driver *driver);
+
+static struct acpi_driver acpi_video_bus = {
+	.name = ACPI_VIDEO_DRIVER_NAME,
+	.class = ACPI_VIDEO_CLASS,
+	.ops = {
+		.add = acpi_video_bus_add,
+		.remove = acpi_video_bus_remove,
+		.match = acpi_video_bus_match,
+	},
+};
+
+struct acpi_video_bus_flags {
+	u8	multihead:1;	/* can switch video heads */
+	u8	rom:1;		/* can retrieve a video rom */
+	u8	post:1;		/* can configure the head to */
+	u8	reserved:5;
+};
+
+struct acpi_video_bus_cap {
+	u8	_DOS:1; /*Enable/Disable output switching*/
+	u8	_DOD:1; /*Enumerate all devices attached to display adapter*/
+	u8	_ROM:1; /*Get ROM Data*/
+	u8	_GPD:1; /*Get POST Device*/
+	u8	_SPD:1; /*Set POST Device*/
+	u8	_VPO:1; /*Video POST Options*/
+	u8	reserved:2;
+};
+
+struct acpi_video_device_attrib{
+	u32	display_index:4; /* A zero-based instance of the Display*/
+	u32	display_port_attachment:4; /*This field differenates displays type*/
+	u32	display_type:4;	/*Describe the specific type in use*/
+	u32	vendor_specific:4; /*Chipset Vendor Specifi*/ 
+	u32	bios_can_detect:1; /*BIOS can detect the device*/
+	u32	depend_on_vga:1; /*Non-VGA output device whose power is related to 
+				   the VGA device.*/
+	u32	pipe_id:3; /*For VGA multiple-head devices.*/
+	u32	reserved:10; /*Must be 0*/
+	u32	device_id_scheme:1; /*Device ID Scheme*/
+};
+
+struct acpi_video_enumerated_device {
+	union {
+		u32 int_val;
+		struct acpi_video_device_attrib	attrib;
+	} value;
+	struct acpi_video_device *bind_info;
+};
+
+struct acpi_video_bus {
+	acpi_handle	handle;
+	u8	dos_setting;
+	struct acpi_video_enumerated_device *attached_array;
+	u8			attached_count;
+	struct acpi_video_bus_cap	cap;
+	struct acpi_video_bus_flags flags;
+	struct semaphore	sem;
+	struct list_head	video_device_list;
+	struct proc_dir_entry 	*dir;
+};
+
+struct acpi_video_device_flags {
+	u8	crt:1;
+	u8	lcd:1;
+	u8	tvout:1;
+	u8	bios:1;
+	u8	unknown:1;
+	u8	reserved:3;
+};
+
+struct acpi_video_device_cap {
+	u8	_ADR:1;	/*Return the unique ID */
+	u8	_BCL:1; /*Query list of brightness control levels supported*/
+	u8	_BCM:1; /*Set the brightness level*/
+	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*/
+	u8	_reserved:1;
+};
+
+struct acpi_video_device_brightness {
+	int	curr;
+	int	count;
+	int	*levels;
+};
+
+struct acpi_video_device {
+	acpi_handle		handle;
+	unsigned long		device_id;
+	struct acpi_video_device_flags	flags;
+	struct acpi_video_device_cap	cap;
+	struct list_head	entry;
+	struct acpi_video_bus	*video;
+	struct acpi_device	*dev;
+	struct acpi_video_device_brightness *brightness;
+};
+
+
+/* bus */
+static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_bus_info_fops = {
+	.open		= acpi_video_bus_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_bus_ROM_fops = {
+	.open		= acpi_video_bus_ROM_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_bus_POST_info_fops = {
+	.open		= acpi_video_bus_POST_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_bus_POST_fops = {
+	.open		= acpi_video_bus_POST_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_bus_DOS_fops = {
+	.open		= acpi_video_bus_DOS_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+/* device */
+static int acpi_video_device_info_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_device_info_fops = {
+	.open		= acpi_video_device_info_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_video_device_state_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_device_state_fops = {
+	.open		= acpi_video_device_state_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_device_brightness_fops = {
+	.open		= acpi_video_device_brightness_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_video_device_EDID_fops = {
+	.open		= acpi_video_device_EDID_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static char	device_decode[][30] = {
+	"motherboard VGA device",
+	"PCI VGA device",
+	"AGP VGA device",
+	"UNKNOWN",
+};
+
+static void acpi_video_device_notify ( acpi_handle handle, u32 event, void *data);
+static void acpi_video_device_rebind( struct acpi_video_bus *video);
+static void acpi_video_device_bind( struct acpi_video_bus *video, struct acpi_video_device *device);
+static int acpi_video_device_enumerate(struct acpi_video_bus *video);
+static int acpi_video_switch_output( struct acpi_video_bus *video, int	event);
+static int acpi_video_get_next_level( struct acpi_video_device *device, u32 level_current,u32 event);
+static void acpi_video_switch_brightness ( struct acpi_video_device *device, int event);
+
+
+/* --------------------------------------------------------------------------
+                               Video Management
+   -------------------------------------------------------------------------- */
+
+/* device */
+
+static int
+acpi_video_device_query (
+	struct acpi_video_device	*device,
+	unsigned long			*state)
+{
+	int			status;
+	ACPI_FUNCTION_TRACE("acpi_video_device_query");
+	status = acpi_evaluate_integer(device->handle, "_DGS", NULL, state);
+
+	return_VALUE(status);
+}
+
+static int
+acpi_video_device_get_state (
+	struct acpi_video_device	*device,
+	unsigned long 		*state)
+{
+	int			status;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_get_state");
+
+	status = acpi_evaluate_integer(device->handle, "_DCS", NULL, state);
+
+	return_VALUE(status);
+}
+
+static int
+acpi_video_device_set_state (
+	struct acpi_video_device	*device,
+	int			state)
+{
+	int			status;
+	union acpi_object	arg0 = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	args = {1, &arg0};
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_set_state");
+
+	arg0.integer.value = state;
+	status = acpi_evaluate_integer(device->handle, "_DSS", &args, NULL);
+
+	return_VALUE(status);
+}
+
+static int
+acpi_video_device_lcd_query_levels (
+	struct acpi_video_device	*device,
+	union acpi_object		**levels)
+{
+	int			status;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*obj;
+
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_lcd_query_levels");
+
+	*levels = NULL;
+
+	status = acpi_evaluate_object(device->handle, "_BCL", NULL, &buffer);
+	if (!ACPI_SUCCESS(status))
+		return_VALUE(status);
+	obj = (union acpi_object *) buffer.pointer;
+	if (!obj && (obj->type != ACPI_TYPE_PACKAGE)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _BCL data\n"));
+		status = -EFAULT;
+		goto err;
+	}
+
+	*levels = obj;
+
+	return_VALUE(0);
+
+err:
+	if (buffer.pointer)
+		kfree(buffer.pointer);
+
+	return_VALUE(status);
+}
+
+static int
+acpi_video_device_lcd_set_level (
+	struct acpi_video_device	*device,
+	int				level)
+{
+	int			status;
+	union acpi_object	arg0 = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	args = {1, &arg0};
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_lcd_set_level");
+
+	arg0.integer.value = level;
+	status = acpi_evaluate_object(device->handle, "_BCM", &args, NULL);
+
+	printk(KERN_DEBUG "set_level status: %x\n", status);
+	return_VALUE(status);
+}
+
+static int
+acpi_video_device_lcd_get_level_current (
+	struct acpi_video_device	*device,
+	unsigned long 	*level)
+{
+	int			status;
+	ACPI_FUNCTION_TRACE("acpi_video_device_lcd_get_level_current");
+
+	status = acpi_evaluate_integer(device->handle, "_BQC", NULL, level);
+
+	return_VALUE(status);
+}
+
+static int
+acpi_video_device_EDID (
+	struct acpi_video_device	*device,
+	union acpi_object		**edid,
+	ssize_t				length)
+{
+	int			status;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*obj;
+	union acpi_object	arg0 = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	args = {1, &arg0};
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_get_EDID");
+
+	*edid = NULL;
+
+	if (!device)
+		return_VALUE(-ENODEV);
+	if (length == 128)
+		arg0.integer.value = 1;
+	else if (length == 256)
+		arg0.integer.value = 2;
+	else
+		return_VALUE(-EINVAL);
+
+	status = acpi_evaluate_object(device->handle, "_DDC", &args, &buffer);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	obj = (union acpi_object *) buffer.pointer;
+
+	if (obj && obj->type == ACPI_TYPE_BUFFER)
+		*edid = obj;
+	else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DDC data\n"));
+		status = -EFAULT;
+		kfree(obj);
+	}
+
+	return_VALUE(status);
+}
+
+
+/* bus */
+
+static int
+acpi_video_bus_set_POST (
+	struct acpi_video_bus	*video,
+	unsigned long		option)
+{
+	int			status;
+	unsigned long		tmp;
+	union acpi_object	arg0 = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	args = {1, &arg0};
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_set_POST");
+
+	arg0.integer.value = option;
+
+	status = acpi_evaluate_integer(video->handle, "_SPD", &args, &tmp);
+	if (ACPI_SUCCESS(status))
+		status = tmp ? (-EINVAL):(AE_OK);
+
+	return_VALUE(status);
+}
+
+static int
+acpi_video_bus_get_POST (
+	struct acpi_video_bus	*video,
+	unsigned long		*id)
+{
+	int status;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_get_POST");
+
+	status = acpi_evaluate_integer(video->handle, "_GPD", NULL, id);
+
+	return_VALUE(status);
+}
+
+static int
+acpi_video_bus_POST_options (
+	struct acpi_video_bus	*video,
+	unsigned long		*options)
+{
+	int			status;
+	ACPI_FUNCTION_TRACE("acpi_video_bus_POST_options");
+
+	status = acpi_evaluate_integer(video->handle, "_VPO", NULL, options);
+	*options &= 3;
+
+	return_VALUE(status);
+}
+
+/*
+ *  Arg:
+ *  	video		: video bus device pointer
+ *	bios_flag	: 
+ *		0.	The system BIOS should NOT automatically switch(toggle)
+ *			the active display output.
+ *		1.	The system BIOS should automatically switch (toggle) the
+ *			active display output. No swich event.
+ *		2.	The _DGS value should be locked.
+ *		3.	The system BIOS should not automatically switch (toggle) the
+ *			active display output, but instead generate the display switch
+ *			event notify code.
+ *	lcd_flag	:
+ *		0.	The system BIOS should automatically control the brightness level
+ *			of the LCD, when the power changes from AC to DC
+ *		1. 	The system BIOS should NOT automatically control the brightness 
+ *			level of the LCD, when the power changes from AC to DC.
+ * Return Value:
+ * 		-1	wrong arg.
+ */
+
+static int
+acpi_video_bus_DOS(
+	struct acpi_video_bus	*video,
+	int			bios_flag,
+	int			lcd_flag)
+{
+	acpi_integer		status = 0;
+	union acpi_object	arg0 = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	args = {1, &arg0};
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_DOS");
+
+	if (bios_flag < 0 || bios_flag >3 || lcd_flag < 0 || lcd_flag > 1){
+		status = -1;
+		goto Failed;
+	}
+	arg0.integer.value = (lcd_flag << 2) | bios_flag;
+	video->dos_setting = arg0.integer.value;
+	acpi_evaluate_object(video->handle, "_DOS", &args, NULL);
+
+Failed:
+	return_VALUE(status);
+}
+
+/*
+ *  Arg:	
+ *  	device	: video output device (LCD, CRT, ..)
+ *
+ *  Return Value:
+ *  	None
+ *
+ *  Find out all required AML method defined under the output
+ *  device.
+ */
+
+static void
+acpi_video_device_find_cap (struct acpi_video_device *device)
+{
+	acpi_integer		status;
+	acpi_handle h_dummy1;
+	int i;
+	union acpi_object *obj = NULL;
+	struct acpi_video_device_brightness *br = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_find_cap");
+
+	memset( &device->cap, 0, 4);
+
+    	if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_ADR", &h_dummy1))) {
+		device->cap._ADR = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCL", &h_dummy1))) {
+		device->cap._BCL= 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCM", &h_dummy1))) {
+		device->cap._BCM= 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DDC", &h_dummy1))) {
+		device->cap._DDC= 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DCS", &h_dummy1))) {
+		device->cap._DCS = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DGS", &h_dummy1))) {
+		device->cap._DGS = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(device->handle, "_DSS", &h_dummy1))) {
+		device->cap._DSS = 1;
+	}
+
+	status = acpi_video_device_lcd_query_levels(device, &obj);
+
+	if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) {
+		int count = 0;
+		union acpi_object *o;
+		
+		br = kmalloc(sizeof &br, GFP_KERNEL);
+		if (!br) {
+			printk(KERN_ERR "can't allocate memory\n");
+		} else {
+			memset(br, 0, sizeof &br);
+			br->levels = kmalloc(obj->package.count * sizeof &br->levels, GFP_KERNEL);
+			if (!br->levels)
+				goto out;
+
+			for (i = 0; i < obj->package.count; i++) {
+				o = (union acpi_object *) &obj->package.elements[i];
+				if (o->type != ACPI_TYPE_INTEGER) {
+					ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
+					continue;
+				}
+				br->levels[count] = (u32) o->integer.value;
+				count++;
+			}
+out:
+			if (count < 2) {
+				if (br->levels)
+					kfree(br->levels);
+				kfree(br);
+			} else {
+				br->count = count;
+				device->brightness = br;
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+			}
+		}
+	}
+
+	if (obj)
+		kfree(obj);
+
+	return_VOID;
+}
+
+/*
+ *  Arg:	
+ *  	device	: video output device (VGA)
+ *
+ *  Return Value:
+ *  	None
+ *
+ *  Find out all required AML method defined under the video bus device.
+ */
+
+static void 
+acpi_video_bus_find_cap (struct acpi_video_bus *video)
+{
+	acpi_handle	h_dummy1;
+
+	memset(&video->cap ,0, 4);
+    	if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOS", &h_dummy1))) {
+		video->cap._DOS = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOD", &h_dummy1))) {
+		video->cap._DOD = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_ROM", &h_dummy1))) {
+		video->cap._ROM = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_GPD", &h_dummy1))) {
+		video->cap._GPD = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_SPD", &h_dummy1))) {
+		video->cap._SPD = 1;
+	}
+    	if( ACPI_SUCCESS(acpi_get_handle(video->handle, "_VPO", &h_dummy1))) {
+		video->cap._VPO = 1;
+	}
+}
+
+/*
+ * Check whether the video bus device has required AML method to
+ * support the desired features
+ */
+
+static int
+acpi_video_bus_check (
+	struct acpi_video_bus	*video)
+{
+	acpi_status		status = -ENOENT;
+
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_check");
+
+	if (!video)
+		return_VALUE(-EINVAL);
+
+	/* Since there is no HID, CID and so on for VGA driver, we have
+	 * to check well known required nodes.
+	 */
+
+	/* Does this device able to support video switching ? */
+	if(video->cap._DOS){
+		video->flags.multihead = 1;
+		status = 0;
+	}
+
+	/* Does this device able to retrieve a retrieve a video ROM ? */
+	if(video->cap._ROM){
+		video->flags.rom = 1;
+		status = 0;
+	}
+
+	/* Does this device able to configure which video device to POST ? */
+	if(video->cap._GPD && video->cap._SPD && video->cap._VPO){
+		video->flags.post = 1;
+		status = 0;
+	}
+
+	return_VALUE(status);
+}
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry	*acpi_video_dir;
+
+/* video devices */
+
+static int
+acpi_video_device_info_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_device	*dev = (struct acpi_video_device *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_info_seq_show");
+
+	if (!dev)
+		goto end;
+
+	seq_printf(seq, "device_id:    0x%04x\n", (u32) dev->device_id);
+	seq_printf(seq, "type:         ");
+	if (dev->flags.crt)
+		seq_printf(seq, "CRT\n");
+	else if (dev->flags.lcd)
+		seq_printf(seq, "LCD\n");
+	else if (dev->flags.tvout)
+		seq_printf(seq, "TVOUT\n");
+	else
+		seq_printf(seq, "UNKNOWN\n");
+
+	seq_printf(seq,"known by bios: %s\n",
+		   dev->flags.bios ? "yes":"no");
+
+end:
+	return_VALUE(0);
+}
+
+static int
+acpi_video_device_info_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_device_info_seq_show,
+			   PDE(inode)->data);
+}
+
+static int  
+acpi_video_device_state_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	int			status;
+	struct acpi_video_device	*dev = (struct acpi_video_device *) seq->private;
+	unsigned long	state;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_state_seq_show");
+
+	if (!dev)
+		goto end;
+
+	status = acpi_video_device_get_state(dev, &state);
+	seq_printf(seq, "state:     ");
+	if (ACPI_SUCCESS(status))
+		seq_printf(seq, "0x%02lx\n", state);
+	else
+		seq_printf(seq, "<not supported>\n");
+
+	status = acpi_video_device_query(dev, &state);
+	seq_printf(seq, "query:     ");
+	if (ACPI_SUCCESS(status))
+		seq_printf(seq, "0x%02lx\n", state);
+	else
+		seq_printf(seq, "<not supported>\n");
+
+end:
+	return_VALUE(0);
+}
+
+static int
+acpi_video_device_state_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_device_state_seq_show,
+			   PDE(inode)->data);
+}
+
+static ssize_t
+acpi_video_device_write_state (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*data)
+{
+	int			status;
+	struct seq_file		*m = (struct seq_file *) file->private_data;
+	struct acpi_video_device	*dev = (struct acpi_video_device *) m->private;
+	char			str[12] = {0};
+	u32			state = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_write_state");
+
+	if (!dev || count + 1 > sizeof str)
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(str, buffer, count))
+		return_VALUE(-EFAULT);
+
+	str[count] = 0;
+	state = simple_strtoul(str, NULL, 0);
+	state &= ((1ul<<31) | (1ul<<30) | (1ul<<0));
+
+	status = acpi_video_device_set_state(dev, state);
+
+	if (status)
+		return_VALUE(-EFAULT);
+
+	return_VALUE(count);
+}
+
+static int
+acpi_video_device_brightness_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_device	*dev = (struct acpi_video_device *) seq->private;
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_brightness_seq_show");
+
+	if (!dev || !dev->brightness) {
+		seq_printf(seq, "<not supported>\n");
+		return_VALUE(0);
+	}
+
+	seq_printf(seq, "levels: ");
+	for (i = 0; i < dev->brightness->count; i++)
+		seq_printf(seq, " %d", dev->brightness->levels[i]);
+	seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_video_device_brightness_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_device_brightness_seq_show,
+			   PDE(inode)->data);
+}
+
+static ssize_t
+acpi_video_device_write_brightness (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*data)
+{
+	struct seq_file		*m = (struct seq_file *) file->private_data;
+	struct acpi_video_device	*dev = (struct acpi_video_device *) m->private;
+	char			str[4] = {0};
+	unsigned int		level = 0;
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_write_brightness");
+
+	if (!dev || count + 1 > sizeof str)
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(str, buffer, count))
+		return_VALUE(-EFAULT);
+
+	str[count] = 0;
+	level = simple_strtoul(str, NULL, 0);
+	
+	if (level > 100)
+		return_VALUE(-EFAULT);
+
+	/* validate though the list of available levels */
+	for (i = 0; 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;
+			break;
+		}
+
+	return_VALUE(count);
+}
+
+static int
+acpi_video_device_EDID_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_device	*dev = (struct acpi_video_device *) seq->private;
+	int			status;
+	int			i;
+	union acpi_object	*edid = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_EDID_seq_show");
+
+	if (!dev)
+		goto out;
+
+	status = acpi_video_device_EDID (dev, &edid, 128);
+	if (ACPI_FAILURE(status)) {
+		status = acpi_video_device_EDID (dev, &edid, 256);
+	}
+
+	if (ACPI_FAILURE(status)) {
+		goto out;
+	}
+
+	if (edid && edid->type == ACPI_TYPE_BUFFER) {
+		for (i = 0; i < edid->buffer.length; i++)
+			seq_putc(seq, edid->buffer.pointer[i]);
+	}
+
+out:
+	if (!edid)
+		seq_printf(seq, "<not supported>\n");
+	else
+		kfree(edid);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_video_device_EDID_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_device_EDID_seq_show,
+			   PDE(inode)->data);
+}
+
+
+static int
+acpi_video_device_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_video_device *vid_dev;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_add_fs");
+
+	if (!device)
+		return_VALUE(-ENODEV);
+
+	vid_dev = (struct acpi_video_device *) acpi_driver_data(device);
+	if (!vid_dev)
+		return_VALUE(-ENODEV);
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+				vid_dev->video->dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
+	}
+
+	/* 'info' [R] */
+	entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create 'info' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_device_info_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'state' [R/W] */
+	entry = create_proc_entry("state", S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create 'state' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_device_state_fops;
+		entry->proc_fops->write = acpi_video_device_write_state;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'brightness' [R/W] */
+	entry = create_proc_entry("brightness", S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create 'brightness' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_device_brightness_fops;
+		entry->proc_fops->write = acpi_video_device_write_brightness;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'EDID' [R] */
+	entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create 'brightness' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_device_EDID_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+static int
+acpi_video_device_remove_fs (
+	struct acpi_device	*device)
+{
+	struct acpi_video_device *vid_dev;
+	ACPI_FUNCTION_TRACE("acpi_video_device_remove_fs");
+
+	vid_dev = (struct acpi_video_device *) acpi_driver_data(device);
+	if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
+		return_VALUE(-ENODEV);
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry("info", acpi_device_dir(device));
+		remove_proc_entry("state", acpi_device_dir(device));
+		remove_proc_entry("brightness", acpi_device_dir(device));
+		remove_proc_entry("EDID", acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device),
+				 vid_dev->video->dir);
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+
+/* video bus */
+static int
+acpi_video_bus_info_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_info_seq_show");
+
+	if (!video)
+		goto end;
+
+	seq_printf(seq, "Switching heads:              %s\n",
+			video->flags.multihead ? "yes":"no");
+	seq_printf(seq, "Video ROM:                    %s\n",
+			video->flags.rom ? "yes":"no");
+	seq_printf(seq, "Device to be POSTed on boot:  %s\n",
+			video->flags.post ? "yes":"no");
+
+end:
+	return_VALUE(0);
+}
+
+static int
+acpi_video_bus_info_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_bus_info_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_video_bus_ROM_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_ROM_seq_show");
+
+	if (!video)
+		goto end;
+
+	printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__);
+	seq_printf(seq, "<TODO>\n");
+
+end:
+	return_VALUE(0);
+}
+
+static int
+acpi_video_bus_ROM_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_video_bus_POST_info_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) seq->private;
+	unsigned long		options;
+	int			status;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_POST_info_seq_show");
+
+	if (!video)
+		goto end;
+
+	status = acpi_video_bus_POST_options(video, &options);
+	if (ACPI_SUCCESS(status)) {
+		if (!(options & 1)) {
+			printk(KERN_WARNING PREFIX "The motherboard VGA device is not listed as a possible POST device.\n");
+			printk(KERN_WARNING PREFIX "This indicate a BIOS bug.  Please contact the manufacturer.\n");
+		}
+		printk("%lx\n", options);
+		seq_printf(seq, "can POST: <intgrated video>");
+		if (options & 2)
+			seq_printf(seq, " <PCI video>");
+		if (options & 4)
+			seq_printf(seq, " <AGP video>");
+		seq_putc(seq, '\n');
+	} else
+		seq_printf(seq, "<not supported>\n");
+end:
+	return_VALUE(0);
+}
+
+static int
+acpi_video_bus_POST_info_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_bus_POST_info_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_video_bus_POST_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) seq->private;
+	int			status;
+	unsigned long		id;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_POST_seq_show");
+
+	if (!video)
+		goto end;
+
+	status = acpi_video_bus_get_POST (video, &id);
+	if (!ACPI_SUCCESS(status)) {
+		seq_printf(seq, "<not supported>\n");
+		goto end;
+	}
+	seq_printf(seq, "device posted is <%s>\n",  device_decode[id & 3]);
+
+end:
+	return_VALUE(0);
+}
+
+static int
+acpi_video_bus_DOS_seq_show (
+	struct seq_file		*seq,
+	void			*offset)
+{
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_DOS_seq_show");
+
+	seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting );
+
+	return_VALUE(0);
+}
+
+static int
+acpi_video_bus_POST_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_bus_POST_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_video_bus_DOS_open_fs (
+	struct inode		*inode,
+	struct file		*file)
+{
+	return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
+}
+
+static ssize_t
+acpi_video_bus_write_POST (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*data)
+{
+	int			status;
+	struct seq_file		*m = (struct seq_file *) file->private_data;
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) m->private;
+	char			str[12] = {0};
+	unsigned long		opt, options;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_write_POST");
+
+
+	if (!video || count + 1 > sizeof str)
+		return_VALUE(-EINVAL);
+
+	status = acpi_video_bus_POST_options(video, &options);
+	if (!ACPI_SUCCESS(status))
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(str, buffer, count))
+		return_VALUE(-EFAULT);
+
+	str[count] = 0;
+	opt = strtoul(str, NULL, 0);
+	if (opt > 3)
+		return_VALUE(-EFAULT);
+
+	/* just in case an OEM 'forget' the motherboard... */
+	options |= 1;
+
+	if (options & (1ul << opt)) {
+		status = acpi_video_bus_set_POST (video, opt);
+		if (!ACPI_SUCCESS(status))
+			return_VALUE(-EFAULT);
+
+	}
+
+
+	return_VALUE(count);
+}
+
+static ssize_t
+acpi_video_bus_write_DOS (
+	struct file		*file,
+	const char		__user *buffer,
+	size_t			count,
+	loff_t			*data)
+{
+	int			status;
+	struct seq_file		*m = (struct seq_file *) file->private_data;
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) m->private;
+	char			str[12] = {0};
+	unsigned long		opt;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_write_DOS");
+
+
+	if (!video || count + 1 > sizeof str)
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(str, buffer, count))
+		return_VALUE(-EFAULT);
+
+	str[count] = 0;
+	opt = strtoul(str, NULL, 0);
+	if (opt > 7)
+		return_VALUE(-EFAULT);
+
+	status = acpi_video_bus_DOS (video, opt & 0x3, (opt & 0x4)>>2);
+
+	if (!ACPI_SUCCESS(status))
+		return_VALUE(-EFAULT);
+
+	return_VALUE(count);
+}
+
+static int
+acpi_video_bus_add_fs (
+	struct acpi_device	*device)
+{
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_video_bus	*video;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_add_fs");
+
+	video = (struct acpi_video_bus *) acpi_driver_data(device);
+
+	if (!acpi_device_dir(device)) {
+		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+				acpi_video_dir);
+		if (!acpi_device_dir(device))
+			return_VALUE(-ENODEV);
+		video->dir = acpi_device_dir(device);
+		acpi_device_dir(device)->owner = THIS_MODULE;
+	}
+
+	/* 'info' [R] */
+	entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'info' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_bus_info_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'ROM' [R] */
+	entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'ROM' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_bus_ROM_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'POST_info' [R] */
+	entry = create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'POST_info' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_bus_POST_info_fops;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'POST' [R/W] */
+	entry = create_proc_entry("POST", S_IFREG|S_IRUGO|S_IRUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'POST' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_bus_POST_fops;
+		entry->proc_fops->write = acpi_video_bus_write_POST;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	/* 'DOS' [R/W] */
+	entry = create_proc_entry("DOS", S_IFREG|S_IRUGO|S_IRUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create 'DOS' fs entry\n"));
+	else {
+		entry->proc_fops = &acpi_video_bus_DOS_fops;
+		entry->proc_fops->write = acpi_video_bus_write_DOS;
+		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
+	}
+
+	return_VALUE(0);
+}
+
+static int
+acpi_video_bus_remove_fs (
+	struct acpi_device	*device)
+{
+	struct acpi_video_bus	*video;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_remove_fs");
+
+	video = (struct acpi_video_bus *) acpi_driver_data(device);
+
+	if (acpi_device_dir(device)) {
+		remove_proc_entry("info", acpi_device_dir(device));
+		remove_proc_entry("ROM", acpi_device_dir(device));
+		remove_proc_entry("POST_info", acpi_device_dir(device));
+		remove_proc_entry("POST", acpi_device_dir(device));
+		remove_proc_entry("DOS", acpi_device_dir(device));
+		remove_proc_entry(acpi_device_bid(device),
+				acpi_video_dir); 
+		acpi_device_dir(device) = NULL;
+	}
+
+	return_VALUE(0);
+}
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+/* device interface */
+
+static int
+acpi_video_bus_get_one_device (
+	struct acpi_device	*device,
+	struct acpi_video_bus	*video)
+{
+	unsigned long		device_id;
+	int			status, result;
+	struct acpi_video_device	*data;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_get_one_device");
+
+	if (!device || !video)
+		return_VALUE(-EINVAL);
+
+	status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
+	if (ACPI_SUCCESS(status)) {
+
+		data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
+		if (!data)
+			return_VALUE(-ENOMEM);
+
+		memset(data, 0, sizeof(struct acpi_video_device));
+
+		data->handle = device->handle;
+		strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
+		strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
+		acpi_driver_data(device) = data;
+
+		data->device_id = device_id;
+		data->video = video;
+		data->dev = device;
+
+		switch (device_id & 0xffff) {
+		case 0x0100:
+			data->flags.crt = 1;
+			break;
+		case 0x0400:
+			data->flags.lcd = 1;
+			break;
+		case 0x0200:
+			data->flags.tvout = 1;
+			break;
+		default:
+			data->flags.unknown = 1;
+			break;
+		}
+		
+		acpi_video_device_bind(video, data);
+		acpi_video_device_find_cap(data);
+
+		status = acpi_install_notify_handler(data->handle,
+			ACPI_DEVICE_NOTIFY, acpi_video_device_notify, data);
+		if (ACPI_FAILURE(status)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error installing notify handler\n"));
+			result = -ENODEV;
+			goto end;
+		}
+
+		down(&video->sem);
+		list_add_tail(&data->entry, &video->video_device_list);
+		up(&video->sem);
+
+		acpi_video_device_add_fs(device);
+
+		return_VALUE(0);
+	}
+
+end:
+	return_VALUE(-ENOENT);
+}
+
+/*
+ *  Arg:
+ *  	video	: video bus device 
+ *
+ *  Return:
+ *  	none
+ *  
+ *  Enumerate the video device list of the video bus, 
+ *  bind the ids with the corresponding video devices
+ *  under the video bus.
+ */  
+
+static void
+acpi_video_device_rebind( struct acpi_video_bus *video)
+{
+	struct list_head * node, * next;
+	list_for_each_safe(node, next, &video->video_device_list) {
+		struct acpi_video_device * dev = container_of(node, struct acpi_video_device, entry);
+		acpi_video_device_bind( video, dev);
+	}
+}
+
+/*
+ *  Arg:
+ *  	video	: video bus device 
+ *  	device	: video output device under the video 
+ *  		bus
+ *
+ *  Return:
+ *  	none
+ *  
+ *  Bind the ids with the corresponding video devices
+ *  under the video bus.
+ */  
+
+static void
+acpi_video_device_bind( struct acpi_video_bus *video,
+			struct acpi_video_device *device)
+{
+	int	i;
+	ACPI_FUNCTION_TRACE("acpi_video_device_bind");
+
+#define IDS_VAL(i) video->attached_array[i].value.int_val
+#define IDS_BIND(i) video->attached_array[i].bind_info
+	
+	for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID && 
+		i < video->attached_count; i++) {
+		if (device->device_id == (IDS_VAL(i)& 0xffff)) {
+			IDS_BIND(i) = device;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
+		}
+	}
+#undef IDS_VAL
+#undef IDS_BIND
+}
+
+/*
+ *  Arg:
+ *  	video	: video bus device 
+ *
+ *  Return:
+ *  	< 0	: error
+ *  
+ *  Call _DOD to enumerate all devices attached to display adapter
+ *
+ */  
+
+static int acpi_video_device_enumerate(struct acpi_video_bus *video)
+{
+	int			status;
+	int			count;
+	int			i;
+	struct acpi_video_enumerated_device *active_device_list;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*dod = NULL;
+	union acpi_object	*obj;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_enumerate");
+
+	status = acpi_evaluate_object(video->handle, "_DOD", NULL, &buffer);
+	if (!ACPI_SUCCESS(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _DOD\n"));
+		return_VALUE(status);
+	}
+
+	dod = (union acpi_object *) buffer.pointer;
+	if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DOD data\n"));
+		status = -EFAULT;
+		goto out;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
+		dod->package.count));
+
+	active_device_list= kmalloc(
+ 		(1+dod->package.count)*sizeof(struct acpi_video_enumerated_device),
+	       	GFP_KERNEL);
+
+	if (!active_device_list) {
+		status = -ENOMEM;
+		goto out;
+	}
+
+	count = 0;
+	for (i = 0; i < dod->package.count; i++) {
+		obj = (union acpi_object *) &dod->package.elements[i];
+
+		if (obj->type != ACPI_TYPE_INTEGER) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _DOD data\n"));
+			active_device_list[i].value.int_val = ACPI_VIDEO_HEAD_INVALID;
+		}
+		active_device_list[i].value.int_val = obj->integer.value;
+		active_device_list[i].bind_info = NULL;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, (int) obj->integer.value));
+		count++;
+	}
+	active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
+
+	if(video->attached_array)
+		kfree(video->attached_array);
+	
+	video->attached_array = active_device_list;
+	video->attached_count = count;
+out:
+	acpi_os_free(buffer.pointer);
+	return_VALUE(status);
+}
+
+/*
+ *  Arg:
+ *  	video	: video bus device 
+ *  	event	: Nontify Event
+ *
+ *  Return:
+ *  	< 0	: error
+ *  
+ *	1. Find out the current active output device.
+ *	2. Identify the next output device to switch
+ *	3. call _DSS to do actual switch.
+ */  
+
+static int 
+acpi_video_switch_output(
+	struct acpi_video_bus *video, 
+	int	event)
+{
+	struct list_head * node, * next;
+	struct acpi_video_device *dev=NULL;
+       	struct acpi_video_device *dev_next=NULL;
+	struct acpi_video_device *dev_prev=NULL;
+	unsigned long state;
+	int status = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_video_switch_output");
+
+	list_for_each_safe(node, next, &video->video_device_list) {
+		struct acpi_video_device * dev = container_of(node, struct acpi_video_device, entry);
+		status = acpi_video_device_get_state(dev, &state);
+		if (state & 0x2){
+			dev_next = container_of(node->next, struct acpi_video_device, entry);
+			dev_prev = container_of(node->prev, struct acpi_video_device, entry);
+			goto out;
+		}
+	}
+	dev_next = container_of(node->next, struct acpi_video_device, entry);
+	dev_prev = container_of(node->prev, struct acpi_video_device, entry);
+out:	
+	switch (event) {
+	case ACPI_VIDEO_NOTIFY_CYCLE:
+	case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
+		acpi_video_device_set_state(dev, 0);
+		acpi_video_device_set_state(dev_next, 0x80000001);
+		break;
+	case ACPI_VIDEO_NOTIFY_PREV_OUTPUT:
+		acpi_video_device_set_state(dev, 0);
+		acpi_video_device_set_state(dev_prev, 0x80000001);
+	default:
+		break;
+	}
+
+	return_VALUE(status);
+}
+
+static int 
+acpi_video_get_next_level(
+	struct acpi_video_device *device,
+	u32	level_current,
+	u32	event)
+{
+	/*Fix me*/
+	return level_current;
+}
+
+
+static void
+acpi_video_switch_brightness (
+	struct acpi_video_device *device, 
+	int	event)
+{
+	unsigned long level_current, level_next;
+	acpi_video_device_lcd_get_level_current(device, &level_current);
+	level_next = acpi_video_get_next_level(device, level_current, event);
+	acpi_video_device_lcd_set_level(device, level_next);
+}
+
+static int
+acpi_video_bus_get_devices (
+	struct acpi_video_bus	*video,
+	struct acpi_device	*device)
+{
+	int			status = 0;
+	struct list_head	*node, *next;
+
+	ACPI_FUNCTION_TRACE("acpi_video_get_devices");
+
+	acpi_video_device_enumerate(video);
+
+	list_for_each_safe(node, next, &device->children) {
+		struct acpi_device *dev = list_entry(node, struct acpi_device, node);
+
+		if (!dev)
+			continue;
+
+		status = acpi_video_bus_get_one_device(dev, video);
+		if (ACPI_FAILURE(status)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Cant attach device\n"));
+			continue;
+		}
+
+	}
+	return_VALUE(status);
+}
+
+static int
+acpi_video_bus_put_one_device(
+	struct acpi_video_device	*device)
+{
+	struct acpi_video_bus *video;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_put_one_device");
+
+	if (!device || !device->video)
+		return_VALUE(-ENOENT);
+
+	video = device->video;
+
+	down(&video->sem);
+	list_del(&device->entry);
+	up(&video->sem);
+	acpi_video_device_remove_fs(device->dev);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_video_bus_put_devices (
+	struct acpi_video_bus	*video)
+{
+	int			status;
+	struct list_head	*node, *next;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_put_devices");
+
+	list_for_each_safe(node, next, &video->video_device_list) {
+		struct acpi_video_device *data = list_entry(node, struct acpi_video_device, entry);
+		if (!data)
+			continue;
+
+		status = acpi_video_bus_put_one_device(data);
+		if(ACPI_FAILURE(status))
+			printk(KERN_WARNING PREFIX "hhuuhhuu bug in acpi video driver.\n");
+
+		if (data->brightness)
+			kfree(data->brightness);
+
+		kfree(data);
+	}
+
+	return_VALUE(0);
+}
+
+/* acpi_video interface */
+
+static int
+acpi_video_bus_start_devices(
+	struct acpi_video_bus	*video)
+{
+	return acpi_video_bus_DOS(video, 1, 0);
+}
+
+static int
+acpi_video_bus_stop_devices(
+	struct acpi_video_bus	*video)
+{
+	return acpi_video_bus_DOS(video, 0, 1);
+}
+
+static void
+acpi_video_bus_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_video_bus	*video = (struct acpi_video_bus *) data;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_notify");
+	printk("video bus notify\n");
+
+	if (!video)
+		return_VOID;
+
+	if (acpi_bus_get_device(handle, &device))
+		return_VOID;
+
+	switch (event) {
+	case ACPI_VIDEO_NOTIFY_SWITCH:	/* User request that a switch occur,
+					 * most likely via hotkey. */
+		acpi_bus_generate_event(device, event, 0);
+		break;
+
+	case ACPI_VIDEO_NOTIFY_PROBE:	/* User plug or remove a video
+					 * connector. */
+		acpi_video_device_enumerate(video);
+		acpi_video_device_rebind(video);
+		acpi_video_switch_output(video, event);
+		acpi_bus_generate_event(device, event, 0);
+		break;
+
+	case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed.*/
+	case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
+	case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
+		acpi_video_switch_output(video, event);
+		acpi_bus_generate_event(device, event, 0);
+		break;
+
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+static void
+acpi_video_device_notify (
+	acpi_handle		handle,
+	u32			event,
+	void			*data)
+{
+	struct acpi_video_device	*video_device = (struct acpi_video_device *) data;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_video_device_notify");
+
+	printk("video device notify\n");
+	if (!video_device)
+		return_VOID;
+
+	if (acpi_bus_get_device(handle, &device))
+		return_VOID;
+
+	switch (event) {
+	case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */
+	case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */
+		acpi_bus_generate_event(device, event, 0);
+		break;
+	case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
+	case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
+	case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
+	case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
+	case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
+		acpi_video_switch_brightness (video_device, event);
+		acpi_bus_generate_event(device, event, 0);
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+	return_VOID;
+}
+
+static int
+acpi_video_bus_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = 0;
+	struct acpi_video_bus	*video = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_add");
+	
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
+	if (!video)
+		return_VALUE(-ENOMEM);
+	memset(video, 0, sizeof(struct acpi_video_bus));
+
+	video->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
+	strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
+	acpi_driver_data(device) = video;
+
+	acpi_video_bus_find_cap(video);
+	result = acpi_video_bus_check(video);
+	if (result)
+		goto end;
+
+	result = acpi_video_bus_add_fs(device);
+	if (result)
+		goto end;
+
+	init_MUTEX(&video->sem);
+	INIT_LIST_HEAD(&video->video_device_list);
+
+	acpi_video_bus_get_devices(video, device);
+	acpi_video_bus_start_devices(video);
+
+	status = acpi_install_notify_handler(video->handle,
+		ACPI_DEVICE_NOTIFY, acpi_video_bus_notify, video);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing notify handler\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s  rom: %s  post: %s)\n",
+		ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
+		video->flags.multihead ? "yes":"no",
+		video->flags.rom ? "yes":"no",
+		video->flags.post ? "yes":"no");
+
+end:
+	if (result) {
+		acpi_video_bus_remove_fs(device);
+		kfree(video);
+	}
+
+	return_VALUE(result);
+}
+
+static int
+acpi_video_bus_remove (
+	struct acpi_device	*device,
+	int			type)
+{
+	acpi_status		status = 0;
+	struct acpi_video_bus	*video = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	video = (struct acpi_video_bus *) acpi_driver_data(device);
+
+	acpi_video_bus_stop_devices(video);
+
+	status = acpi_remove_notify_handler(video->handle,
+		ACPI_DEVICE_NOTIFY, acpi_video_bus_notify);
+	if (ACPI_FAILURE(status))
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error removing notify handler\n"));
+
+	acpi_video_bus_put_devices(video);
+	acpi_video_bus_remove_fs(device);
+
+	if (video->attached_array)
+		kfree(video->attached_array);
+	kfree(video);
+
+	return_VALUE(0);
+}
+
+
+static int
+acpi_video_bus_match (
+	struct acpi_device	*device,
+	struct acpi_driver	*driver)
+{
+	acpi_handle		h_dummy1;
+	acpi_handle		h_dummy2;
+	acpi_handle		h_dummy3;
+
+	ACPI_FUNCTION_TRACE("acpi_video_bus_match");
+
+	if (!device || !driver)
+		return_VALUE(-EINVAL);
+
+	/* Since there is no HID, CID for ACPI Video drivers, we have
+	 * to check well known required nodes for each feature we support.
+	 */
+
+	/* Does this device able to support video switching ? */
+	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
+	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
+		return_VALUE(0);
+
+	/* Does this device able to retrieve a video ROM ? */
+	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
+		return_VALUE(0);
+
+	/* Does this device able to configure which video head to be POSTed ? */
+	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
+	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
+	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
+		return_VALUE(0);
+
+
+	return_VALUE(-ENODEV);
+}
+
+
+static int __init
+acpi_video_init (void)
+{
+	int			result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_video_init");
+
+	/*
+	acpi_dbg_level = 0xFFFFFFFF;
+	acpi_dbg_layer = 0x08000000;
+	*/
+
+	acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
+	if (!acpi_video_dir)
+		return_VALUE(-ENODEV);
+	acpi_video_dir->owner = THIS_MODULE;
+
+	result = acpi_bus_register_driver(&acpi_video_bus);
+	if (result < 0) {
+		remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+static void __exit
+acpi_video_exit (void)
+{
+	ACPI_FUNCTION_TRACE("acpi_video_exit");
+
+	acpi_bus_unregister_driver(&acpi_video_bus);
+
+	remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
+
+	return_VOID;
+}
+
+module_init(acpi_video_init);
+module_exit(acpi_video_exit);