summary refs log tree commit diff
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2007-02-03 01:08:52 -0500
committerLen Brown <len.brown@intel.com>2007-02-03 01:08:52 -0500
commite8bdc5a9c56c140c732246a298922c3cf3777460 (patch)
treedfdbf3a5597dfc5b29324a4dcb303839504cd88e /drivers/acpi
parentc6f4bc211122c86de85a6c93f139319957fd1f8a (diff)
parentb0b7eaaf0c7aefd118d3ff8640fbed75a9fad9a1 (diff)
downloadlinux-e8bdc5a9c56c140c732246a298922c3cf3777460.tar.gz
Pull acpica into test branch
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/asus_acpi.c9
-rw-r--r--drivers/acpi/blacklist.c29
-rw-r--r--drivers/acpi/bus.c42
-rw-r--r--drivers/acpi/dispatcher/dsfield.c32
-rw-r--r--drivers/acpi/dispatcher/dsinit.c25
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c55
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c2
-rw-r--r--drivers/acpi/dispatcher/dsobject.c78
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c6
-rw-r--r--drivers/acpi/dispatcher/dsutils.c2
-rw-r--r--drivers/acpi/dispatcher/dswexec.c12
-rw-r--r--drivers/acpi/dispatcher/dswload.c19
-rw-r--r--drivers/acpi/dispatcher/dswscope.c2
-rw-r--r--drivers/acpi/dispatcher/dswstate.c2
-rw-r--r--drivers/acpi/ec.c13
-rw-r--r--drivers/acpi/events/evevent.c17
-rw-r--r--drivers/acpi/events/evgpe.c91
-rw-r--r--drivers/acpi/events/evgpeblk.c64
-rw-r--r--drivers/acpi/events/evmisc.c201
-rw-r--r--drivers/acpi/events/evregion.c17
-rw-r--r--drivers/acpi/events/evrgnini.c168
-rw-r--r--drivers/acpi/events/evsci.c14
-rw-r--r--drivers/acpi/events/evxface.c8
-rw-r--r--drivers/acpi/events/evxfevnt.c27
-rw-r--r--drivers/acpi/events/evxfregn.c2
-rw-r--r--drivers/acpi/executer/exconfig.c235
-rw-r--r--drivers/acpi/executer/exconvrt.c2
-rw-r--r--drivers/acpi/executer/excreate.c21
-rw-r--r--drivers/acpi/executer/exdump.c29
-rw-r--r--drivers/acpi/executer/exfield.c2
-rw-r--r--drivers/acpi/executer/exfldio.c7
-rw-r--r--drivers/acpi/executer/exmisc.c2
-rw-r--r--drivers/acpi/executer/exmutex.c86
-rw-r--r--drivers/acpi/executer/exnames.c2
-rw-r--r--drivers/acpi/executer/exoparg1.c4
-rw-r--r--drivers/acpi/executer/exoparg2.c2
-rw-r--r--drivers/acpi/executer/exoparg3.c2
-rw-r--r--drivers/acpi/executer/exoparg6.c2
-rw-r--r--drivers/acpi/executer/exprep.c2
-rw-r--r--drivers/acpi/executer/exregion.c16
-rw-r--r--drivers/acpi/executer/exresnte.c2
-rw-r--r--drivers/acpi/executer/exresolv.c10
-rw-r--r--drivers/acpi/executer/exresop.c12
-rw-r--r--drivers/acpi/executer/exstore.c2
-rw-r--r--drivers/acpi/executer/exstoren.c2
-rw-r--r--drivers/acpi/executer/exstorob.c2
-rw-r--r--drivers/acpi/executer/exsystem.c110
-rw-r--r--drivers/acpi/executer/exutils.c106
-rw-r--r--drivers/acpi/hardware/hwacpi.c56
-rw-r--r--drivers/acpi/hardware/hwgpe.c15
-rw-r--r--drivers/acpi/hardware/hwregs.c98
-rw-r--r--drivers/acpi/hardware/hwsleep.c81
-rw-r--r--drivers/acpi/hardware/hwtimer.c9
-rw-r--r--drivers/acpi/motherboard.c40
-rw-r--r--drivers/acpi/namespace/nsaccess.c36
-rw-r--r--drivers/acpi/namespace/nsalloc.c14
-rw-r--r--drivers/acpi/namespace/nsdump.c13
-rw-r--r--drivers/acpi/namespace/nsdumpdv.c2
-rw-r--r--drivers/acpi/namespace/nseval.c13
-rw-r--r--drivers/acpi/namespace/nsinit.c9
-rw-r--r--drivers/acpi/namespace/nsload.c160
-rw-r--r--drivers/acpi/namespace/nsnames.c2
-rw-r--r--drivers/acpi/namespace/nsobject.c2
-rw-r--r--drivers/acpi/namespace/nsparse.c52
-rw-r--r--drivers/acpi/namespace/nssearch.c9
-rw-r--r--drivers/acpi/namespace/nsutils.c9
-rw-r--r--drivers/acpi/namespace/nswalk.c65
-rw-r--r--drivers/acpi/namespace/nsxfeval.c13
-rw-r--r--drivers/acpi/namespace/nsxfname.c47
-rw-r--r--drivers/acpi/namespace/nsxfobj.c2
-rw-r--r--drivers/acpi/numa.c77
-rw-r--r--drivers/acpi/osl.c49
-rw-r--r--drivers/acpi/parser/psargs.c2
-rw-r--r--drivers/acpi/parser/psloop.c1408
-rw-r--r--drivers/acpi/parser/psopcode.c2
-rw-r--r--drivers/acpi/parser/psparse.c7
-rw-r--r--drivers/acpi/parser/psscope.c2
-rw-r--r--drivers/acpi/parser/pstree.c2
-rw-r--r--drivers/acpi/parser/psutils.c2
-rw-r--r--drivers/acpi/parser/pswalk.c2
-rw-r--r--drivers/acpi/parser/psxface.c116
-rw-r--r--drivers/acpi/pci_link.c4
-rw-r--r--drivers/acpi/processor_core.c181
-rw-r--r--drivers/acpi/processor_idle.c52
-rw-r--r--drivers/acpi/processor_perflib.c27
-rw-r--r--drivers/acpi/processor_throttling.c4
-rw-r--r--drivers/acpi/resources/rsaddr.c2
-rw-r--r--drivers/acpi/resources/rscalc.c2
-rw-r--r--drivers/acpi/resources/rscreate.c2
-rw-r--r--drivers/acpi/resources/rsdump.c2
-rw-r--r--drivers/acpi/resources/rsinfo.c2
-rw-r--r--drivers/acpi/resources/rsio.c2
-rw-r--r--drivers/acpi/resources/rsirq.c2
-rw-r--r--drivers/acpi/resources/rslist.c2
-rw-r--r--drivers/acpi/resources/rsmemory.c2
-rw-r--r--drivers/acpi/resources/rsmisc.c2
-rw-r--r--drivers/acpi/resources/rsutils.c2
-rw-r--r--drivers/acpi/resources/rsxface.c2
-rw-r--r--drivers/acpi/scan.c4
-rw-r--r--drivers/acpi/sleep/proc.c36
-rw-r--r--drivers/acpi/system.c15
-rw-r--r--drivers/acpi/tables.c508
-rw-r--r--drivers/acpi/tables/Makefile3
-rw-r--r--drivers/acpi/tables/tbconvrt.c622
-rw-r--r--drivers/acpi/tables/tbfadt.c434
-rw-r--r--drivers/acpi/tables/tbfind.c126
-rw-r--r--drivers/acpi/tables/tbget.c471
-rw-r--r--drivers/acpi/tables/tbgetall.c311
-rw-r--r--drivers/acpi/tables/tbinstal.c664
-rw-r--r--drivers/acpi/tables/tbrsdt.c307
-rw-r--r--drivers/acpi/tables/tbutils.c513
-rw-r--r--drivers/acpi/tables/tbxface.c671
-rw-r--r--drivers/acpi/tables/tbxfroot.c552
-rw-r--r--drivers/acpi/utilities/utalloc.c11
-rw-r--r--drivers/acpi/utilities/utcache.c10
-rw-r--r--drivers/acpi/utilities/utcopy.c11
-rw-r--r--drivers/acpi/utilities/utdebug.c7
-rw-r--r--drivers/acpi/utilities/utdelete.c16
-rw-r--r--drivers/acpi/utilities/uteval.c2
-rw-r--r--drivers/acpi/utilities/utglobal.c199
-rw-r--r--drivers/acpi/utilities/utinit.c114
-rw-r--r--drivers/acpi/utilities/utmath.c2
-rw-r--r--drivers/acpi/utilities/utmisc.c102
-rw-r--r--drivers/acpi/utilities/utmutex.c2
-rw-r--r--drivers/acpi/utilities/utobject.c2
-rw-r--r--drivers/acpi/utilities/utresrc.c2
-rw-r--r--drivers/acpi/utilities/utstate.c2
-rw-r--r--drivers/acpi/utilities/utxface.c29
128 files changed, 4198 insertions, 5855 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 396140bbbe57..31ad70a6e22e 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -26,7 +26,7 @@
  *  Pontus Fuchs   - Helper functions, cleanup
  *  Johann Wiesner - Small compile fixes
  *  John Belmonte  - ACPI code for Toshiba laptop was a good starting point.
- *  Éric Burghard  - LED display support for W1N
+ *  �ic Burghard  - LED display support for W1N
  *
  */
 
@@ -1128,7 +1128,6 @@ static int asus_model_match(char *model)
 static int 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;
 	char *string = NULL;
@@ -1142,11 +1141,9 @@ static int asus_hotk_get_info(void)
 	 * HID), this bit will be moved. A global variable asus_info contains
 	 * the DSDT header.
 	 */
-	status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt);
+	status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info);
 	if (ACPI_FAILURE(status))
 		printk(KERN_WARNING "  Couldn't get the DSDT table header\n");
-	else
-		asus_info = dsdt.pointer;
 
 	/* We have to write 0 on init this far for all ASUS models */
 	if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
@@ -1358,8 +1355,6 @@ static void __exit asus_acpi_exit(void)
 	acpi_bus_unregister_driver(&asus_hotk_driver);
 	remove_proc_entry(PROC_ASUS, acpi_root_dir);
 
-	kfree(asus_info);
-
 	return;
 }
 
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index f9c972b26f4f..f289fd41e77d 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -44,7 +44,7 @@ struct acpi_blacklist_item {
 	char oem_id[7];
 	char oem_table_id[9];
 	u32 oem_revision;
-	acpi_table_type table;
+	char *table;
 	enum acpi_blacklist_predicates oem_revision_predicate;
 	char *reason;
 	u32 is_critical_error;
@@ -56,18 +56,18 @@ struct acpi_blacklist_item {
  */
 static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
 	/* Compaq Presario 1700 */
-	{"PTLTD ", "  DSDT  ", 0x06040000, ACPI_DSDT, less_than_or_equal,
+	{"PTLTD ", "  DSDT  ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal,
 	 "Multiple problems", 1},
 	/* Sony FX120, FX140, FX150? */
-	{"SONY  ", "U0      ", 0x20010313, ACPI_DSDT, less_than_or_equal,
+	{"SONY  ", "U0      ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal,
 	 "ACPI driver problem", 1},
 	/* Compaq Presario 800, Insyde BIOS */
-	{"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT, less_than_or_equal,
+	{"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_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,
+	{"IBM   ", "TP600E  ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
 	 "Incorrect _ADR", 1},
-	{"ASUS\0\0", "P2B-S   ", 0, ACPI_DSDT, all_versions,
+	{"ASUS\0\0", "P2B-S   ", 0, ACPI_SIG_DSDT, all_versions,
 	 "Bogus PCI routing", 1},
 
 	{""}
@@ -79,7 +79,7 @@ static int __init blacklist_by_year(void)
 {
 	int year = dmi_get_year(DMI_BIOS_DATE);
 	/* Doesn't exist? Likely an old system */
-	if (year == -1) 
+	if (year == -1)
 		return 1;
 	/* 0? Likely a buggy new BIOS */
 	if (year == 0)
@@ -103,22 +103,21 @@ int __init acpi_blacklisted(void)
 {
 	int i = 0;
 	int blacklisted = 0;
-	struct acpi_table_header *table_header;
+	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)) {
+		if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) {
 			i++;
 			continue;
 		}
 
-		if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) {
+		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,
+		    (acpi_blacklist[i].oem_table_id, table_header.oem_table_id,
 		     8)) {
 			i++;
 			continue;
@@ -127,14 +126,14 @@ int __init acpi_blacklisted(void)
 		if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
 		    || (acpi_blacklist[i].oem_revision_predicate ==
 			less_than_or_equal
-			&& table_header->oem_revision <=
+			&& table_header.oem_revision <=
 			acpi_blacklist[i].oem_revision)
 		    || (acpi_blacklist[i].oem_revision_predicate ==
 			greater_than_or_equal
-			&& table_header->oem_revision >=
+			&& table_header.oem_revision >=
 			acpi_blacklist[i].oem_revision)
 		    || (acpi_blacklist[i].oem_revision_predicate == equal
-			&& table_header->oem_revision ==
+			&& table_header.oem_revision ==
 			acpi_blacklist[i].oem_revision)) {
 
 			printk(KERN_ERR PREFIX
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 766332e45592..15d677e6cee9 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -44,9 +44,6 @@ ACPI_MODULE_NAME("acpi_bus")
 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
 #endif
 
-struct 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);
@@ -582,11 +579,12 @@ static int __init acpi_bus_init_irq(void)
 	return 0;
 }
 
+acpi_native_uint acpi_gbl_permanent_mmap;
+
+
 void __init acpi_early_init(void)
 {
 	acpi_status status = AE_OK;
-	struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt };
-
 
 	if (acpi_disabled)
 		return;
@@ -597,6 +595,15 @@ void __init acpi_early_init(void)
 	if (!acpi_strict)
 		acpi_gbl_enable_interpreter_slack = TRUE;
 
+	acpi_gbl_permanent_mmap = 1;
+
+	status = acpi_reallocate_root_table();
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX
+		       "Unable to reallocate ACPI tables\n");
+		goto error0;
+	}
+
 	status = acpi_initialize_subsystem();
 	if (ACPI_FAILURE(status)) {
 		printk(KERN_ERR PREFIX
@@ -611,32 +618,25 @@ void __init acpi_early_init(void)
 		goto error0;
 	}
 
-	/*
-	 * Get a separate copy of the FADT for use by other drivers.
-	 */
-	status = acpi_get_table(ACPI_TABLE_ID_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;
+		extern u8 acpi_sci_flags;
 
 		/* compatible (0) means level (3) */
-		if (acpi_sci_flags.trigger == 0)
-			acpi_sci_flags.trigger = 3;
-
+		if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
+			acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
+			acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
+		}
 		/* Set PIC-mode SCI trigger type */
-		acpi_pic_sci_set_trigger(acpi_fadt.sci_int,
-					 acpi_sci_flags.trigger);
+		acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
+					 (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
 	} else {
 		extern int acpi_sci_override_gsi;
 		/*
-		 * now that acpi_fadt is initialized,
+		 * now that acpi_gbl_FADT is initialized,
 		 * update it with result from INT_SRC_OVR parsing
 		 */
-		acpi_fadt.sci_int = acpi_sci_override_gsi;
+		acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
 	}
 #endif
 
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index a6d77efb41a0..f049639bac35 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -133,7 +133,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
 		}
 	}
 
-	/* We could put the returned object (Node) on the object stack for later,
+	/*
+	 * 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
 	 */
@@ -514,8 +515,33 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
 
 	/* Third arg is the bank_value */
 
+	/* TBD: This arg is a term_arg, not a constant, and must be evaluated */
+
 	arg = arg->common.next;
-	info.bank_value = (u32) arg->common.value.integer;
+
+	/* Currently, only the following constants are supported */
+
+	switch (arg->common.aml_opcode) {
+	case AML_ZERO_OP:
+		info.bank_value = 0;
+		break;
+
+	case AML_ONE_OP:
+		info.bank_value = 1;
+		break;
+
+	case AML_BYTE_OP:
+	case AML_WORD_OP:
+	case AML_DWORD_OP:
+	case AML_QWORD_OP:
+		info.bank_value = (u32) arg->common.value.integer;
+		break;
+
+	default:
+		info.bank_value = 0;
+		ACPI_ERROR((AE_INFO,
+			    "Non-constant BankValue for BankField is not implemented"));
+	}
 
 	/* Fourth arg is the field flags */
 
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index 1888c055d10f..af923c388520 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
 #include <acpi/acpi.h>
 #include <acpi/acdispat.h>
 #include <acpi/acnamesp.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dsinit")
@@ -90,7 +91,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
 	 * We are only interested in NS nodes owned by the table that
 	 * was just loaded
 	 */
-	if (node->owner_id != info->table_desc->owner_id) {
+	if (node->owner_id != info->owner_id) {
 		return (AE_OK);
 	}
 
@@ -150,14 +151,21 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
  ******************************************************************************/
 
 acpi_status
-acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
+acpi_ds_initialize_objects(acpi_native_uint table_index,
 			   struct acpi_namespace_node * start_node)
 {
 	acpi_status status;
 	struct acpi_init_walk_info info;
+	struct acpi_table_header *table;
+	acpi_owner_id owner_id;
 
 	ACPI_FUNCTION_TRACE(ds_initialize_objects);
 
+	status = acpi_tb_get_owner_id(table_index, &owner_id);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 			  "**** Starting initialization of namespace objects ****\n"));
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
@@ -166,7 +174,8 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
 	info.op_region_count = 0;
 	info.object_count = 0;
 	info.device_count = 0;
-	info.table_desc = table_desc;
+	info.table_index = table_index;
+	info.owner_id = owner_id;
 
 	/* Walk entire namespace from the supplied root */
 
@@ -176,10 +185,14 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 	}
 
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(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->owner_id, info.object_count,
+			      table->signature, owner_id, info.object_count,
 			      info.device_count, info.method_count,
 			      info.op_region_count));
 
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index cf888add3191..1cbe61905824 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -327,7 +327,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
 	ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-			  "Execute method %p, currentstate=%p\n",
+			  "Calling method %p, currentstate=%p\n",
 			  this_walk_state->prev_op, this_walk_state));
 
 	/*
@@ -351,49 +351,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
 		return_ACPI_STATUS(status);
 	}
 
-	/*
-	 * 1) Parse the method. All "normal" methods are parsed for each execution.
-	 * Internal methods (_OSI, etc.) do not require parsing.
-	 */
-	if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
-
-		/* Create a new walk state for the parse */
-
-		next_walk_state =
-		    acpi_ds_create_walk_state(obj_desc->method.owner_id, op,
-					      obj_desc, NULL);
-		if (!next_walk_state) {
-			status = AE_NO_MEMORY;
-			goto cleanup;
-		}
-
-		/* Create and init a parse tree root */
-
-		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_ps_delete_parse_tree(op);
-			goto cleanup;
-		}
-
-		/* Begin AML parse (deletes next_walk_state) */
-
-		status = acpi_ps_parse_aml(next_walk_state);
-		acpi_ps_delete_parse_tree(op);
-		if (ACPI_FAILURE(status)) {
-			goto cleanup;
-		}
-	}
-
-	/* 2) Begin method execution. Create a new walk state */
+	/* Begin method parse/execution. Create a new walk state */
 
 	next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id,
 						    NULL, obj_desc, thread);
@@ -424,7 +382,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
 
 	status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
 				       obj_desc->method.aml_start,
-				       obj_desc->method.aml_length, info, 3);
+				       obj_desc->method.aml_length, info,
+				       ACPI_IMODE_EXECUTE);
 
 	ACPI_FREE(info);
 	if (ACPI_FAILURE(status)) {
@@ -445,8 +404,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
 	this_walk_state->num_operands = 0;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-			  "Starting nested execution, newstate=%p\n",
-			  next_walk_state));
+			  "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
+			  method_node->name.ascii, next_walk_state));
 
 	/* Invoke an internal method if necessary */
 
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index 459160ff9058..ba4626e06a5e 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 72190abb1d59..a474ca2334d5 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -260,7 +260,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
 	}
 
 	obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
-	op->common.node = (struct acpi_namespace_node *)obj_desc;
+	op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
 	return_ACPI_STATUS(AE_OK);
 }
 
@@ -270,7 +270,8 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
  *
  * PARAMETERS:  walk_state      - Current walk state
  *              Op              - Parser object to be translated
- *              package_length  - Number of elements in the package
+ *              element_count   - Number of elements in the package - this is
+ *                                the num_elements argument to Package()
  *              obj_desc_ptr    - Where the ACPI internal object is returned
  *
  * RETURN:      Status
@@ -278,18 +279,29 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
  * DESCRIPTION: Translate a parser Op package object to the equivalent
  *              namespace object
  *
+ * NOTE: The number of elements in the package will be always be the num_elements
+ * count, regardless of the number of elements in the package list. If
+ * num_elements is smaller, only that many package list elements are used.
+ * if num_elements is larger, the Package object is padded out with
+ * objects of type Uninitialized (as per ACPI spec.)
+ *
+ * Even though the ASL compilers do not allow num_elements to be smaller
+ * than the Package list length (for the fixed length package opcode), some
+ * BIOS code modifies the AML on the fly to adjust the num_elements, and
+ * this code compensates for that. This also provides compatibility with
+ * other AML interpreters.
+ *
  ******************************************************************************/
 
 acpi_status
 acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
 				   union acpi_parse_object *op,
-				   u32 package_length,
+				   u32 element_count,
 				   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;
 	acpi_native_uint i;
 
@@ -318,32 +330,13 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
 		obj_desc->package.node = parent->common.node;
 	}
 
-	obj_desc->package.count = package_length;
-
-	/* Count the number of items in the package list */
-
-	arg = op->common.value.arg;
-	arg = arg->common.next;
-	for (package_list_length = 0; 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.
+	 * Allocate the element array (array of pointers to the individual
+	 * objects) based on the num_elements parameter. Add an extra pointer slot
+	 * so that the list is always null terminated.
 	 */
 	obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
-							   obj_desc->package.
-							   count +
+							   element_count +
 							   1) * sizeof(void *));
 
 	if (!obj_desc->package.elements) {
@@ -351,15 +344,20 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
+	obj_desc->package.count = element_count;
+
 	/*
-	 * Initialize all elements of the package
+	 * Initialize the elements of the package, up to the num_elements count.
+	 * Package is automatically padded with uninitialized (NULL) elements
+	 * if num_elements is greater than the package list length. Likewise,
+	 * Package is truncated if num_elements is less than the list length.
 	 */
 	arg = op->common.value.arg;
 	arg = arg->common.next;
-	for (i = 0; arg; i++) {
+	for (i = 0; arg && (i < element_count); i++) {
 		if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
 
-			/* Object (package or buffer) is already built */
+			/* This package element is already built, just get it */
 
 			obj_desc->package.elements[i] =
 			    ACPI_CAST_PTR(union acpi_operand_object,
@@ -373,8 +371,14 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
 		arg = arg->common.next;
 	}
 
+	if (!arg) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Package List length larger than NumElements count (%X), truncated\n",
+				  element_count));
+	}
+
 	obj_desc->package.flags |= AOPOBJ_DATA_VALID;
-	op->common.node = (struct acpi_namespace_node *)obj_desc;
+	op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
 	return_ACPI_STATUS(status);
 }
 
@@ -488,8 +492,9 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
 		/*
 		 * Defer evaluation of Buffer term_arg operand
 		 */
-		obj_desc->buffer.node = (struct acpi_namespace_node *)
-		    walk_state->operands[0];
+		obj_desc->buffer.node =
+		    ACPI_CAST_PTR(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;
@@ -499,8 +504,9 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
 		/*
 		 * Defer evaluation of Package term_arg operand
 		 */
-		obj_desc->package.node = (struct acpi_namespace_node *)
-		    walk_state->operands[0];
+		obj_desc->package.node =
+		    ACPI_CAST_PTR(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;
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index 5b974a8fe614..6c6104a7a247 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -114,7 +114,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node,
 	}
 
 	status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
-				       aml_length, NULL, 1);
+				       aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
 	if (ACPI_FAILURE(status)) {
 		acpi_ds_delete_walk_state(walk_state);
 		goto cleanup;
@@ -157,7 +157,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node,
 	/* Execute the opcode and arguments */
 
 	status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
-				       aml_length, NULL, 3);
+				       aml_length, NULL, ACPI_IMODE_EXECUTE);
 	if (ACPI_FAILURE(status)) {
 		acpi_ds_delete_walk_state(walk_state);
 		goto cleanup;
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index 05230baf5de8..e4073e05a75c 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index d7a616c3104e..69693fa07224 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -219,7 +219,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
 	if (!op) {
 		status = acpi_ds_load2_begin_op(walk_state, out_op);
 		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
+			goto error_exit;
 		}
 
 		op = *out_op;
@@ -238,7 +238,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
 
 			status = acpi_ds_scope_stack_pop(walk_state);
 			if (ACPI_FAILURE(status)) {
-				return_ACPI_STATUS(status);
+				goto error_exit;
 			}
 		}
 	}
@@ -287,7 +287,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
 
 		status = acpi_ds_result_stack_push(walk_state);
 		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
+			goto error_exit;
 		}
 
 		status = acpi_ds_exec_begin_control_op(walk_state, op);
@@ -328,6 +328,10 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
 	/* Nothing to do here during method execution */
 
 	return_ACPI_STATUS(status);
+
+      error_exit:
+	status = acpi_ds_method_error(status, walk_state);
+	return_ACPI_STATUS(status);
 }
 
 /*****************************************************************************
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index e3ca7f6539c1..8ab9d1b29a4c 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -196,6 +196,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
 		 * one of the opcodes that actually opens a scope
 		 */
 		switch (node->type) {
+		case ACPI_TYPE_ANY:
 		case ACPI_TYPE_LOCAL_SCOPE:	/* Scope  */
 		case ACPI_TYPE_DEVICE:
 		case ACPI_TYPE_POWER:
@@ -546,6 +547,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
 	acpi_status status;
 	acpi_object_type object_type;
 	char *buffer_ptr;
+	u32 flags;
 
 	ACPI_FUNCTION_TRACE(ds_load2_begin_op);
 
@@ -669,6 +671,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
 		 * one of the opcodes that actually opens a scope
 		 */
 		switch (node->type) {
+		case ACPI_TYPE_ANY:
 		case ACPI_TYPE_LOCAL_SCOPE:	/* Scope */
 		case ACPI_TYPE_DEVICE:
 		case ACPI_TYPE_POWER:
@@ -750,12 +753,20 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
 			break;
 		}
 
-		/* Add new entry into namespace */
+		flags = ACPI_NS_NO_UPSEARCH;
+		if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
+
+			/* Execution mode, node cannot already exist, node is temporary */
+
+			flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY);
+		}
+
+		/* Add new entry or lookup existing entry */
 
 		status =
 		    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
-				   object_type, ACPI_IMODE_LOAD_PASS2,
-				   ACPI_NS_NO_UPSEARCH, walk_state, &(node));
+				   object_type, ACPI_IMODE_LOAD_PASS2, flags,
+				   walk_state, &node);
 		break;
 	}
 
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
index c9228972f5f6..3927c495e4bf 100644
--- a/drivers/acpi/dispatcher/dswscope.c
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 7817e5522679..16c8e38b51ef 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index cbdf031f3c09..743ce27fa0bb 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -872,9 +872,8 @@ 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);
+	status = acpi_get_table(ACPI_SIG_ECDT, 1,
+				(struct acpi_table_header **)&ecdt_ptr);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
@@ -891,14 +890,14 @@ static int __init acpi_ec_get_real_ecdt(void)
 	if (acpi_ec_mode == EC_INTR) {
 		init_waitqueue_head(&ec_ecdt->wait);
 	}
-	ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
-	ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
-	ec_ecdt->gpe = ecdt_ptr->gpe_bit;
+	ec_ecdt->command_addr = ecdt_ptr->control.address;
+	ec_ecdt->data_addr = ecdt_ptr->data.address;
+	ec_ecdt->gpe = ecdt_ptr->gpe;
 	/* 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);
+	status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle);
 	if (ACPI_FAILURE(status)) {
 		goto error;
 	}
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index 919037d6acff..a1f87b5def2a 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,13 +70,6 @@ acpi_status acpi_ev_initialize_events(void)
 
 	ACPI_FUNCTION_TRACE(ev_initialize_events);
 
-	/* Make sure we have ACPI tables */
-
-	if (!acpi_gbl_DSDT) {
-		ACPI_WARNING((AE_INFO, "No ACPI tables present!"));
-		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 the handlers are
@@ -211,8 +204,7 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
 		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);
+					      enable_register_id, 0);
 			if (ACPI_FAILURE(status)) {
 				return (status);
 			}
@@ -298,7 +290,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
 	/* Clear the status bit */
 
 	(void)acpi_set_register(acpi_gbl_fixed_event_info[event].
-				status_register_id, 1, ACPI_MTX_DO_NOT_LOCK);
+				status_register_id, 1);
 
 	/*
 	 * Make sure we've got a handler.  If not, report an error.
@@ -306,8 +298,7 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
 	 */
 	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);
+					enable_register_id, 0);
 
 		ACPI_ERROR((AE_INFO,
 			    "No installed handler for fixed event [%08X]",
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index c76c0583ca6a..dfac3ecc596e 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -121,7 +121,9 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
 	if (!gpe_register_info) {
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
-	register_bit = gpe_event_info->register_bit;
+	register_bit = (u8)
+	    (1 <<
+	     (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
 
 	/* 1) Disable case.  Simply clear all enable bits */
 
@@ -458,8 +460,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
 
 				/* Examine one GPE bit */
 
-				if (enabled_status_byte &
-				    acpi_gbl_decode_to8bit[j]) {
+				if (enabled_status_byte & (1 << j)) {
 					/*
 					 * Found an active GPE. Dispatch the event to a handler
 					 * or method.
@@ -570,7 +571,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
 
 		if (ACPI_FAILURE(status)) {
 			ACPI_EXCEPTION((AE_INFO, status,
-					"While evaluating GPE method [%4.4s]",
+					"while evaluating GPE method [%4.4s]",
 					acpi_ut_get_node_name
 					(local_gpe_event_info.dispatch.
 					 method_node)));
@@ -618,6 +619,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 
 	ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
 
+	acpi_gpe_count++;
+
 	/*
 	 * If edge-triggered, clear the GPE status bit now.  Note that
 	 * level-triggered events are cleared after the GPE is serviced.
@@ -633,20 +636,23 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 		}
 	}
 
-	/* 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);
+	if (!acpi_gbl_system_awake_and_running) {
+		/*
+		 * We just woke up because of a wake GPE. Disable any further GPEs
+		 * until we are fully up and running (Only wake GPEs should be enabled
+		 * at this time, but we just brute-force disable them all.)
+		 * 1) We must disable this particular wake GPE so it won't fire again
+		 * 2) We want to disable all wake GPEs, since we are now awake
+		 */
+		(void)acpi_hw_disable_all_gpes();
 	}
 
 	/*
-	 * 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.
+	 * 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 this GPE to prevent further such pointless
+	 * events from firing.
 	 */
 	switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
 	case ACPI_GPE_DISPATCH_HANDLER:
@@ -677,8 +683,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 	case ACPI_GPE_DISPATCH_METHOD:
 
 		/*
-		 * Disable GPE, so it doesn't keep firing before the method has a
-		 * chance to run.
+		 * Disable the GPE, so it doesn't keep firing before the method has a
+		 * chance to run (it runs asynchronously with interrupts enabled).
 		 */
 		status = acpi_ev_disable_gpe(gpe_event_info);
 		if (ACPI_FAILURE(status)) {
@@ -711,7 +717,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 			    gpe_number));
 
 		/*
-		 * Disable the GPE.  The GPE will remain disabled until the ACPI
+		 * 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);
@@ -726,50 +732,3 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 
 	return_UINT32(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 "DeviceWake"
- *              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_INFO((AE_INFO,
-			   "GPE %p was updated from wake/run to wake-only",
-			   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
index 95ddeb48bc0f..ad5bc76edf46 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32
 
 	/* Install new interrupt handler if not SCI_INT */
 
-	if (interrupt_number != acpi_gbl_FADT->sci_int) {
+	if (interrupt_number != acpi_gbl_FADT.sci_interrupt) {
 		status = acpi_os_install_interrupt_handler(interrupt_number,
 							   acpi_ev_gpe_xrupt_handler,
 							   gpe_xrupt);
@@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
 
 	/* We never want to remove the SCI interrupt handler */
 
-	if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) {
+	if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) {
 		gpe_xrupt->gpe_block_list_head = NULL;
 		return_ACPI_STATUS(AE_OK);
 	}
@@ -796,30 +796,31 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
 		    (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));
+		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->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 =
+		this_register->status_address.space_id =
+		    gpe_block->block_address.space_id;
+		this_register->enable_address.space_id =
+		    gpe_block->block_address.space_id;
+		this_register->status_address.bit_width =
 		    ACPI_GPE_REGISTER_WIDTH;
-		this_register->enable_address.register_bit_width =
+		this_register->enable_address.bit_width =
 		    ACPI_GPE_REGISTER_WIDTH;
-		this_register->status_address.register_bit_offset =
+		this_register->status_address.bit_offset =
 		    ACPI_GPE_REGISTER_WIDTH;
-		this_register->enable_address.register_bit_offset =
+		this_register->enable_address.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->gpe_number =
+			    (u8) (this_register->base_gpe_number + j);
 			this_event->register_info = this_register;
 			this_event++;
 		}
@@ -1109,11 +1110,12 @@ acpi_status acpi_ev_gpe_initialize(void)
 	 * 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) {
+	if (acpi_gbl_FADT.gpe0_block_length &&
+	    acpi_gbl_FADT.xgpe0_block.address) {
 
 		/* GPE block 0 exists (has both length and address > 0) */
 
-		register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2);
+		register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2);
 
 		gpe_number_max =
 		    (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
@@ -1121,9 +1123,9 @@ acpi_status acpi_ev_gpe_initialize(void)
 		/* Install GPE Block 0 */
 
 		status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
-						  &acpi_gbl_FADT->xgpe0_blk,
+						  &acpi_gbl_FADT.xgpe0_block,
 						  register_count0, 0,
-						  acpi_gbl_FADT->sci_int,
+						  acpi_gbl_FADT.sci_interrupt,
 						  &acpi_gbl_gpe_fadt_blocks[0]);
 
 		if (ACPI_FAILURE(status)) {
@@ -1132,20 +1134,21 @@ acpi_status acpi_ev_gpe_initialize(void)
 		}
 	}
 
-	if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) {
+	if (acpi_gbl_FADT.gpe1_block_length &&
+	    acpi_gbl_FADT.xgpe1_block.address) {
 
 		/* GPE block 1 exists (has both length and address > 0) */
 
-		register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2);
+		register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2);
 
 		/* Check for GPE0/GPE1 overlap (if both banks exist) */
 
 		if ((register_count0) &&
-		    (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
+		    (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
 			ACPI_ERROR((AE_INFO,
 				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
-				    gpe_number_max, acpi_gbl_FADT->gpe1_base,
-				    acpi_gbl_FADT->gpe1_base +
+				    gpe_number_max, acpi_gbl_FADT.gpe1_base,
+				    acpi_gbl_FADT.gpe1_base +
 				    ((register_count1 *
 				      ACPI_GPE_REGISTER_WIDTH) - 1)));
 
@@ -1157,10 +1160,11 @@ acpi_status acpi_ev_gpe_initialize(void)
 
 			status =
 			    acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
-						     &acpi_gbl_FADT->xgpe1_blk,
+						     &acpi_gbl_FADT.xgpe1_block,
 						     register_count1,
-						     acpi_gbl_FADT->gpe1_base,
-						     acpi_gbl_FADT->sci_int,
+						     acpi_gbl_FADT.gpe1_base,
+						     acpi_gbl_FADT.
+						     sci_interrupt,
 						     &acpi_gbl_gpe_fadt_blocks
 						     [1]);
 
@@ -1173,7 +1177,7 @@ acpi_status acpi_ev_gpe_initialize(void)
 			 * 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 +
+			gpe_number_max = acpi_gbl_FADT.gpe1_base +
 			    ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
 		}
 	}
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index bf63edc6608d..1b784ffe54c3 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,14 +63,18 @@ static const char *acpi_notify_value_names[] = {
 };
 #endif
 
+/* Pointer to FACS needed for the Global Lock */
+
+static struct acpi_table_facs *facs = NULL;
+
 /* Local prototypes */
 
 static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
 
-static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context);
-
 static u32 acpi_ev_global_lock_handler(void *context);
 
+static acpi_status acpi_ev_remove_global_lock_handler(void);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_is_notify_object
@@ -282,49 +286,19 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
 
 /*******************************************************************************
  *
- * 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_ERROR((AE_INFO,
-				    "Could not signal Global Lock semaphore"));
-		}
-	}
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ev_global_lock_handler
  *
  * PARAMETERS:  Context         - From thread interface, not used
  *
- * RETURN:      ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED
+ * RETURN:      ACPI_INTERRUPT_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
+ *              release interrupt occurs. Attempt to acquire the global lock,
+ *              if successful, signal the thread waiting for the lock.
+ *
+ * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
+ * this is not possible for some reason, a separate thread will have to be
+ * scheduled to do this.
  *
  ******************************************************************************/
 
@@ -333,16 +307,24 @@ static u32 acpi_ev_global_lock_handler(void *context)
 	u8 acquired = FALSE;
 
 	/*
-	 * Attempt to get the lock
+	 * 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);
+	ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
 	if (acquired) {
 
 		/* Got the lock, now wake all threads waiting for it */
+
 		acpi_gbl_global_lock_acquired = TRUE;
-		acpi_ev_global_lock_thread(context);
+		/* Send a unit to the semaphore */
+
+		if (ACPI_FAILURE(acpi_os_signal_semaphore(
+			acpi_gbl_global_lock_semaphore, 1))) {
+			ACPI_ERROR((AE_INFO,
+				    "Could not signal Global Lock semaphore"));
+		}
 	}
 
 	return (ACPI_INTERRUPT_HANDLED);
@@ -366,6 +348,13 @@ acpi_status acpi_ev_init_global_lock_handler(void)
 
 	ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
 
+	status =
+	    acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
+				    (struct acpi_table_header **)&facs);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	acpi_gbl_global_lock_present = TRUE;
 	status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
 						  acpi_ev_global_lock_handler,
@@ -389,6 +378,31 @@ acpi_status acpi_ev_init_global_lock_handler(void)
 	return_ACPI_STATUS(status);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_remove_global_lock_handler
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove the handler for the Global Lock
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_ev_remove_global_lock_handler(void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
+
+	acpi_gbl_global_lock_present = FALSE;
+	status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
+						 acpi_ev_global_lock_handler);
+
+	return_ACPI_STATUS(status);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_ev_acquire_global_lock
@@ -399,6 +413,16 @@ acpi_status acpi_ev_init_global_lock_handler(void)
  *
  * DESCRIPTION: Attempt to gain ownership of the Global Lock.
  *
+ * MUTEX:       Interpreter must be locked
+ *
+ * Note: The original implementation allowed multiple threads to "acquire" the
+ * Global Lock, and the OS would hold the lock until the last thread had
+ * released it. However, this could potentially starve the BIOS out of the
+ * lock, especially in the case where there is a tight handshake between the
+ * Embedded Controller driver and the BIOS. Therefore, this implementation
+ * allows only one thread to acquire the HW Global Lock at a time, and makes
+ * the global lock appear as a standard mutex on the OS side.
+ *
  *****************************************************************************/
 
 acpi_status acpi_ev_acquire_global_lock(u16 timeout)
@@ -408,53 +432,51 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
 
 	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);
+	/*
+	 * Only one thread can acquire the GL at a time, the global_lock_mutex
+	 * enforces this. This interface releases the interpreter if we must wait.
+	 */
+	status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
 	}
-#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
+	 * Make sure that a global lock actually exists. If not, just treat
+	 * the lock as a standard mutex.
 	 */
-	if (acpi_gbl_global_lock_acquired) {
+	if (!acpi_gbl_global_lock_present) {
+		acpi_gbl_global_lock_acquired = TRUE;
 		return_ACPI_STATUS(AE_OK);
 	}
 
-	/* We must acquire the actual hardware lock */
+	/* Attempt to acquire the actual hardware lock */
 
-	ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired);
+	ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
 	if (acquired) {
 
 		/* We got the lock */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "Acquired the HW Global Lock\n"));
+				  "Acquired hardware 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
+	 * 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"));
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
 
 	/*
-	 * Acquire the global lock semaphore first.
-	 * Since this wait will block, we must release the interpreter
+	 * Wait for handshake with the global lock interrupt handler.
+	 * This interface releases the interpreter if we must wait.
 	 */
-	status =
-	    acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
-					  timeout);
+	status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
+					       ACPI_WAIT_FOREVER);
+
 	return_ACPI_STATUS(status);
 }
 
@@ -477,38 +499,39 @@ acpi_status acpi_ev_release_global_lock(void)
 
 	ACPI_FUNCTION_TRACE(ev_release_global_lock);
 
-	if (!acpi_gbl_global_lock_thread_count) {
+	/* Lock must be already acquired */
+
+	if (!acpi_gbl_global_lock_acquired) {
 		ACPI_WARNING((AE_INFO,
-			      "Cannot release HW Global Lock, it has not been acquired"));
+			      "Cannot release the ACPI Global Lock, it has not been acquired"));
 		return_ACPI_STATUS(AE_NOT_ACQUIRED);
 	}
 
-	/* One fewer thread has the global lock */
+	if (acpi_gbl_global_lock_present) {
 
-	acpi_gbl_global_lock_thread_count--;
-	if (acpi_gbl_global_lock_thread_count) {
+		/* Allow any thread to release the lock */
 
-		/* There are still some threads holding the lock, cannot release */
+		ACPI_RELEASE_GLOBAL_LOCK(facs, pending);
 
-		return_ACPI_STATUS(AE_OK);
+		/*
+		 * 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_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Released hardware Global Lock\n"));
 	}
 
-	/*
-	 * 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);
-	}
+	/* Release the local GL mutex */
 
+	acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
 	return_ACPI_STATUS(status);
 }
 
@@ -558,6 +581,12 @@ void acpi_ev_terminate(void)
 		if (ACPI_FAILURE(status)) {
 			ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
 		}
+
+		status = acpi_ev_remove_global_lock_handler();
+		if (ACPI_FAILURE(status)) {
+			ACPI_ERROR((AE_INFO,
+				    "Could not remove Global Lock handler"));
+		}
 	}
 
 	/* Deallocate all handler objects installed within GPE info structs */
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 21caae04fe85..e99f0c435a47 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -291,7 +291,6 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 			       u32 bit_width, acpi_integer * value)
 {
 	acpi_status status;
-	acpi_status status2;
 	acpi_adr_space_handler handler;
 	acpi_adr_space_setup region_setup;
 	union acpi_operand_object *handler_desc;
@@ -345,7 +344,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 		 * setup will potentially execute control methods
 		 * (e.g., _REG method for this region)
 		 */
-		acpi_ex_exit_interpreter();
+		acpi_ex_relinquish_interpreter();
 
 		status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
 				      handler_desc->address_space.context,
@@ -353,10 +352,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 
 		/* Re-enter the interpreter */
 
-		status2 = acpi_ex_enter_interpreter();
-		if (ACPI_FAILURE(status2)) {
-			return_ACPI_STATUS(status2);
-		}
+		acpi_ex_reacquire_interpreter();
 
 		/* Check for failure of the Region Setup */
 
@@ -409,7 +405,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 		 * 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();
+		acpi_ex_relinquish_interpreter();
 	}
 
 	/* Call the handler */
@@ -430,10 +426,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 		 * 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);
-		}
+		acpi_ex_reacquire_interpreter();
 	}
 
 	return_ACPI_STATUS(status);
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 203d1359190a..a4fa7e6822a3 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,11 @@
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evrgnini")
 
+/* Local prototypes */
+static u8 acpi_ev_match_pci_root_bridge(char *id);
+
+static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_system_memory_region_setup
@@ -62,6 +67,7 @@ ACPI_MODULE_NAME("evrgnini")
  * DESCRIPTION: Setup a system_memory operation region
  *
  ******************************************************************************/
+
 acpi_status
 acpi_ev_system_memory_region_setup(acpi_handle handle,
 				   u32 function,
@@ -168,9 +174,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
 	union acpi_operand_object *handler_obj;
 	struct acpi_namespace_node *parent_node;
 	struct acpi_namespace_node *pci_root_node;
+	struct acpi_namespace_node *pci_device_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);
 
@@ -215,45 +221,30 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
 
 		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 string, check if this is a PCI root.
-				 * New for ACPI 3.0: check for a PCI Express root also.
-				 */
-				if (!
-				    (ACPI_STRNCMP
-				     (object_hID.value, PCI_ROOT_HID_STRING,
-				      sizeof(PCI_ROOT_HID_STRING)))
-				    ||
-				    !(ACPI_STRNCMP
-				      (object_hID.value,
-				       PCI_EXPRESS_ROOT_HID_STRING,
-				       sizeof(PCI_EXPRESS_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_EXCEPTION((AE_INFO,
-									status,
-									"Could not install PciConfig handler for Root Bridge %4.4s",
-									acpi_ut_get_node_name
-									(pci_root_node)));
-						}
+			/* Get the _HID/_CID in order to detect a root_bridge */
+
+			if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
+
+				/* 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_EXCEPTION((AE_INFO, status,
+								"Could not install PciConfig handler for Root Bridge %4.4s",
+								acpi_ut_get_node_name
+								(pci_root_node)));
 					}
-					break;
 				}
+				break;
 			}
 
 			pci_root_node = acpi_ns_get_parent_node(pci_root_node);
@@ -282,14 +273,25 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
 	/*
 	 * For PCI_Config space access, we need the segment, bus,
 	 * device and function numbers.  Acquire them here.
+	 *
+	 * Find the parent device object. (This allows the operation region to be
+	 * within a subscope under the device, such as a control method.)
 	 */
+	pci_device_node = region_obj->region.node;
+	while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
+		pci_device_node = acpi_ns_get_parent_node(pci_device_node);
+	}
+
+	if (!pci_device_node) {
+		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
+	}
 
 	/*
 	 * 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,
+	    acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
 					    &pci_value);
 
 	/*
@@ -329,6 +331,91 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ev_match_pci_root_bridge
+ *
+ * PARAMETERS:  Id              - The HID/CID in string format
+ *
+ * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
+ *
+ * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
+ *
+ ******************************************************************************/
+
+static u8 acpi_ev_match_pci_root_bridge(char *id)
+{
+
+	/*
+	 * Check if this is a PCI root.
+	 * ACPI 3.0+: check for a PCI Express root also.
+	 */
+	if (!(ACPI_STRNCMP(id,
+			   PCI_ROOT_HID_STRING,
+			   sizeof(PCI_ROOT_HID_STRING))) ||
+	    !(ACPI_STRNCMP(id,
+			   PCI_EXPRESS_ROOT_HID_STRING,
+			   sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
+		return (TRUE);
+	}
+
+	return (FALSE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_is_pci_root_bridge
+ *
+ * PARAMETERS:  Node            - Device node being examined
+ *
+ * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
+ *
+ * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
+ *              examining the _HID and _CID for the device.
+ *
+ ******************************************************************************/
+
+static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
+{
+	acpi_status status;
+	struct acpi_device_id hid;
+	struct acpi_compatible_id_list *cid;
+	acpi_native_uint i;
+
+	/*
+	 * Get the _HID and check for a PCI Root Bridge
+	 */
+	status = acpi_ut_execute_HID(node, &hid);
+	if (ACPI_FAILURE(status)) {
+		return (FALSE);
+	}
+
+	if (acpi_ev_match_pci_root_bridge(hid.value)) {
+		return (TRUE);
+	}
+
+	/*
+	 * The _HID did not match.
+	 * Get the _CID and check for a PCI Root Bridge
+	 */
+	status = acpi_ut_execute_CID(node, &cid);
+	if (ACPI_FAILURE(status)) {
+		return (FALSE);
+	}
+
+	/* Check all _CIDs in the returned list */
+
+	for (i = 0; i < cid->count; i++) {
+		if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) {
+			ACPI_FREE(cid);
+			return (TRUE);
+		}
+	}
+
+	ACPI_FREE(cid);
+	return (FALSE);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ev_pci_bar_region_setup
  *
  * PARAMETERS:  Handle              - Region we are interested in
@@ -432,6 +519,9 @@ acpi_ev_default_region_setup(acpi_handle handle,
  *              a PCI address in the scope of the definition.  This address is
  *              required to perform an access to PCI config space.
  *
+ * MUTEX:       Interpreter should be unlocked, because we may run the _REG
+ *              method for this region.
+ *
  ******************************************************************************/
 
 acpi_status
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
index 8106215ad554..7e5d15ce2395 100644
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -142,9 +142,10 @@ u32 acpi_ev_install_sci_handler(void)
 
 	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);
+	status =
+	    acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
+					      acpi_ev_sci_xrupt_handler,
+					      acpi_gbl_gpe_xrupt_list_head);
 	return_ACPI_STATUS(status);
 }
 
@@ -175,8 +176,9 @@ acpi_status acpi_ev_remove_sci_handler(void)
 
 	/* 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);
+	status =
+	    acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
+					     acpi_ev_sci_xrupt_handler);
 
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 923fd2b46955..685a103a3587 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -768,11 +768,9 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
 		return (AE_BAD_PARAMETER);
 	}
 
-	status = acpi_ex_enter_interpreter();
-	if (ACPI_FAILURE(status)) {
-		return (status);
-	}
+	/* Must lock interpreter to prevent race conditions */
 
+	acpi_ex_enter_interpreter();
 	status = acpi_ev_acquire_global_lock(timeout);
 	acpi_ex_exit_interpreter();
 
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 7ebc2efac936..17065e98807c 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
 #include <acpi/acpi.h>
 #include <acpi/acevents.h>
 #include <acpi/acnamesp.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evxfevnt")
@@ -65,13 +66,14 @@ acpi_status acpi_enable(void)
 
 	ACPI_FUNCTION_TRACE(acpi_enable);
 
-	/* Make sure we have the FADT */
+	/* ACPI tables must be present */
 
-	if (!acpi_gbl_FADT) {
-		ACPI_WARNING((AE_INFO, "No FADT information present!"));
+	if (!acpi_tb_tables_loaded()) {
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
 
+	/* Check current mode */
+
 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
 				  "System is already in ACPI mode\n"));
@@ -111,11 +113,6 @@ acpi_status acpi_disable(void)
 
 	ACPI_FUNCTION_TRACE(acpi_disable);
 
-	if (!acpi_gbl_FADT) {
-		ACPI_WARNING((AE_INFO, "No FADT information present!"));
-		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"));
@@ -169,7 +166,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
 	 */
 	status =
 	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 1, ACPI_MTX_LOCK);
+			      enable_register_id, 1);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -178,7 +175,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
 
 	status =
 	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, &value, ACPI_MTX_LOCK);
+			      enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -368,14 +365,14 @@ acpi_status acpi_disable_event(u32 event, u32 flags)
 	 */
 	status =
 	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 0, ACPI_MTX_LOCK);
+			      enable_register_id, 0);
 	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);
+			      enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -421,7 +418,7 @@ acpi_status acpi_clear_event(u32 event)
 	 */
 	status =
 	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      status_register_id, 1, ACPI_MTX_LOCK);
+			      status_register_id, 1);
 
 	return_ACPI_STATUS(status);
 }
@@ -510,7 +507,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
 
 	status =
 	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      status_register_id, event_status, ACPI_MTX_LOCK);
+			      status_register_id, event_status);
 
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index 83b12a9afa32..7bf09c5fb242 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index c8341fa5fe01..25802f302ffe 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig")
 
 /* Local prototypes */
 static acpi_status
-acpi_ex_add_table(struct acpi_table_header *table,
+acpi_ex_add_table(acpi_native_uint table_index,
 		  struct acpi_namespace_node *parent_node,
 		  union acpi_operand_object **ddb_handle);
 
@@ -74,12 +74,11 @@ acpi_ex_add_table(struct acpi_table_header *table,
  ******************************************************************************/
 
 static acpi_status
-acpi_ex_add_table(struct acpi_table_header *table,
+acpi_ex_add_table(acpi_native_uint table_index,
 		  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);
@@ -98,42 +97,16 @@ acpi_ex_add_table(struct acpi_table_header *table,
 
 	/* Install the new table into the local data structures */
 
-	ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc));
-
-	table_info.type = ACPI_TABLE_ID_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);
-	obj_desc->reference.object = table_info.installed_desc;
-
-	if (ACPI_FAILURE(status)) {
-		if (status == AE_ALREADY_EXISTS) {
-
-			/* Table already exists, just return the handle */
-
-			return_ACPI_STATUS(AE_OK);
-		}
-		goto cleanup;
-	}
+	obj_desc->reference.object = ACPI_CAST_PTR(void, table_index);
 
 	/* Add the table to the namespace */
 
-	status = acpi_ns_load_table(table_info.installed_desc, parent_node);
+	status = acpi_ns_load_table(table_index, parent_node);
 	if (ACPI_FAILURE(status)) {
-
-		/* Uninstall table on error */
-
-		(void)acpi_tb_uninstall_table(table_info.installed_desc);
-		goto cleanup;
+		acpi_ut_remove_reference(obj_desc);
+		*ddb_handle = NULL;
 	}
 
-	return_ACPI_STATUS(AE_OK);
-
-      cleanup:
-	acpi_ut_remove_reference(obj_desc);
-	*ddb_handle = NULL;
 	return_ACPI_STATUS(status);
 }
 
@@ -146,7 +119,7 @@ acpi_ex_add_table(struct acpi_table_header *table,
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Load an ACPI table
+ * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
  *
  ******************************************************************************/
 
@@ -156,33 +129,20 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 {
 	acpi_status status;
 	union acpi_operand_object **operand = &walk_state->operands[0];
-	struct acpi_table_header *table;
+	acpi_native_uint table_index;
 	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;
+	struct acpi_table_header *table;
 
 	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 */
+	/* Find the ACPI table in the RSDT/XSDT */
 
 	status = acpi_tb_find_table(operand[0]->string.pointer,
 				    operand[1]->string.pointer,
-				    operand[2]->string.pointer, &table);
+				    operand[2]->string.pointer, &table_index);
 	if (ACPI_FAILURE(status)) {
 		if (status != AE_NOT_FOUND) {
 			return_ACPI_STATUS(status);
@@ -245,7 +205,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 
 	/* Load the table into the namespace */
 
-	status = acpi_ex_add_table(table, parent_node, &ddb_handle);
+	status = acpi_ex_add_table(table_index, parent_node, &ddb_handle);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -266,9 +226,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 		}
 	}
 
-	ACPI_INFO((AE_INFO,
-		   "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
-		   table->signature, table->oem_id, table->oem_table_id));
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_SUCCESS(status)) {
+		ACPI_INFO((AE_INFO,
+			   "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
+			   table->signature, table->oem_id,
+			   table->oem_table_id));
+	}
 
 	*return_desc = ddb_handle;
 	return_ACPI_STATUS(status);
@@ -278,7 +242,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
  *
  * FUNCTION:    acpi_ex_load_op
  *
- * PARAMETERS:  obj_desc        - Region or Field where the table will be
+ * PARAMETERS:  obj_desc        - Region or Buffer/Field where the table will be
  *                                obtained
  *              Target          - Where a handle to the table will be stored
  *              walk_state      - Current state
@@ -287,6 +251,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
  *
  * DESCRIPTION: Load an ACPI table from a field or operation region
  *
+ * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer
+ *       objects before this code is reached.
+ *
+ *       If source is an operation region, it must refer to system_memory, as
+ *       per the ACPI specification.
+ *
  ******************************************************************************/
 
 acpi_status
@@ -294,22 +264,26 @@ 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;
-	acpi_integer temp;
-	u32 i;
+	struct acpi_table_desc table_desc;
+	acpi_native_uint table_index;
+	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(ex_load_op);
 
-	/* Object can be either an op_region or a Field */
+	ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
+
+	/* Source Object can be either an op_region or a Buffer/Field */
 
 	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
 	case ACPI_TYPE_REGION:
 
+		/* Region must be system_memory (from ACPI spec) */
+
+		if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
+		}
+
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
 				  obj_desc,
 				  acpi_ut_get_object_type_name(obj_desc)));
@@ -325,113 +299,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 			}
 		}
 
-		/* Get the base physical address of the region */
-
-		address = obj_desc->region.address;
-
-		/* Get part of the table header to get the table length */
-
-		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,
-							   &temp);
-			if (ACPI_FAILURE(status)) {
-				return_ACPI_STATUS(status);
-			}
-
-			/* Get the one valid byte of the returned 64-bit value */
-
-			ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp;
-		}
-
-		/* 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_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,
-							   &temp);
-			if (ACPI_FAILURE(status)) {
-				goto cleanup;
-			}
-
-			/* Get the one valid byte of the returned 64-bit value */
-
-			ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp;
-		}
+		table_desc.address = obj_desc->region.address;
+		table_desc.length = obj_desc->region.length;
+		table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
 		break;
 
-	case ACPI_TYPE_LOCAL_REGION_FIELD:
-	case ACPI_TYPE_LOCAL_BANK_FIELD:
-	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+	case ACPI_TYPE_BUFFER:	/* Buffer or resolved region_field */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Field %p %s\n",
-				  obj_desc,
-				  acpi_ut_get_object_type_name(obj_desc)));
+		/* Simply extract the buffer from the buffer object */
 
-		/*
-		 * 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)) {
-			return_ACPI_STATUS(status);
-		}
-
-		table_ptr = ACPI_CAST_PTR(struct acpi_table_header,
-					  buffer_desc->buffer.pointer);
-
-		/* All done with the buffer_desc, delete it */
-
-		buffer_desc->buffer.pointer = NULL;
-		acpi_ut_remove_reference(buffer_desc);
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Load from Buffer or Field %p %s\n", obj_desc,
+				  acpi_ut_get_object_type_name(obj_desc)));
 
-		/* Sanity check the table length */
+		table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header,
+						   obj_desc->buffer.pointer);
+		table_desc.length = table_desc.pointer->length;
+		table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
 
-		if (table_ptr->length < sizeof(struct acpi_table_header)) {
-			status = AE_BAD_HEADER;
-			goto cleanup;
-		}
+		obj_desc->buffer.pointer = NULL;
 		break;
 
 	default:
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 	}
 
-	/* The table must be either an SSDT or a PSDT */
-
-	if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) &&
-	    (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) {
-		ACPI_ERROR((AE_INFO,
-			    "Table has invalid signature [%4.4s], must be SSDT or PSDT",
-			    table_ptr->signature));
-		status = AE_BAD_SIGNATURE;
+	/*
+	 * Install the new table into the local data structures
+	 */
+	status = acpi_tb_add_table(&table_desc, &table_index);
+	if (ACPI_FAILURE(status)) {
 		goto cleanup;
 	}
 
-	/* Install the new table into the local data structures */
-
-	status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle);
+	status =
+	    acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
 	if (ACPI_FAILURE(status)) {
 
 		/* On error, table_ptr was deallocated above */
@@ -450,13 +352,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 		return_ACPI_STATUS(status);
 	}
 
-	ACPI_INFO((AE_INFO,
-		   "Dynamic SSDT Load - OemId [%6.6s] OemTableId [%8.8s]",
-		   table_ptr->oem_id, table_ptr->oem_table_id));
-
       cleanup:
 	if (ACPI_FAILURE(status)) {
-		ACPI_FREE(table_ptr);
+		acpi_tb_delete_table(&table_desc);
 	}
 	return_ACPI_STATUS(status);
 }
@@ -477,7 +375,7 @@ 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_native_uint table_index;
 
 	ACPI_FUNCTION_TRACE(ex_unload_table);
 
@@ -493,19 +391,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Get the actual table descriptor from the ddb_handle */
+	/* Get the table index from the ddb_handle */
 
-	table_info = (struct acpi_table_desc *)table_desc->reference.object;
+	table_index = (acpi_native_uint) 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->owner_id);
-
-	/* Delete the table itself */
+	acpi_tb_delete_namespace_by_owner(table_index);
+	acpi_tb_release_owner_id(table_index);
 
-	(void)acpi_tb_uninstall_table(table_info->installed_desc);
+	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
 	/* Delete the table descriptor (ddb_handle) */
 
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index 544e81a6a438..d470e8b1f4ea 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 34eec82c1b1e..7c38528a7e83 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -359,8 +359,9 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
 	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_native_uint table_index;
+	struct acpi_table_header *table;
 
 	ACPI_FUNCTION_TRACE(ex_create_table_region);
 
@@ -380,7 +381,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
 
 	status = acpi_tb_find_table(operand[1]->string.pointer,
 				    operand[2]->string.pointer,
-				    operand[3]->string.pointer, &table);
+				    operand[3]->string.pointer, &table_index);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -395,6 +396,11 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
 	region_obj2 = obj_desc->common.next_object;
 	region_obj2->extra.region_context = NULL;
 
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	/* Init the region from the operands */
 
 	obj_desc->region.space_id = REGION_DATA_TABLE;
@@ -553,7 +559,8 @@ acpi_ex_create_method(u8 * aml_start,
 
 	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
 	if (!obj_desc) {
-		return_ACPI_STATUS(AE_NO_MEMORY);
+		status = AE_NO_MEMORY;
+		goto exit;
 	}
 
 	/* Save the method's AML pointer and length  */
@@ -576,10 +583,7 @@ acpi_ex_create_method(u8 * aml_start,
 	 * Get the sync_level. If method is serialized, a mutex will be
 	 * created for this method when it is parsed.
 	 */
-	if (acpi_gbl_all_methods_serialized) {
-		obj_desc->method.sync_level = 0;
-		obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
-	} else if (method_flags & AML_METHOD_SERIALIZED) {
+	if (method_flags & AML_METHOD_SERIALIZED) {
 		/*
 		 * ACPI 1.0: sync_level = 0
 		 * ACPI 2.0: sync_level = sync_level in method declaration
@@ -597,6 +601,7 @@ acpi_ex_create_method(u8 * aml_start,
 
 	acpi_ut_remove_reference(obj_desc);
 
+      exit:
 	/* Remove a reference to the operand */
 
 	acpi_ut_remove_reference(operand[1]);
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 2450943add33..68d283fd60e7 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -59,8 +59,6 @@ static void acpi_ex_out_string(char *title, char *value);
 
 static void acpi_ex_out_pointer(char *title, void *value);
 
-static void acpi_ex_out_address(char *title, acpi_physical_address value);
-
 static void
 acpi_ex_dump_object(union acpi_operand_object *obj_desc,
 		    struct acpi_exdump_info *info);
@@ -92,10 +90,11 @@ static struct acpi_exdump_info acpi_ex_dump_string[4] = {
 	{ACPI_EXD_STRING, 0, NULL}
 };
 
-static struct acpi_exdump_info acpi_ex_dump_buffer[4] = {
+static struct acpi_exdump_info acpi_ex_dump_buffer[5] = {
 	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL},
 	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"},
 	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.node), "Parent Node"},
 	{ACPI_EXD_BUFFER, 0, NULL}
 };
 
@@ -165,8 +164,8 @@ static struct acpi_exdump_info acpi_ex_dump_power[5] = {
 
 static struct acpi_exdump_info acpi_ex_dump_processor[7] = {
 	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL},
-	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
-	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"},
 	{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"},
 	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify),
 	 "System Notify"},
@@ -379,18 +378,12 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
 			break;
 
 		case ACPI_EXD_POINTER:
+		case ACPI_EXD_ADDRESS:
 
 			acpi_ex_out_pointer(name,
 					    *ACPI_CAST_PTR(void *, target));
 			break;
 
-		case ACPI_EXD_ADDRESS:
-
-			acpi_ex_out_address(name,
-					    *ACPI_CAST_PTR
-					    (acpi_physical_address, target));
-			break;
-
 		case ACPI_EXD_STRING:
 
 			acpi_ut_print_string(obj_desc->string.pointer,
@@ -834,16 +827,6 @@ static void acpi_ex_out_pointer(char *title, void *value)
 	acpi_os_printf("%20s : %p\n", title, value);
 }
 
-static 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_namespace_node
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index 9ea9c3a67ca9..2d88a3d8d1ad 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index 40f0bee6faa5..65a48b6170ee 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -257,14 +257,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
-			      " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
+			      " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\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)));
+			      field_datum_byte_offset, (void *)address));
 
 	/* Invoke the appropriate address_space/op_region handler */
 
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index bd98aab017cf..f13d1cec2d6d 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index bf90f04f2c60..5101bad5baf8 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acinterp.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exmutex")
@@ -150,7 +151,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Sanity check -- we must have a valid thread ID */
+	/* Sanity check: we must have a valid thread ID */
 
 	if (!walk_state->thread) {
 		ACPI_ERROR((AE_INFO,
@@ -174,24 +175,28 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
 	/* 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.os_mutex == ACPI_GLOBAL_LOCK)) {
+		if (obj_desc->mutex.owner_thread->thread_id ==
+		    walk_state->thread->thread_id) {
 			/*
-			 * The mutex is already owned by this thread,
-			 * just increment the acquisition depth
+			 * 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 */
+	/* Acquire the mutex, wait if necessary. Special case for Global Lock */
+
+	if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
+		status =
+		    acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
+	} else {
+		status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
+						   (u16) time_desc->integer.
+						   value);
+	}
 
-	status = acpi_ex_system_acquire_mutex(time_desc, obj_desc);
 	if (ACPI_FAILURE(status)) {
 
 		/* Includes failure from a timeout on time_desc */
@@ -211,7 +216,6 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
 	/* 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);
 }
 
@@ -232,7 +236,7 @@ acpi_status
 acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 		      struct acpi_walk_state *walk_state)
 {
-	acpi_status status;
+	acpi_status status = AE_OK;
 
 	ACPI_FUNCTION_TRACE(ex_release_mutex);
 
@@ -249,7 +253,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 		return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
 	}
 
-	/* Sanity check -- we must have a valid thread ID */
+	/* Sanity check: we must have a valid thread ID */
 
 	if (!walk_state->thread) {
 		ACPI_ERROR((AE_INFO,
@@ -264,7 +268,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 	 */
 	if ((obj_desc->mutex.owner_thread->thread_id !=
 	     walk_state->thread->thread_id)
-	    && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) {
+	    && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
 		ACPI_ERROR((AE_INFO,
 			    "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
 			    (unsigned long)walk_state->thread->thread_id,
@@ -274,8 +278,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 	}
 
 	/*
-	 * The sync level of the mutex must be less than or
-	 * equal to the current sync level
+	 * 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_ERROR((AE_INFO,
@@ -298,11 +302,15 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 
 	acpi_ex_unlink_mutex(obj_desc);
 
-	/* Release the mutex */
+	/* Release the mutex, special case for Global Lock */
 
-	status = acpi_ex_system_release_mutex(obj_desc);
+	if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
+		status = acpi_ev_release_global_lock();
+	} else {
+		acpi_os_release_mutex(obj_desc->mutex.os_mutex);
+	}
 
-	/* Update the mutex and walk state, restore sync_level before acquire */
+	/* Update the mutex and restore sync_level */
 
 	obj_desc->mutex.owner_thread = NULL;
 	walk_state->thread->current_sync_level =
@@ -321,39 +329,49 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
  *
  * DESCRIPTION: Release all mutexes held by this thread
  *
+ * NOTE: This function is called as the thread is exiting the interpreter.
+ * Mutexes are not released when an individual control method is exited, but
+ * only when the parent thread actually exits the interpreter. This allows one
+ * method to acquire a mutex, and a different method to release it, as long as
+ * this is performed underneath a single parent control method.
+ *
  ******************************************************************************/
 
 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;
+	union acpi_operand_object *obj_desc;
 
 	ACPI_FUNCTION_ENTRY();
 
 	/* Traverse the list of owned mutexes, releasing each one */
 
 	while (next) {
-		this = next;
-		next = this->mutex.next;
+		obj_desc = next;
+		next = obj_desc->mutex.next;
+
+		obj_desc->mutex.prev = NULL;
+		obj_desc->mutex.next = NULL;
+		obj_desc->mutex.acquisition_depth = 0;
+
+		/* Release the mutex, special case for Global Lock */
 
-		this->mutex.acquisition_depth = 1;
-		this->mutex.prev = NULL;
-		this->mutex.next = NULL;
+		if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
 
-		/* Release the mutex */
+			/* Ignore errors */
 
-		status = acpi_ex_system_release_mutex(this);
-		if (ACPI_FAILURE(status)) {
-			continue;
+			(void)acpi_ev_release_global_lock();
+		} else {
+			acpi_os_release_mutex(obj_desc->mutex.os_mutex);
 		}
 
 		/* Mark mutex unowned */
 
-		this->mutex.owner_thread = NULL;
+		obj_desc->mutex.owner_thread = NULL;
 
 		/* Update Thread sync_level (Last mutex is the important one) */
 
-		thread->current_sync_level = this->mutex.original_sync_level;
+		thread->current_sync_level =
+		    obj_desc->mutex.original_sync_level;
 	}
 }
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
index d3d70364626c..1ee4fb1175c6 100644
--- a/drivers/acpi/executer/exnames.c
+++ b/drivers/acpi/executer/exnames.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 6374d8be88e0..252f10acbbcc 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -104,9 +104,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
 			status = AE_NO_MEMORY;
 			goto cleanup;
 		}
-#if ACPI_MACHINE_WIDTH != 16
 		return_desc->integer.value = acpi_os_get_timer();
-#endif
 		break;
 
 	default:		/*  Unknown opcode  */
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 7d2cbc113160..17e652e65379 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
index e2d945dfd509..7fe67cf82cee 100644
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
index f0c0ba6eb408..bd80a9cb3d65 100644
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
index 44d064f427b9..a6696621ff1b 100644
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 3cc97ba48b36..2e9ce94798c7 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -155,16 +155,15 @@ acpi_ex_system_memory_space_handler(u32 function,
 
 		/* 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)) {
+		mem_info->mapped_logical_address =
+		    acpi_os_map_memory((acpi_native_uint) address, window_size);
+		if (!mem_info->mapped_logical_address) {
 			ACPI_ERROR((AE_INFO,
 				    "Could not map memory at %8.8X%8.8X, size %X",
 				    ACPI_FORMAT_UINT64(address),
 				    (u32) window_size));
 			mem_info->mapped_length = 0;
-			return_ACPI_STATUS(status);
+			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
 		/* Save the physical address and mapping size */
@@ -210,11 +209,10 @@ acpi_ex_system_memory_space_handler(u32 function,
 			*value = (acpi_integer) ACPI_GET32(logical_addr_ptr);
 			break;
 
-#if ACPI_MACHINE_WIDTH != 16
 		case 64:
 			*value = (acpi_integer) ACPI_GET64(logical_addr_ptr);
 			break;
-#endif
+
 		default:
 			/* bit_width was already validated */
 			break;
@@ -236,11 +234,9 @@ acpi_ex_system_memory_space_handler(u32 function,
 			ACPI_SET32(logical_addr_ptr) = (u32) * value;
 			break;
 
-#if ACPI_MACHINE_WIDTH != 16
 		case 64:
 			ACPI_SET64(logical_addr_ptr) = (u64) * value;
 			break;
-#endif
 
 		default:
 			/* bit_width was already validated */
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
index 3089b05a1368..2b3a01cc4929 100644
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index 6499de878017..6c64e55dab0e 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -141,7 +141,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 	acpi_status status = AE_OK;
 	union acpi_operand_object *stack_desc;
 	void *temp_node;
-	union acpi_operand_object *obj_desc;
+	union acpi_operand_object *obj_desc = NULL;
 	u16 opcode;
 
 	ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
@@ -299,8 +299,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 		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:
@@ -314,6 +312,10 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 		status =
 		    acpi_ex_read_data_from_field(walk_state, stack_desc,
 						 &obj_desc);
+
+		/* Remove a reference to the original operand, then override */
+
+		acpi_ut_remove_reference(*stack_ptr);
 		*stack_ptr = (void *)obj_desc;
 		break;
 
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index 4c93d0972333..ba761862a599 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -611,22 +611,20 @@ acpi_ex_resolve_operands(u16 opcode,
 			}
 			goto next_operand;
 
-		case ARGI_REGION_OR_FIELD:
+		case ARGI_REGION_OR_BUFFER:	/* Used by Load() only */
 
-			/* Need an operand of type REGION or a FIELD in a region */
+			/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
 
 			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			case ACPI_TYPE_BUFFER:
 			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_ERROR((AE_INFO,
-					    "Needed [Region/RegionField], found [%s] %p",
+					    "Needed [Region/Buffer], found [%s] %p",
 					    acpi_ut_get_object_type_name
 					    (obj_desc), obj_desc));
 
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index 0456405ba019..f4b69a637820 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index 591aaf0e18b3..1d622c625c64 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index 99ebe5adfcda..8233d40178ee 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 28aef3e69ecc..9460baff3032 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,6 @@ ACPI_MODULE_NAME("exsystem")
 acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 {
 	acpi_status status;
-	acpi_status status2;
 
 	ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
 
@@ -79,7 +78,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 
 		/* We must wait, so unlock the interpreter */
 
-		acpi_ex_exit_interpreter();
+		acpi_ex_relinquish_interpreter();
 
 		status = acpi_os_wait_semaphore(semaphore, 1, timeout);
 
@@ -89,13 +88,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 
 		/* Reacquire the interpreter */
 
-		status2 = acpi_ex_enter_interpreter();
-		if (ACPI_FAILURE(status2)) {
-
-			/* Report fatal error, could not acquire interpreter */
-
-			return_ACPI_STATUS(status2);
-		}
+		acpi_ex_reacquire_interpreter();
 	}
 
 	return_ACPI_STATUS(status);
@@ -119,7 +112,6 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 {
 	acpi_status status;
-	acpi_status status2;
 
 	ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
 
@@ -132,7 +124,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 
 		/* We must wait, so unlock the interpreter */
 
-		acpi_ex_exit_interpreter();
+		acpi_ex_relinquish_interpreter();
 
 		status = acpi_os_acquire_mutex(mutex, timeout);
 
@@ -142,13 +134,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 
 		/* Reacquire the interpreter */
 
-		status2 = acpi_ex_enter_interpreter();
-		if (ACPI_FAILURE(status2)) {
-
-			/* Report fatal error, could not acquire interpreter */
-
-			return_ACPI_STATUS(status2);
-		}
+		acpi_ex_reacquire_interpreter();
 	}
 
 	return_ACPI_STATUS(status);
@@ -209,96 +195,18 @@ acpi_status acpi_ex_system_do_stall(u32 how_long)
 
 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_ex_relinquish_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       - Maximum time to wait for the mutex
- *              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.os_mutex == ACPI_GLOBAL_LOCK) {
-		status =
-		    acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
-		return_ACPI_STATUS(status);
-	}
-
-	status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
-					   (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.os_mutex == ACPI_GLOBAL_LOCK) {
-		status = acpi_ev_release_global_lock();
-		return_ACPI_STATUS(status);
-	}
-
-	acpi_os_release_mutex(obj_desc->mutex.os_mutex);
-	return_ACPI_STATUS(AE_OK);
+	acpi_ex_reacquire_interpreter();
+	return (AE_OK);
 }
 
 /*******************************************************************************
@@ -314,7 +222,7 @@ acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc)
  *
  ******************************************************************************/
 
-acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc)
+acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
 {
 	acpi_status status = AE_OK;
 
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 982c8b65876f..6b0aeccbb69b 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,14 +76,15 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base);
  *
  * PARAMETERS:  None
  *
- * RETURN:      Status
+ * RETURN:      None
  *
- * DESCRIPTION: Enter the interpreter execution region.  Failure to enter
- *              the interpreter region is a fatal system error
+ * DESCRIPTION: Enter the interpreter execution region. Failure to enter
+ *              the interpreter region is a fatal system error. Used in
+ *              conjunction with exit_interpreter.
  *
  ******************************************************************************/
 
-acpi_status acpi_ex_enter_interpreter(void)
+void acpi_ex_enter_interpreter(void)
 {
 	acpi_status status;
 
@@ -91,31 +92,55 @@ acpi_status acpi_ex_enter_interpreter(void)
 
 	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
 	if (ACPI_FAILURE(status)) {
-		ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex"));
+		ACPI_ERROR((AE_INFO,
+			    "Could not acquire AML Interpreter mutex"));
 	}
 
-	return_ACPI_STATUS(status);
+	return_VOID;
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ex_exit_interpreter
+ * FUNCTION:    acpi_ex_reacquire_interpreter
  *
  * PARAMETERS:  None
  *
  * RETURN:      None
  *
- * DESCRIPTION: Exit the interpreter execution region
+ * DESCRIPTION: Reacquire the interpreter execution region from within the
+ *              interpreter code. Failure to enter the interpreter region is a
+ *              fatal system error. Used in  conjuction with
+ *              relinquish_interpreter
+ *
+ ******************************************************************************/
+
+void acpi_ex_reacquire_interpreter(void)
+{
+	ACPI_FUNCTION_TRACE(ex_reacquire_interpreter);
+
+	/*
+	 * If the global serialized flag is set, do not release the interpreter,
+	 * since it was not actually released by acpi_ex_relinquish_interpreter.
+	 * This forces the interpreter to be single threaded.
+	 */
+	if (!acpi_gbl_all_methods_serialized) {
+		acpi_ex_enter_interpreter();
+	}
+
+	return_VOID;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_exit_interpreter
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
  *
- * 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
+ * DESCRIPTION: Exit the interpreter execution region. This is the top level
+ *              routine used to exit the interpreter when all processing has
+ *              been completed.
  *
  ******************************************************************************/
 
@@ -127,7 +152,46 @@ void acpi_ex_exit_interpreter(void)
 
 	status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
 	if (ACPI_FAILURE(status)) {
-		ACPI_ERROR((AE_INFO, "Could not release interpreter mutex"));
+		ACPI_ERROR((AE_INFO,
+			    "Could not release AML Interpreter mutex"));
+	}
+
+	return_VOID;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_relinquish_interpreter
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Exit the interpreter execution region, from within the
+ *              interpreter - before attempting an operation that will possibly
+ *              block the running thread.
+ *
+ * Cases where the interpreter is unlocked internally
+ *      1) Method to be blocked on a Sleep() AML opcode
+ *      2) Method to be blocked on an Acquire() AML opcode
+ *      3) Method to be blocked on a Wait() AML opcode
+ *      4) Method to be blocked to acquire the global lock
+ *      5) Method to be blocked waiting to execute a serialized control method
+ *          that is currently executing
+ *      6) About to invoke a user-installed opregion handler
+ *
+ ******************************************************************************/
+
+void acpi_ex_relinquish_interpreter(void)
+{
+	ACPI_FUNCTION_TRACE(ex_relinquish_interpreter);
+
+	/*
+	 * If the global serialized flag is set, do not release the interpreter.
+	 * This forces the interpreter to be single threaded.
+	 */
+	if (!acpi_gbl_all_methods_serialized) {
+		acpi_ex_exit_interpreter();
 	}
 
 	return_VOID;
@@ -141,8 +205,8 @@ void acpi_ex_exit_interpreter(void)
  *
  * RETURN:      none
  *
- * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
- *              belongs to a 32-bit ACPI table.
+ * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
+ *              32-bit, as determined by the revision of the DSDT.
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
index de50fab2a910..6031ca13dd2f 100644
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,41 +49,6 @@ ACPI_MODULE_NAME("hwacpi")
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_hw_initialize
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initialize and validate the various ACPI registers defined in
- *              the FADT.
- *
- ******************************************************************************/
-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_ERROR((AE_INFO, "No FADT is present"));
-		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
@@ -93,7 +58,6 @@ acpi_status acpi_hw_initialize(void)
  * DESCRIPTION: Transitions the system into the requested mode.
  *
  ******************************************************************************/
-
 acpi_status acpi_hw_set_mode(u32 mode)
 {
 
@@ -106,7 +70,7 @@ acpi_status acpi_hw_set_mode(u32 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) {
+	if (!acpi_gbl_FADT.smi_command) {
 		ACPI_ERROR((AE_INFO,
 			    "No SMI_CMD in FADT, mode transition failed"));
 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
@@ -119,7 +83,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
 	 * 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) {
+	if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
 		ACPI_ERROR((AE_INFO,
 			    "No ACPI mode transition supported in this system (enable/disable both zero)"));
 		return_ACPI_STATUS(AE_OK);
@@ -130,9 +94,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
 
 		/* 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);
+		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+					    (u32) acpi_gbl_FADT.acpi_enable, 8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Attempting to enable ACPI mode\n"));
 		break;
@@ -143,8 +106,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
 		 * 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,
+		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+					    (u32) acpi_gbl_FADT.acpi_disable,
 					    8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Attempting to enable Legacy (non-ACPI) mode\n"));
@@ -204,12 +167,11 @@ u32 acpi_hw_get_mode(void)
 	 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
 	 * system does not support mode transition.
 	 */
-	if (!acpi_gbl_FADT->smi_cmd) {
+	if (!acpi_gbl_FADT.smi_command) {
 		return_UINT32(ACPI_SYS_MODE_ACPI);
 	}
 
-	status =
-	    acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK);
+	status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
 	if (ACPI_FAILURE(status)) {
 		return_UINT32(ACPI_SYS_MODE_LEGACY);
 	}
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 608a3a60ee11..117a05cadaaa 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -105,14 +105,20 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info)
 acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
 {
 	acpi_status status;
+	u8 register_bit;
 
 	ACPI_FUNCTION_ENTRY();
 
+	register_bit = (u8)
+	    (1 <<
+	     (gpe_event_info->gpe_number -
+	      gpe_event_info->register_info->base_gpe_number));
+
 	/*
 	 * Write a one to the appropriate bit in the status register to
 	 * clear this GPE.
 	 */
-	status = acpi_hw_low_level_write(8, gpe_event_info->register_bit,
+	status = acpi_hw_low_level_write(8, register_bit,
 					 &gpe_event_info->register_info->
 					 status_address);
 
@@ -155,7 +161,10 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
 
 	/* Get the register bitmask for this GPE */
 
-	register_bit = gpe_event_info->register_bit;
+	register_bit = (u8)
+	    (1 <<
+	     (gpe_event_info->gpe_number -
+	      gpe_event_info->register_info->base_gpe_number));
 
 	/* GPE currently enabled? (enabled for runtime?) */
 
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index fa58c1edce1e..1d371fa663f2 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -7,7 +7,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,17 +54,15 @@ ACPI_MODULE_NAME("hwregs")
  *
  * FUNCTION:    acpi_hw_clear_acpi_status
  *
- * PARAMETERS:  Flags           - Lock the hardware or not
+ * PARAMETERS:  None
  *
- * RETURN:      none
+ * RETURN:      None
  *
  * DESCRIPTION: Clears all fixed and general purpose status bits
  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
- * NOTE: TBD: Flags parameter is obsolete, to be removed
- *
  ******************************************************************************/
-acpi_status acpi_hw_clear_acpi_status(u32 flags)
+acpi_status acpi_hw_clear_acpi_status(void)
 {
 	acpi_status status;
 	acpi_cpu_flags lock_flags = 0;
@@ -73,7 +71,7 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags)
 
 	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));
+			  (u16) acpi_gbl_FADT.xpm1a_event_block.address));
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
@@ -86,10 +84,10 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags)
 
 	/* Clear the fixed events */
 
-	if (acpi_gbl_FADT->xpm1b_evt_blk.address) {
+	if (acpi_gbl_FADT.xpm1b_event_block.address) {
 		status =
 		    acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS,
-					    &acpi_gbl_FADT->xpm1b_evt_blk);
+					    &acpi_gbl_FADT.xpm1b_event_block);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
@@ -253,18 +251,15 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
  *
  * 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.
  *
- * NOTE: TBD: Flags parameter is obsolete, to be removed
- *
  ******************************************************************************/
 
-acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags)
+acpi_status acpi_get_register(u32 register_id, u32 * return_value)
 {
 	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
@@ -312,16 +307,13 @@ ACPI_EXPORT_SYMBOL(acpi_get_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.
  *
- * NOTE: TBD: Flags parameter is obsolete, to be removed
- *
  ******************************************************************************/
-acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
+acpi_status acpi_set_register(u32 register_id, u32 value)
 {
 	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
@@ -422,8 +414,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
 		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_FORMAT_UINT64(acpi_gbl_FADT.
+						     xpm2_control_block.
+						     address)));
 
 		ACPI_REGISTER_INSERT_VALUE(register_value,
 					   bit_reg_info->bit_position,
@@ -433,8 +426,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
 		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)));
+				  ACPI_FORMAT_UINT64(acpi_gbl_FADT.
+						     xpm2_control_block.
+						     address)));
 
 		status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
 						ACPI_REGISTER_PM2_CONTROL,
@@ -495,7 +489,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
 
 		status =
 		    acpi_hw_low_level_read(16, &value1,
-					   &acpi_gbl_FADT->xpm1a_evt_blk);
+					   &acpi_gbl_FADT.xpm1a_event_block);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
@@ -504,7 +498,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
 
 		status =
 		    acpi_hw_low_level_read(16, &value2,
-					   &acpi_gbl_FADT->xpm1b_evt_blk);
+					   &acpi_gbl_FADT.xpm1b_event_block);
 		value1 |= value2;
 		break;
 
@@ -527,14 +521,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
 
 		status =
 		    acpi_hw_low_level_read(16, &value1,
-					   &acpi_gbl_FADT->xpm1a_cnt_blk);
+					   &acpi_gbl_FADT.xpm1a_control_block);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
 
 		status =
 		    acpi_hw_low_level_read(16, &value2,
-					   &acpi_gbl_FADT->xpm1b_cnt_blk);
+					   &acpi_gbl_FADT.xpm1b_control_block);
 		value1 |= value2;
 		break;
 
@@ -542,19 +536,20 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
 
 		status =
 		    acpi_hw_low_level_read(8, &value1,
-					   &acpi_gbl_FADT->xpm2_cnt_blk);
+					   &acpi_gbl_FADT.xpm2_control_block);
 		break;
 
 	case ACPI_REGISTER_PM_TIMER:	/* 32-bit access */
 
 		status =
 		    acpi_hw_low_level_read(32, &value1,
-					   &acpi_gbl_FADT->xpm_tmr_blk);
+					   &acpi_gbl_FADT.xpm_timer_block);
 		break;
 
 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:	/* 8-bit access */
 
-		status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8);
+		status =
+		    acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
 		break;
 
 	default:
@@ -635,7 +630,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
 
 		status =
 		    acpi_hw_low_level_write(16, value,
-					    &acpi_gbl_FADT->xpm1a_evt_blk);
+					    &acpi_gbl_FADT.xpm1a_event_block);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
@@ -644,7 +639,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
 
 		status =
 		    acpi_hw_low_level_write(16, value,
-					    &acpi_gbl_FADT->xpm1b_evt_blk);
+					    &acpi_gbl_FADT.xpm1b_event_block);
 		break;
 
 	case ACPI_REGISTER_PM1_ENABLE:	/* 16-bit access */
@@ -682,49 +677,50 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
 
 		status =
 		    acpi_hw_low_level_write(16, value,
-					    &acpi_gbl_FADT->xpm1a_cnt_blk);
+					    &acpi_gbl_FADT.xpm1a_control_block);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
 
 		status =
 		    acpi_hw_low_level_write(16, value,
-					    &acpi_gbl_FADT->xpm1b_cnt_blk);
+					    &acpi_gbl_FADT.xpm1b_control_block);
 		break;
 
 	case ACPI_REGISTER_PM1A_CONTROL:	/* 16-bit access */
 
 		status =
 		    acpi_hw_low_level_write(16, value,
-					    &acpi_gbl_FADT->xpm1a_cnt_blk);
+					    &acpi_gbl_FADT.xpm1a_control_block);
 		break;
 
 	case ACPI_REGISTER_PM1B_CONTROL:	/* 16-bit access */
 
 		status =
 		    acpi_hw_low_level_write(16, value,
-					    &acpi_gbl_FADT->xpm1b_cnt_blk);
+					    &acpi_gbl_FADT.xpm1b_control_block);
 		break;
 
 	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
 
 		status =
 		    acpi_hw_low_level_write(8, value,
-					    &acpi_gbl_FADT->xpm2_cnt_blk);
+					    &acpi_gbl_FADT.xpm2_control_block);
 		break;
 
 	case ACPI_REGISTER_PM_TIMER:	/* 32-bit access */
 
 		status =
 		    acpi_hw_low_level_write(32, value,
-					    &acpi_gbl_FADT->xpm_tmr_blk);
+					    &acpi_gbl_FADT.xpm_timer_block);
 		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);
+		status =
+		    acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
 		break;
 
 	default:
@@ -783,7 +779,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
 	 * Two address spaces supported: Memory or IO.
 	 * PCI_Config is not supported here because the GAS struct is insufficient
 	 */
-	switch (reg->address_space_id) {
+	switch (reg->space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
 		status = acpi_os_read_memory((acpi_physical_address) address,
@@ -792,22 +788,20 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		status = acpi_os_read_port((acpi_io_address) address,
-					   value, width);
+		status =
+		    acpi_os_read_port((acpi_io_address) address, value, width);
 		break;
 
 	default:
 		ACPI_ERROR((AE_INFO,
-			    "Unsupported address space: %X",
-			    reg->address_space_id));
+			    "Unsupported address space: %X", reg->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)));
+			  *value, width, ACPI_FORMAT_UINT64(address),
+			  acpi_ut_get_region_name(reg->space_id)));
 
 	return (status);
 }
@@ -854,7 +848,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
 	 * Two address spaces supported: Memory or IO.
 	 * PCI_Config is not supported here because the GAS struct is insufficient
 	 */
-	switch (reg->address_space_id) {
+	switch (reg->space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
 		status = acpi_os_write_memory((acpi_physical_address) address,
@@ -863,22 +857,20 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		status = acpi_os_write_port((acpi_io_address) address,
-					    value, width);
+		status = acpi_os_write_port((acpi_io_address) address, value,
+					    width);
 		break;
 
 	default:
 		ACPI_ERROR((AE_INFO,
-			    "Unsupported address space: %X",
-			    reg->address_space_id));
+			    "Unsupported address space: %X", reg->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)));
+			  value, width, ACPI_FORMAT_UINT64(address),
+			  acpi_ut_get_region_name(reg->space_id)));
 
 	return (status);
 }
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 8bb43cae60c2..57901ca3ade9 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,7 @@
  */
 
 #include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwsleep")
@@ -62,17 +63,32 @@ ACPI_MODULE_NAME("hwsleep")
 acpi_status
 acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
 {
+	struct acpi_table_facs *facs;
+	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
 
+	/* Get the FACS */
+
+	status =
+	    acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
+				    (struct acpi_table_header **)&facs);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	/* 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;
+	if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
+		/*
+		 * ACPI 1.0 FACS or short table or optional X_ field is zero
+		 */
+		facs->firmware_waking_vector = (u32) physical_address;
 	} else {
-		*acpi_gbl_common_fACS.firmware_waking_vector = physical_address;
+		/*
+		 * ACPI 2.0 FACS with valid X_ field
+		 */
+		facs->xfirmware_waking_vector = physical_address;
 	}
 
 	return_ACPI_STATUS(AE_OK);
@@ -97,6 +113,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
 acpi_status
 acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
 {
+	struct acpi_table_facs *facs;
+	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector);
 
@@ -104,16 +122,29 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
+	/* Get the FACS */
+
+	status =
+	    acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
+				    (struct acpi_table_header **)&facs);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	/* 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));
+	if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
+		/*
+		 * ACPI 1.0 FACS or short table or optional X_ field is zero
+		 */
+		*physical_address =
+		    (acpi_physical_address) facs->firmware_waking_vector;
 	} else {
+		/*
+		 * ACPI 2.0 FACS with valid X_ field
+		 */
 		*physical_address =
-		    *acpi_gbl_common_fACS.firmware_waking_vector;
+		    (acpi_physical_address) facs->xfirmware_waking_vector;
 	}
 
 	return_ACPI_STATUS(AE_OK);
@@ -246,15 +277,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 
 	/* Clear wake status */
 
-	status =
-	    acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
 	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);
+	status = acpi_hw_clear_acpi_status();
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -367,8 +397,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 	/* Wait until we enter sleep state */
 
 	do {
-		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value,
-					   ACPI_MTX_DO_NOT_LOCK);
+		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -401,13 +430,12 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
 
 	ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
 
-	status =
-	    acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
+	status = acpi_hw_clear_acpi_status();
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -429,13 +457,12 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd,
-				    (u32) acpi_gbl_FADT->S4bios_req, 8);
+	status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+				    (u32) acpi_gbl_FADT.S4bios_request, 8);
 
 	do {
 		acpi_os_stall(1000);
-		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value,
-					   ACPI_MTX_DO_NOT_LOCK);
+		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -568,13 +595,11 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
 
 	(void)
 	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1,
-			      ACPI_MTX_DO_NOT_LOCK);
+			      [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
 
 	(void)
 	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].status_register_id, 1,
-			      ACPI_MTX_DO_NOT_LOCK);
+			      [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
 
 	arg.integer.value = ACPI_SST_WORKING;
 	status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
index c4ec47c939fd..c32eab696acd 100644
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	if (acpi_gbl_FADT->tmr_val_ext == 0) {
+	if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
 		*resolution = 24;
 	} else {
 		*resolution = 32;
@@ -98,7 +98,8 @@ acpi_status acpi_get_timer(u32 * ticks)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk);
+	status =
+	    acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block);
 
 	return_ACPI_STATUS(status);
 }
@@ -153,7 +154,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
 	if (start_ticks < end_ticks) {
 		delta_ticks = end_ticks - start_ticks;
 	} else if (start_ticks > end_ticks) {
-		if (acpi_gbl_FADT->tmr_val_ext == 0) {
+		if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
 
 			/* 24-bit Timer */
 
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
index 2e17ec75af03..b61107b05262 100644
--- a/drivers/acpi/motherboard.c
+++ b/drivers/acpi/motherboard.c
@@ -134,41 +134,41 @@ static void __init acpi_request_region (struct acpi_generic_address *addr,
 	if (!addr->address || !length)
 		return;
 
-	if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO)
+	if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
 		request_region(addr->address, length, desc);
-	else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+	else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 		request_mem_region(addr->address, length, desc);
 }
 
 static void __init acpi_reserve_resources(void)
 {
-	acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk,
-			       acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK");
+	acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block,
+			       acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK");
 
-	acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk,
-			       acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK");
+	acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block,
+			       acpi_gbl_FADT.pm1_event_length, "ACPI PM1b_EVT_BLK");
 
-	acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk,
-			       acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK");
+	acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block,
+			       acpi_gbl_FADT.pm1_control_length, "ACPI PM1a_CNT_BLK");
 
-	acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk,
-			       acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK");
+	acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block,
+			       acpi_gbl_FADT.pm1_control_length, "ACPI PM1b_CNT_BLK");
 
-	if (acpi_gbl_FADT->pm_tm_len == 4)
-		acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR");
+	if (acpi_gbl_FADT.pm_timer_length == 4)
+		acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
 
-	acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk,
-			       acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK");
+	acpi_request_region(&acpi_gbl_FADT.xpm2_control_block,
+			       acpi_gbl_FADT.pm2_control_length, "ACPI PM2_CNT_BLK");
 
 	/* Length of GPE blocks must be a non-negative multiple of 2 */
 
-	if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1))
-		acpi_request_region(&acpi_gbl_FADT->xgpe0_blk,
-			       acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK");
+	if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
+		acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
+			       acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
 
-	if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1))
-		acpi_request_region(&acpi_gbl_FADT->xgpe1_blk,
-			       acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK");
+	if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
+		acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
+			       acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
 }
 
 static int __init acpi_motherboard_init(void)
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index c1c6c236df9a..57faf598bad8 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -195,31 +195,27 @@ acpi_status acpi_ns_root_initialize(void)
 				obj_desc->mutex.sync_level =
 				    (u8) (ACPI_TO_INTEGER(val) - 1);
 
-				if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
+				/* Create a mutex */
 
-					/* Create a counting semaphore for the global lock */
+				status =
+				    acpi_os_create_mutex(&obj_desc->mutex.
+							 os_mutex);
+				if (ACPI_FAILURE(status)) {
+					acpi_ut_remove_reference(obj_desc);
+					goto unlock_and_exit;
+				}
 
-					status =
-					    acpi_os_create_semaphore
-					    (ACPI_NO_UNIT_LIMIT, 1,
-					     &acpi_gbl_global_lock_semaphore);
-					if (ACPI_FAILURE(status)) {
-						acpi_ut_remove_reference
-						    (obj_desc);
-						goto unlock_and_exit;
-					}
+				/* Special case for ACPI Global Lock */
 
-					/* Mark this mutex as very special */
+				if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
+					acpi_gbl_global_lock_mutex =
+					    obj_desc->mutex.os_mutex;
 
-					obj_desc->mutex.os_mutex =
-					    ACPI_GLOBAL_LOCK;
-				} else {
-					/* Create a mutex */
+					/* Create additional counting semaphore for global lock */
 
 					status =
-					    acpi_os_create_mutex(&obj_desc->
-								 mutex.
-								 os_mutex);
+					    acpi_os_create_semaphore(1, 0,
+								     &acpi_gbl_global_lock_semaphore);
 					if (ACPI_FAILURE(status)) {
 						acpi_ut_remove_reference
 						    (obj_desc);
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index 55b407aae266..1d693d8ad2d8 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,6 +61,9 @@ ACPI_MODULE_NAME("nsalloc")
 struct acpi_namespace_node *acpi_ns_create_node(u32 name)
 {
 	struct acpi_namespace_node *node;
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+	u32 temp;
+#endif
 
 	ACPI_FUNCTION_TRACE(ns_create_node);
 
@@ -71,6 +74,15 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
 
 	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
 
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+	temp =
+	    acpi_gbl_ns_node_list->total_allocated -
+	    acpi_gbl_ns_node_list->total_freed;
+	if (temp > acpi_gbl_ns_node_list->max_occupied) {
+		acpi_gbl_ns_node_list->max_occupied = temp;
+	}
+#endif
+
 	node->name.integer = name;
 	ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED);
 	return_PTR(node);
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index d72df66aa965..1fc4f86676e1 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -205,7 +205,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
 
 		if (!acpi_ut_valid_acpi_name(this_node->name.integer)) {
 			this_node->name.integer =
-			    acpi_ut_repair_name(this_node->name.integer);
+			    acpi_ut_repair_name(this_node->name.ascii);
 
 			ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X",
 				      this_node->name.integer));
@@ -226,6 +226,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
 	obj_desc = acpi_ns_get_attached_object(this_node);
 	acpi_dbg_level = dbg_level;
 
+	/* Temp nodes are those nodes created by a control method */
+
+	if (this_node->flags & ANOBJ_TEMPORARY) {
+		acpi_os_printf("(T) ");
+	}
+
 	switch (info->display_type & ACPI_DISPLAY_MASK) {
 	case ACPI_DISPLAY_SUMMARY:
 
@@ -623,7 +629,8 @@ acpi_ns_dump_objects(acpi_object_type type,
 	info.display_type = display_type;
 
 	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
-				     ACPI_NS_WALK_NO_UNLOCK,
+				     ACPI_NS_WALK_NO_UNLOCK |
+				     ACPI_NS_WALK_TEMP_NODES,
 				     acpi_ns_dump_one_object, (void *)&info,
 				     NULL);
 }
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
index c6bf5d30fca3..5097e167939e 100644
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 4b0a4a8c9843..aa6370c67ec1 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -154,11 +154,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
 		 * 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);
-		}
-
+		acpi_ex_enter_interpreter();
 		status = acpi_ps_execute_method(info);
 		acpi_ex_exit_interpreter();
 	} else {
@@ -182,10 +178,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
 		 * resolution, we must lock it because we could access an opregion.
 		 * The opregion access code assumes that the interpreter is locked.
 		 */
-		status = acpi_ex_enter_interpreter();
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
+		acpi_ex_enter_interpreter();
 
 		/* Function has a strange interface */
 
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index aec8488c0019..326af8fc0ce7 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -213,7 +213,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
 			u32 level, void *context, void **return_value)
 {
 	acpi_object_type type;
-	acpi_status status;
+	acpi_status status = AE_OK;
 	struct acpi_init_walk_info *info =
 	    (struct acpi_init_walk_info *)context;
 	struct acpi_namespace_node *node =
@@ -267,10 +267,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
 	/*
 	 * Must lock the interpreter before executing AML code
 	 */
-	status = acpi_ex_enter_interpreter();
-	if (ACPI_FAILURE(status)) {
-		return (status);
-	}
+	acpi_ex_enter_interpreter();
 
 	/*
 	 * Each of these types can contain executable AML code within the
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index fe75d888e183..d4f9654fd20f 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,13 +44,12 @@
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acdispat.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsload")
 
 /* Local prototypes */
-static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type);
-
 #ifdef ACPI_FUTURE_IMPLEMENTATION
 acpi_status acpi_ns_unload_namespace(acpi_handle handle);
 
@@ -62,7 +61,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
  *
  * FUNCTION:    acpi_ns_load_table
  *
- * PARAMETERS:  table_desc      - Descriptor for table to be loaded
+ * PARAMETERS:  table_index     - Index for table to be loaded
  *              Node            - Owning NS node
  *
  * RETURN:      Status
@@ -72,42 +71,13 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
  ******************************************************************************/
 
 acpi_status
-acpi_ns_load_table(struct acpi_table_desc *table_desc,
+acpi_ns_load_table(acpi_native_uint table_index,
 		   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_ERROR((AE_INFO, "Null AML pointer"));
-		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_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]",
-			      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
@@ -117,15 +87,34 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
 	 * to another control method, we can't continue parsing
 	 * because we don't know how many arguments to parse next!
 	 */
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/* If table already loaded into namespace, just return */
+
+	if (acpi_tb_is_table_loaded(table_index)) {
+		status = AE_ALREADY_EXISTS;
+		goto unlock;
+	}
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "**** Loading table into namespace ****\n"));
 
-	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	status = acpi_tb_allocate_owner_id(table_index);
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+		goto unlock;
+	}
+
+	status = acpi_ns_parse_table(table_index, node->child);
+	if (ACPI_SUCCESS(status)) {
+		acpi_tb_set_table_loaded_flag(table_index, TRUE);
+	} else {
+		acpi_tb_release_owner_id(table_index);
 	}
 
-	status = acpi_ns_parse_table(table_desc, node->child);
+      unlock:
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 	if (ACPI_FAILURE(status)) {
@@ -141,7 +130,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "**** Begin Table Method Parsing and Object Initialization ****\n"));
 
-	status = acpi_ds_initialize_objects(table_desc, node);
+	status = acpi_ds_initialize_objects(table_index, node);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "**** Completed Table Method Parsing and Object Initialization ****\n"));
@@ -149,99 +138,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
 	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.
- *
- ******************************************************************************/
-
-static 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_ID_DSDT:
-
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n"));
-
-		table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_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_ID_SSDT:
-	case ACPI_TABLE_ID_PSDT:
-
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Namespace load: %d SSDT or PSDTs\n",
-				  acpi_gbl_table_lists[table_type].count));
-
-		/*
-		 * Traverse list of SSDT or PSDT tables
-		 */
-		table_desc = acpi_gbl_table_lists[table_type].next;
-		for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) {
-			/*
-			 * Only attempt to load table into namespace 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);
-}
-
+#ifdef ACPI_OBSOLETE_FUNCTIONS
 /*******************************************************************************
  *
  * FUNCTION:    acpi_load_namespace
@@ -288,6 +185,7 @@ acpi_status acpi_ns_load_namespace(void)
 
 	return_ACPI_STATUS(status);
 }
+#endif
 
 #ifdef ACPI_FUTURE_IMPLEMENTATION
 /*******************************************************************************
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index 97b8332c9746..cbd94af08cc5 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
index aabe8794b908..d9d7377bc6e6 100644
--- a/drivers/acpi/namespace/nsobject.c
+++ b/drivers/acpi/namespace/nsobject.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index 155505a4ef69..e696aa847990 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
 #include <acpi/acnamesp.h>
 #include <acpi/acparser.h>
 #include <acpi/acdispat.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsparse")
@@ -62,14 +63,24 @@ ACPI_MODULE_NAME("nsparse")
  *
  ******************************************************************************/
 acpi_status
-acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
+acpi_ns_one_complete_parse(acpi_native_uint pass_number,
+			   acpi_native_uint table_index)
 {
 	union acpi_parse_object *parse_root;
 	acpi_status status;
+	acpi_native_uint aml_length;
+	u8 *aml_start;
 	struct acpi_walk_state *walk_state;
+	struct acpi_table_header *table;
+	acpi_owner_id owner_id;
 
 	ACPI_FUNCTION_TRACE(ns_one_complete_parse);
 
+	status = acpi_tb_get_owner_id(table_index, &owner_id);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	/* Create and init a Root Node */
 
 	parse_root = acpi_ps_create_scope_op();
@@ -79,26 +90,41 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
 
 	/* Create and initialize a new walk state */
 
-	walk_state = acpi_ds_create_walk_state(table_desc->owner_id,
-					       NULL, NULL, NULL);
+	walk_state = acpi_ds_create_walk_state(owner_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);
+	status = acpi_get_table_by_index(table_index, &table);
+	if (ACPI_FAILURE(status)) {
+		acpi_ds_delete_walk_state(walk_state);
+		acpi_ps_free_op(parse_root);
+		return_ACPI_STATUS(status);
+	}
+
+	/* Table must consist of at least a complete header */
+
+	if (table->length < sizeof(struct acpi_table_header)) {
+		status = AE_BAD_HEADER;
+	} else {
+		aml_start = (u8 *) table + sizeof(struct acpi_table_header);
+		aml_length = table->length - sizeof(struct acpi_table_header);
+		status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
+					       aml_start, aml_length, NULL,
+					       (u8) pass_number);
+	}
+
 	if (ACPI_FAILURE(status)) {
 		acpi_ds_delete_walk_state(walk_state);
+		acpi_ps_delete_parse_tree(parse_root);
 		return_ACPI_STATUS(status);
 	}
 
 	/* Parse the AML */
 
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n",
-			  pass_number));
+			  (unsigned)pass_number));
 	status = acpi_ps_parse_aml(walk_state);
 
 	acpi_ps_delete_parse_tree(parse_root);
@@ -119,7 +145,7 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
  ******************************************************************************/
 
 acpi_status
-acpi_ns_parse_table(struct acpi_table_desc *table_desc,
+acpi_ns_parse_table(acpi_native_uint table_index,
 		    struct acpi_namespace_node *start_node)
 {
 	acpi_status status;
@@ -134,10 +160,10 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc,
 	 * 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..
+	 * performs another complete parse of the AML.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
-	status = acpi_ns_one_complete_parse(1, table_desc);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -152,7 +178,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc,
 	 * parse objects are all cached.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
-	status = acpi_ns_one_complete_parse(2, table_desc);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index 500e2bbcfaf7..e863be665ce8 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -321,7 +321,8 @@ acpi_ns_search_and_enter(u32 target_name,
 	 * even though there are a few bad names.
 	 */
 	if (!acpi_ut_valid_acpi_name(target_name)) {
-		target_name = acpi_ut_repair_name(target_name);
+		target_name =
+		    acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name));
 
 		/* Report warning only if in strict mode or debug mode */
 
@@ -401,6 +402,10 @@ acpi_ns_search_and_enter(u32 target_name,
 	}
 #endif
 
+	if (flags & ACPI_NS_TEMPORARY) {
+		new_node->flags |= ANOBJ_TEMPORARY;
+	}
+
 	/* Install the new object into the parent's list of children */
 
 	acpi_ns_install_node(walk_state, node, new_node, type);
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index aa4e799d9a8c..90fd059615ff 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -770,13 +770,6 @@ void acpi_ns_terminate(void)
 	}
 
 	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;
 }
 
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
index c8f6bef16ed0..94eb8f332d94 100644
--- a/drivers/acpi/namespace/nswalk.c
+++ b/drivers/acpi/namespace/nswalk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -126,7 +126,7 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type,
  * 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
+ *              Flags               - 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
@@ -153,7 +153,7 @@ acpi_status
 acpi_ns_walk_namespace(acpi_object_type type,
 		       acpi_handle start_node,
 		       u32 max_depth,
-		       u8 unlock_before_callback,
+		       u32 flags,
 		       acpi_walk_callback user_function,
 		       void *context, void **return_value)
 {
@@ -193,20 +193,34 @@ acpi_ns_walk_namespace(acpi_object_type type,
 		    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
-			 */
+
+			/* Found next child, get the type if we are not searching for ANY */
+
 			if (type != ACPI_TYPE_ANY) {
 				child_type = child_node->type;
 			}
 
-			if (child_type == type) {
+			/*
+			 * Ignore all temporary namespace nodes (created during control
+			 * method execution) unless told otherwise. These temporary nodes
+			 * can cause a race condition because they can be deleted during the
+			 * execution of the user function (if the namespace is unlocked before
+			 * invocation of the user function.) Only the debugger namespace dump
+			 * will examine the temporary nodes.
+			 */
+			if ((child_node->flags & ANOBJ_TEMPORARY) &&
+			    !(flags & ACPI_NS_WALK_TEMP_NODES)) {
+				status = AE_CTRL_DEPTH;
+			}
+
+			/* Type must match requested type */
+
+			else if (child_type == type) {
 				/*
-				 * Found a matching node, invoke the user
-				 * callback function
+				 * Found a matching node, invoke the user callback function.
+				 * Unlock the namespace if flag is set.
 				 */
-				if (unlock_before_callback) {
+				if (flags & ACPI_NS_WALK_UNLOCK) {
 					mutex_status =
 					    acpi_ut_release_mutex
 					    (ACPI_MTX_NAMESPACE);
@@ -216,10 +230,11 @@ acpi_ns_walk_namespace(acpi_object_type type,
 					}
 				}
 
-				status = user_function(child_node, level,
-						       context, return_value);
+				status =
+				    user_function(child_node, level, context,
+						  return_value);
 
-				if (unlock_before_callback) {
+				if (flags & ACPI_NS_WALK_UNLOCK) {
 					mutex_status =
 					    acpi_ut_acquire_mutex
 					    (ACPI_MTX_NAMESPACE);
@@ -251,20 +266,17 @@ acpi_ns_walk_namespace(acpi_object_type type,
 			}
 
 			/*
-			 * 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.
+			 * 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
-					 */
+
+					/* There is at least one child of this node, visit it */
+
 					level++;
 					parent_node = child_node;
 					child_node = NULL;
@@ -272,9 +284,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
 			}
 		} 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.
+			 * 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;
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index dca6799ac678..7ac6ace50059 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -170,7 +170,6 @@ acpi_evaluate_object(acpi_handle handle,
 		     struct acpi_buffer *return_buffer)
 {
 	acpi_status status;
-	acpi_status status2;
 	struct acpi_evaluate_info *info;
 	acpi_size buffer_space_needed;
 	u32 i;
@@ -329,14 +328,12 @@ acpi_evaluate_object(acpi_handle handle,
 		 * Delete the internal return object. NOTE: Interpreter must be
 		 * locked to avoid race condition.
 		 */
-		status2 = acpi_ex_enter_interpreter();
-		if (ACPI_SUCCESS(status2)) {
+		acpi_ex_enter_interpreter();
 
-			/* Remove one reference on the return object (should delete it) */
+		/* Remove one reference on the return object (should delete it) */
 
-			acpi_ut_remove_reference(info->return_object);
-			acpi_ex_exit_interpreter();
-		}
+		acpi_ut_remove_reference(info->return_object);
+		acpi_ex_exit_interpreter();
 	}
 
       cleanup:
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index 978213a6c19f..b489781b22a8 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -84,38 +84,41 @@ acpi_get_handle(acpi_handle parent,
 	/* 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);
 		}
+	}
+
+	/*
+	 * Valid cases are:
+	 * 1) Fully qualified pathname
+	 * 2) Parent + Relative pathname
+	 *
+	 * Error for <null Parent + relative path>
+	 */
+	if (acpi_ns_valid_root_prefix(pathname[0])) {
 
-		status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-		if (ACPI_FAILURE(status)) {
-			return (status);
+		/* Pathname is fully qualified (starts with '\') */
+
+		/* Special case for root-only, since we can't search for it */
+
+		if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) {
+			*ret_handle =
+			    acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
+			return (AE_OK);
 		}
-	}
+	} else if (!prefix_node) {
 
-	/* Special case for root, since we can't search for it */
+		/* Relative path with null prefix is disallowed */
 
-	if (ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH) == 0) {
-		*ret_handle =
-		    acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
-		return (AE_OK);
+		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 *  Find the Node and convert to a handle
-	 */
-	status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH,
-				  &node);
+	/* Find the Node and convert to a handle */
 
-	*ret_handle = NULL;
+	status =
+	    acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node);
 	if (ACPI_SUCCESS(status)) {
 		*ret_handle = acpi_ns_convert_entry_to_handle(node);
 	}
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index a18b1c223129..faa375887201 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index bd96a7045925..4a9faff4c01d 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -45,7 +45,7 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
 int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
 				= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
-extern int __init acpi_table_parse_madt_family(enum acpi_table_id id,
+extern int __init acpi_table_parse_madt_family(char *id,
 					       unsigned long madt_size,
 					       int entry_id,
 					       acpi_madt_entry_handler handler,
@@ -89,7 +89,7 @@ void __cpuinit acpi_unmap_pxm_to_node(int node)
 	node_clear(node, nodes_found_map);
 }
 
-void __init acpi_table_print_srat_entry(acpi_table_entry_header * header)
+void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header)
 {
 
 	ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
@@ -99,36 +99,35 @@ void __init acpi_table_print_srat_entry(acpi_table_entry_header * header)
 
 	switch (header->type) {
 
-	case ACPI_SRAT_PROCESSOR_AFFINITY:
+	case ACPI_SRAT_TYPE_CPU_AFFINITY:
 #ifdef ACPI_DEBUG_OUTPUT
 		{
-			struct acpi_table_processor_affinity *p =
-			    (struct acpi_table_processor_affinity *)header;
+			struct acpi_srat_cpu_affinity *p =
+			    (struct acpi_srat_cpu_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"));
+					  p->apic_id, p->local_sapic_eid,
+					  p->proximity_domain_lo,
+					  (p->flags & ACPI_SRAT_CPU_ENABLED)?
+					  "enabled" : "disabled"));
 		}
 #endif				/* ACPI_DEBUG_OUTPUT */
 		break;
 
-	case ACPI_SRAT_MEMORY_AFFINITY:
+	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
 #ifdef ACPI_DEBUG_OUTPUT
 		{
-			struct acpi_table_memory_affinity *p =
-			    (struct acpi_table_memory_affinity *)header;
+			struct acpi_srat_mem_affinity *p =
+			    (struct acpi_srat_mem_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,
+					  "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n",
+					  (unsigned long)p->base_address,
+					  (unsigned long)p->length,
 					  p->memory_type, p->proximity_domain,
-					  p->flags.
-					  enabled ? "enabled" : "disabled",
-					  p->flags.
-					  hot_pluggable ? " hot-pluggable" :
-					  ""));
+					  (p->flags & ACPI_SRAT_MEM_ENABLED)?
+					  "enabled" : "disabled",
+					  (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
+					  " hot-pluggable" : ""));
 		}
 #endif				/* ACPI_DEBUG_OUTPUT */
 		break;
@@ -141,18 +140,18 @@ void __init acpi_table_print_srat_entry(acpi_table_entry_header * header)
 	}
 }
 
-static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size)
+static int __init acpi_parse_slit(struct acpi_table_header *table)
 {
 	struct acpi_table_slit *slit;
 	u32 localities;
 
-	if (!phys_addr || !size)
+	if (!table)
 		return -EINVAL;
 
-	slit = (struct acpi_table_slit *)__va(phys_addr);
+	slit = (struct acpi_table_slit *)table;
 
 	/* downcast just for %llu vs %lu for i386/ia64  */
-	localities = (u32) slit->localities;
+	localities = (u32) slit->locality_count;
 
 	acpi_numa_slit_init(slit);
 
@@ -160,12 +159,12 @@ static int __init acpi_parse_slit(unsigned long phys_addr, unsigned long size)
 }
 
 static int __init
-acpi_parse_processor_affinity(acpi_table_entry_header * header,
+acpi_parse_processor_affinity(struct acpi_subtable_header * header,
 			      const unsigned long end)
 {
-	struct acpi_table_processor_affinity *processor_affinity;
+	struct acpi_srat_cpu_affinity *processor_affinity;
 
-	processor_affinity = (struct acpi_table_processor_affinity *)header;
+	processor_affinity = (struct acpi_srat_cpu_affinity *)header;
 	if (!processor_affinity)
 		return -EINVAL;
 
@@ -178,12 +177,12 @@ acpi_parse_processor_affinity(acpi_table_entry_header * header,
 }
 
 static int __init
-acpi_parse_memory_affinity(acpi_table_entry_header * header,
+acpi_parse_memory_affinity(struct acpi_subtable_header * header,
 			   const unsigned long end)
 {
-	struct acpi_table_memory_affinity *memory_affinity;
+	struct acpi_srat_mem_affinity *memory_affinity;
 
-	memory_affinity = (struct acpi_table_memory_affinity *)header;
+	memory_affinity = (struct acpi_srat_mem_affinity *)header;
 	if (!memory_affinity)
 		return -EINVAL;
 
@@ -195,23 +194,23 @@ acpi_parse_memory_affinity(acpi_table_entry_header * header,
 	return 0;
 }
 
-static int __init acpi_parse_srat(unsigned long phys_addr, unsigned long size)
+static int __init acpi_parse_srat(struct acpi_table_header *table)
 {
 	struct acpi_table_srat *srat;
 
-	if (!phys_addr || !size)
+	if (!table)
 		return -EINVAL;
 
-	srat = (struct acpi_table_srat *)__va(phys_addr);
+	srat = (struct acpi_table_srat *)table;
 
 	return 0;
 }
 
 int __init
-acpi_table_parse_srat(enum acpi_srat_entry_id id,
+acpi_table_parse_srat(enum acpi_srat_type id,
 		      acpi_madt_entry_handler handler, unsigned int max_entries)
 {
-	return acpi_table_parse_madt_family(ACPI_SRAT,
+	return acpi_table_parse_madt_family(ACPI_SIG_SRAT,
 					    sizeof(struct acpi_table_srat), id,
 					    handler, max_entries);
 }
@@ -221,17 +220,17 @@ int __init acpi_numa_init(void)
 	int result;
 
 	/* SRAT: Static Resource Affinity Table */
-	result = acpi_table_parse(ACPI_SRAT, acpi_parse_srat);
+	result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat);
 
 	if (result > 0) {
-		result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY,
+		result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_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
+		result = acpi_table_parse_srat(ACPI_SRAT_TYPE_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);
+	result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
 
 	acpi_numa_arch_fixup();
 	return 0;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 57ae1e5cde0a..a28f5b8972b4 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -36,6 +36,7 @@
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/nmi.h>
+#include <linux/acpi.h>
 #include <acpi/acpi.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
@@ -136,53 +137,43 @@ void acpi_os_vprintf(const char *fmt, va_list args)
 #endif
 }
 
-acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
+acpi_physical_address __init acpi_os_get_root_pointer(void)
 {
 	if (efi_enabled) {
-		addr->pointer_type = ACPI_PHYSICAL_POINTER;
 		if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
-			addr->pointer.physical = efi.acpi20;
+			return efi.acpi20;
 		else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
-			addr->pointer.physical = efi.acpi;
+			return efi.acpi;
 		else {
 			printk(KERN_ERR PREFIX
 			       "System description tables not found\n");
-			return AE_NOT_FOUND;
+			return 0;
 		}
-	} 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;
+	} else
+		return acpi_find_rsdp();
 }
 
-acpi_status
-acpi_os_map_memory(acpi_physical_address phys, acpi_size size,
-		   void __iomem ** virt)
+void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
 	if (phys > ULONG_MAX) {
 		printk(KERN_ERR PREFIX "Cannot map memory that high\n");
-		return AE_BAD_PARAMETER;
+		return 0;
 	}
-	/*
-	 * ioremap checks to ensure this is in reserved space
-	 */
-	*virt = ioremap((unsigned long)phys, size);
-
-	if (!*virt)
-		return AE_NO_MEMORY;
-
-	return AE_OK;
+	if (acpi_gbl_permanent_mmap)
+		/*
+		* ioremap checks to ensure this is in reserved space
+		*/
+		return ioremap((unsigned long)phys, size);
+	else
+		return __acpi_map_table((unsigned long)phys, size);
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
 void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
 {
-	iounmap(virt);
+	if (acpi_gbl_permanent_mmap) {
+		iounmap(virt);
+	}
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
@@ -254,7 +245,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
 	 * FADT. It may not be the same if an interrupt source override exists
 	 * for the SCI.
 	 */
-	gsi = acpi_fadt.sci_int;
+	gsi = acpi_gbl_FADT.sci_interrupt;
 	if (acpi_gsi_to_irq(gsi, &irq) < 0) {
 		printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
 		       gsi);
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index bf88e076c3e9..c2b9835c890b 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index e1541db3753a..773aee82fbb8 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,12 +42,11 @@
  */
 
 /*
- * 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[]
+ * Parse the AML and build an operation tree as most interpreters, (such as
+ * Perl) do. Parsing is done by hand rather than with a YACC generated parser
+ * to tightly constrain stack and dynamic memory usage. 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>
@@ -60,766 +59,679 @@ ACPI_MODULE_NAME("psloop")
 
 static u32 acpi_gbl_depth = 0;
 
+/* Local prototypes */
+
+static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
+
+static acpi_status
+acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
+		       u8 * aml_op_start,
+		       union acpi_parse_object *unnamed_op,
+		       union acpi_parse_object **op);
+
+static acpi_status
+acpi_ps_create_op(struct acpi_walk_state *walk_state,
+		  u8 * aml_op_start, union acpi_parse_object **new_op);
+
+static acpi_status
+acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
+		      u8 * aml_op_start, union acpi_parse_object *op);
+
+static acpi_status
+acpi_ps_complete_op(struct acpi_walk_state *walk_state,
+		    union acpi_parse_object **op, acpi_status status);
+
+static acpi_status
+acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
+			  union acpi_parse_object *op, acpi_status status);
+
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ps_parse_loop
+ * FUNCTION:    acpi_ps_get_aml_opcode
  *
  * PARAMETERS:  walk_state          - Current state
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
- *              a tree of ops.
+ * DESCRIPTION: Extract the next AML opcode from the input stream.
  *
  ******************************************************************************/
 
-acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
+static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
 {
-	acpi_status status = AE_OK;
-	acpi_status status2;
-	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);
+	ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
 
-	if (walk_state->descending_callback == NULL) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
+	walk_state->aml_offset =
+	    (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
+				walk_state->parser_state.aml_start);
+	walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
 
-	parser_state = &walk_state->parser_state;
-	walk_state->arg_types = 0;
+	/*
+	 * 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);
 
-#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+	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;
 
-	if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
+	case AML_CLASS_UNKNOWN:
 
-		/* We are restarting a preempted control method */
+		/* The opcode is unrecognized. Just skip unknown opcodes */
 
-		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_EXCEPTION((AE_INFO, status,
-								"Invoked method did not return a value"));
+		ACPI_ERROR((AE_INFO,
+			    "Found unknown opcode %X at AML address %p offset %X, ignoring",
+			    walk_state->opcode, walk_state->parser_state.aml,
+			    walk_state->aml_offset));
 
-					}
-					ACPI_EXCEPTION((AE_INFO, status,
-							"GetPredicate Failed"));
-					return_ACPI_STATUS(status);
-				}
+		ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128);
 
-				status =
-				    acpi_ps_next_parse_state(walk_state, op,
-							     status);
-			}
+		/* Assume one-byte bad opcode */
 
-			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) {
+		walk_state->parser_state.aml++;
+		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 
-			/* We were in the middle of an op */
+	default:
 
-			op = walk_state->prev_op;
-			walk_state->arg_types = walk_state->prev_arg_types;
-		}
+		/* Found opcode info, this is a normal opcode */
+
+		walk_state->parser_state.aml +=
+		    acpi_ps_get_opcode_size(walk_state->opcode);
+		walk_state->arg_types = walk_state->op_info->parse_args;
+		break;
 	}
-#endif
 
-	/* Iterative parsing loop, while there is more AML to process: */
+	return_ACPI_STATUS(AE_OK);
+}
 
-	while ((parser_state->aml < parser_state->aml_end) || (op)) {
-		aml_op_start = parser_state->aml;
-		if (!op) {
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_build_named_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              aml_op_start        - Begin of named Op in AML
+ *              unnamed_op          - Early Op (not a named Op)
+ *              Op                  - Returned Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse a named Op
+ *
+ ******************************************************************************/
 
-			/* Get the next opcode from the AML stream */
+static acpi_status
+acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
+		       u8 * aml_op_start,
+		       union acpi_parse_object *unnamed_op,
+		       union acpi_parse_object **op)
+{
+	acpi_status status = AE_OK;
+	union acpi_parse_object *arg = NULL;
 
-			walk_state->aml_offset =
-			    (u32) ACPI_PTR_DIFF(parser_state->aml,
-						parser_state->aml_start);
-			walk_state->opcode = acpi_ps_peek_opcode(parser_state);
+	ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_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;
+	unnamed_op->common.value.arg = NULL;
+	unnamed_op->common.aml_opcode = walk_state->opcode;
 
-			case AML_CLASS_UNKNOWN:
+	/*
+	 * 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,
+					 &(walk_state->parser_state),
+					 GET_CURRENT_ARG_TYPE(walk_state->
+							      arg_types), &arg);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
 
-				/* The opcode is unrecognized.  Just skip unknown opcodes */
+		acpi_ps_append_arg(unnamed_op, arg);
+		INCREMENT_ARG_LIST(walk_state->arg_types);
+	}
 
-				ACPI_ERROR((AE_INFO,
-					    "Found unknown opcode %X at AML address %p offset %X, ignoring",
-					    walk_state->opcode,
-					    parser_state->aml,
-					    walk_state->aml_offset));
+	/*
+	 * Make sure that we found a NAME and didn't run out of arguments
+	 */
+	if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
+		return_ACPI_STATUS(AE_AML_NO_OPERAND);
+	}
 
-				ACPI_DUMP_BUFFER(parser_state->aml, 128);
+	/* We know that this arg is a name, move to next arg */
 
-				/* Assume one-byte bad opcode */
+	INCREMENT_ARG_LIST(walk_state->arg_types);
 
-				parser_state->aml++;
-				continue;
+	/*
+	 * Find the object. This will either insert the object into
+	 * the namespace or simply look it up
+	 */
+	walk_state->op = NULL;
 
-			default:
+	status = walk_state->descending_callback(walk_state, op);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
+		return_ACPI_STATUS(status);
+	}
 
-				/* Found opcode info, this is a normal opcode */
+	if (!*op) {
+		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
+	}
 
-				parser_state->aml +=
-				    acpi_ps_get_opcode_size(walk_state->opcode);
-				walk_state->arg_types =
-				    walk_state->op_info->parse_args;
-				break;
-			}
+	status = acpi_ps_next_parse_state(walk_state, *op, status);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_CTRL_PENDING) {
+			return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
+		}
+		return_ACPI_STATUS(status);
+	}
 
-			/* Create Op structure and append to parent's argument list */
+	acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
+	acpi_gbl_depth++;
 
-			if (walk_state->op_info->flags & AML_NAMED) {
+	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;
+	}
 
-				/* Allocate a new pre_op if necessary */
+	return_ACPI_STATUS(AE_OK);
+}
 
-				if (!pre_op) {
-					pre_op =
-					    acpi_ps_alloc_op(walk_state->
-							     opcode);
-					if (!pre_op) {
-						status = AE_NO_MEMORY;
-						goto close_this_op;
-					}
-				}
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_create_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              aml_op_start        - Op start in AML
+ *              new_op              - Returned Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get Op from AML
+ *
+ ******************************************************************************/
 
-				pre_op->common.value.arg = NULL;
-				pre_op->common.aml_opcode = walk_state->opcode;
+static acpi_status
+acpi_ps_create_op(struct acpi_walk_state *walk_state,
+		  u8 * aml_op_start, union acpi_parse_object **new_op)
+{
+	acpi_status status = AE_OK;
+	union acpi_parse_object *op;
+	union acpi_parse_object *named_op = NULL;
 
-				/*
-				 * 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_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
 
-					acpi_ps_append_arg(pre_op, arg);
-					INCREMENT_ARG_LIST(walk_state->
-							   arg_types);
-				}
+	status = acpi_ps_get_aml_opcode(walk_state);
+	if (status == AE_CTRL_PARSE_CONTINUE) {
+		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
+	}
 
-				/*
-				 * 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;
-				}
+	/* Create Op structure and append to parent's argument list */
 
-				/* We know that this arg is a name, move to next arg */
+	walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
+	op = acpi_ps_alloc_op(walk_state->opcode);
+	if (!op) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
 
-				INCREMENT_ARG_LIST(walk_state->arg_types);
+	if (walk_state->op_info->flags & AML_NAMED) {
+		status =
+		    acpi_ps_build_named_op(walk_state, aml_op_start, op,
+					   &named_op);
+		acpi_ps_free_op(op);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
 
-				/*
-				 * Find the object.  This will either insert the object into
-				 * the namespace or simply look it up
-				 */
-				walk_state->op = NULL;
+		*new_op = named_op;
+		return_ACPI_STATUS(AE_OK);
+	}
 
-				status =
-				    walk_state->descending_callback(walk_state,
-								    &op);
-				if (ACPI_FAILURE(status)) {
-					ACPI_EXCEPTION((AE_INFO, status,
-							"During name lookup/catalog"));
-					goto close_this_op;
-				}
+	/* Not a named opcode, just allocate Op and append to parent */
 
-				if (!op) {
-					continue;
-				}
+	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;
+	}
 
-				status =
-				    acpi_ps_next_parse_state(walk_state, op,
-							     status);
-				if (status == AE_CTRL_PENDING) {
-					status = AE_OK;
-					goto close_this_op;
-				}
+	acpi_ps_append_arg(acpi_ps_get_parent_scope
+			   (&(walk_state->parser_state)), op);
 
-				if (ACPI_FAILURE(status)) {
-					goto close_this_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 = *new_op = 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 */
+		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_CTRL_PARSE_PENDING;
+		}
+	}
 
-				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;
-				}
+	return_ACPI_STATUS(status);
+}
 
-				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;
-				}
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_arguments
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              aml_op_start        - Op start in AML
+ *              Op                  - Current Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get arguments for passed Op.
+ *
+ ******************************************************************************/
 
-				acpi_ps_append_arg(acpi_ps_get_parent_scope
-						   (parser_state), op);
+static acpi_status
+acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
+		      u8 * aml_op_start, union acpi_parse_object *op)
+{
+	acpi_status status = AE_OK;
+	union acpi_parse_object *arg = NULL;
 
-				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;
+	ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
 
-					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;
-					}
+	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 */
 
-					if (ACPI_FAILURE(status)) {
-						goto close_this_op;
-					}
-				}
-			}
+		/* Fill in constant or string argument directly */
 
-			op->common.aml_offset = walk_state->aml_offset;
+		acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
+					    GET_CURRENT_ARG_TYPE(walk_state->
+								 arg_types),
+					    op);
+		break;
 
-			if (walk_state->op_info) {
-				ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-						  "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
-						  (u32) op->common.aml_opcode,
-						  walk_state->op_info->name, op,
-						  parser_state->aml,
-						  op->common.aml_offset));
-			}
+	case AML_INT_NAMEPATH_OP:	/* AML_NAMESTRING_ARG */
+
+		status =
+		    acpi_ps_get_next_namepath(walk_state,
+					      &(walk_state->parser_state), op,
+					      1);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
 		}
 
+		walk_state->arg_types = 0;
+		break;
+
+	default:
 		/*
-		 * Start arg_count at zero because we don't know if there are
-		 * any args yet
+		 * Op is not a constant or string, append each argument to the Op
 		 */
-		walk_state->arg_count = 0;
-
-		/* Are there any arguments that must be processed? */
-
-		if (walk_state->arg_types) {
-
-			/* 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;
+		while (GET_CURRENT_ARG_TYPE(walk_state->arg_types)
+		       && !walk_state->arg_count) {
+			walk_state->aml_offset =
+			    (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
+						walk_state->parser_state.
+						aml_start);
 
-			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,
+						 &(walk_state->parser_state),
+						 GET_CURRENT_ARG_TYPE
+						 (walk_state->arg_types), &arg);
+			if (ACPI_FAILURE(status)) {
+				return_ACPI_STATUS(status);
+			}
 
-					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);
+			}
 
-					if (arg) {
-						arg->common.aml_offset =
-						    walk_state->aml_offset;
-						acpi_ps_append_arg(op, arg);
-					}
-					INCREMENT_ARG_LIST(walk_state->
-							   arg_types);
-				}
+			INCREMENT_ARG_LIST(walk_state->arg_types);
+		}
 
-				/* Special processing for certain opcodes */
+		/* Special processing for certain opcodes */
 
-				/* TBD (remove): Temporary mechanism to disable this code if needed */
+		/* TBD (remove): Temporary mechanism to disable this code if needed */
 
 #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
 
-				if ((walk_state->pass_number <=
-				     ACPI_IMODE_LOAD_PASS1)
-				    &&
-				    ((walk_state->
-				      parse_flags & ACPI_PARSE_DISASSEMBLE) ==
-				     0)) {
-					/*
-					 * We want to skip If/Else/While constructs during Pass1
-					 * because we want to actually conditionally execute the
-					 * code during Pass2.
-					 *
-					 * Except for disassembly, where we always want to
-					 * walk the If/Else/While packages
-					 */
-					switch (op->common.aml_opcode) {
-					case AML_IF_OP:
-					case AML_ELSE_OP:
-					case AML_WHILE_OP:
-
-						ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-								  "Pass1: Skipping an If/Else/While body\n"));
-
-						/* Skip body of if/else/while in pass 1 */
-
-						parser_state->aml =
-						    parser_state->pkg_end;
-						walk_state->arg_count = 0;
-						break;
-
-					default:
-						break;
-					}
-				}
-#endif
-				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->pass_number <=
-						ACPI_IMODE_LOAD_PASS2)) {
-						/*
-						 * 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;
+		if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
+		    ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
+			/*
+			 * We want to skip If/Else/While constructs during Pass1 because we
+			 * want to actually conditionally execute the code during Pass2.
+			 *
+			 * Except for disassembly, where we always want to walk the
+			 * If/Else/While packages
+			 */
+			switch (op->common.aml_opcode) {
+			case AML_IF_OP:
+			case AML_ELSE_OP:
+			case AML_WHILE_OP:
 
-				case AML_WHILE_OP:
+				ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+						  "Pass1: Skipping an If/Else/While body\n"));
 
-					if (walk_state->control_state) {
-						walk_state->control_state->
-						    control.package_end =
-						    parser_state->pkg_end;
-					}
-					break;
+				/* Skip body of if/else/while in pass 1 */
 
-				default:
+				walk_state->parser_state.aml =
+				    walk_state->parser_state.pkg_end;
+				walk_state->arg_count = 0;
+				break;
 
-					/* No action for all other opcodes */
-					break;
-				}
+			default:
 				break;
 			}
 		}
+#endif
 
-		/* Check for arguments that need to be processed */
-
-		if (walk_state->arg_count) {
+		switch (op->common.aml_opcode) {
+		case AML_METHOD_OP:
 			/*
-			 * There are arguments (complex ones), push Op and
-			 * prepare for argument
+			 * 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
 			 */
-			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;
-		}
+			op->named.data = walk_state->parser_state.aml;
+			op->named.length = (u32)
+			    (walk_state->parser_state.pkg_end -
+			     walk_state->parser_state.aml);
 
-		/*
-		 * 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--;
-			}
+			/* Skip body of method */
 
-			if (op->common.aml_opcode == AML_REGION_OP) {
+			walk_state->parser_state.aml =
+			    walk_state->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->pass_number <=
+				ACPI_IMODE_LOAD_PASS2)) {
 				/*
-				 * 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.
+				 * Skip parsing of Buffers and Packages because we don't have
+				 * enough info in the first pass to parse them correctly.
 				 */
-				op->named.length =
-				    (u32) (parser_state->aml - op->named.data);
-			}
-		}
+				op->named.data = aml_op_start;
+				op->named.length = (u32)
+				    (walk_state->parser_state.pkg_end -
+				     aml_op_start);
 
-		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);
-		}
+				/* Skip body */
 
-		/* This op complete, notify the dispatcher */
+				walk_state->parser_state.aml =
+				    walk_state->parser_state.pkg_end;
+				walk_state->arg_count = 0;
+			}
+			break;
 
-		if (walk_state->ascending_callback != NULL) {
-			walk_state->op = op;
-			walk_state->opcode = op->common.aml_opcode;
+		case AML_WHILE_OP:
 
-			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 (walk_state->control_state) {
+				walk_state->control_state->control.package_end =
+				    walk_state->parser_state.pkg_end;
 			}
-		}
-
-	      close_this_op:
-		/*
-		 * Finished one argument of the containing scope
-		 */
-		parser_state->scope->parse_scope.arg_count--;
+			break;
 
-		/* Finished with pre_op */
+		default:
 
-		if (pre_op) {
-			acpi_ps_free_op(pre_op);
-			pre_op = NULL;
+			/* No action for all other opcodes */
+			break;
 		}
 
-		/* Close this Op (will result in parse subtree deletion) */
+		break;
+	}
 
-		status2 = acpi_ps_complete_this_op(walk_state, op);
-		if (ACPI_FAILURE(status2)) {
-			return_ACPI_STATUS(status2);
-		}
-		op = NULL;
+	return_ACPI_STATUS(AE_OK);
+}
 
-		switch (status) {
-		case AE_OK:
-			break;
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_complete_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              Op                  - Returned Op
+ *              Status              - Parse status before complete Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Complete Op
+ *
+ ******************************************************************************/
 
-		case AE_CTRL_TRANSFER:
+static acpi_status
+acpi_ps_complete_op(struct acpi_walk_state *walk_state,
+		    union acpi_parse_object **op, acpi_status status)
+{
+	acpi_status status2;
 
-			/* We are about to transfer to a called method. */
+	ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
 
-			walk_state->prev_op = op;
-			walk_state->prev_arg_types = walk_state->arg_types;
-			return_ACPI_STATUS(status);
+	/*
+	 * Finished one argument of the containing scope
+	 */
+	walk_state->parser_state.scope->parse_scope.arg_count--;
 
-		case AE_CTRL_END:
+	/* Close this Op (will result in parse subtree deletion) */
 
-			acpi_ps_pop_scope(parser_state, &op,
-					  &walk_state->arg_types,
-					  &walk_state->arg_count);
+	status2 = acpi_ps_complete_this_op(walk_state, *op);
+	if (ACPI_FAILURE(status2)) {
+		return_ACPI_STATUS(status2);
+	}
 
-			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;
+	*op = NULL;
 
-				status =
-				    walk_state->ascending_callback(walk_state);
-				status =
-				    acpi_ps_next_parse_state(walk_state, op,
-							     status);
+	switch (status) {
+	case AE_OK:
+		break;
 
-				status2 =
-				    acpi_ps_complete_this_op(walk_state, op);
-				if (ACPI_FAILURE(status2)) {
-					return_ACPI_STATUS(status2);
-				}
-				op = NULL;
-			}
-			status = AE_OK;
-			break;
+	case AE_CTRL_TRANSFER:
 
-		case AE_CTRL_BREAK:
-		case AE_CTRL_CONTINUE:
+		/* We are about to transfer to a called method */
 
-			/* Pop off scopes until we find the While */
+		walk_state->prev_op = NULL;
+		walk_state->prev_arg_types = walk_state->arg_types;
+		return_ACPI_STATUS(status);
 
-			while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
-				acpi_ps_pop_scope(parser_state, &op,
-						  &walk_state->arg_types,
-						  &walk_state->arg_count);
+	case AE_CTRL_END:
 
-				if (op->common.aml_opcode != AML_WHILE_OP) {
-					status2 =
-					    acpi_ds_result_stack_pop
-					    (walk_state);
-					if (ACPI_FAILURE(status2)) {
-						return_ACPI_STATUS(status2);
-					}
-				}
-			}
-
-			/* Close this iteration of the While loop */
+		acpi_ps_pop_scope(&(walk_state->parser_state), op,
+				  &walk_state->arg_types,
+				  &walk_state->arg_count);
 
-			walk_state->op = op;
+		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;
+			    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_next_parse_state(walk_state, *op, status);
 
-			status2 = acpi_ps_complete_this_op(walk_state, op);
+			status2 = acpi_ps_complete_this_op(walk_state, *op);
 			if (ACPI_FAILURE(status2)) {
 				return_ACPI_STATUS(status2);
 			}
-			op = NULL;
-
-			status = AE_OK;
-			break;
+		}
 
-		case AE_CTRL_TERMINATE:
+		status = AE_OK;
+		break;
 
-			status = AE_OK;
+	case AE_CTRL_BREAK:
+	case AE_CTRL_CONTINUE:
 
-			/* Clean up */
-			do {
-				if (op) {
-					status2 =
-					    acpi_ps_complete_this_op(walk_state,
-								     op);
-					if (ACPI_FAILURE(status2)) {
-						return_ACPI_STATUS(status2);
-					}
+		/* Pop off scopes until we find the While */
 
-					status2 =
-					    acpi_ds_result_stack_pop
-					    (walk_state);
-					if (ACPI_FAILURE(status2)) {
-						return_ACPI_STATUS(status2);
-					}
+		while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
+			acpi_ps_pop_scope(&(walk_state->parser_state), op,
+					  &walk_state->arg_types,
+					  &walk_state->arg_count);
 
-					acpi_ut_delete_generic_state
-					    (acpi_ut_pop_generic_state
-					     (&walk_state->control_state));
+			if ((*op)->common.aml_opcode != AML_WHILE_OP) {
+				status2 = acpi_ds_result_stack_pop(walk_state);
+				if (ACPI_FAILURE(status2)) {
+					return_ACPI_STATUS(status2);
 				}
+			}
+		}
 
-				acpi_ps_pop_scope(parser_state, &op,
-						  &walk_state->arg_types,
-						  &walk_state->arg_count);
+		/* Close this iteration of the While loop */
 
-			} while (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;
 
-			return_ACPI_STATUS(status);
+		status = walk_state->ascending_callback(walk_state);
+		status = acpi_ps_next_parse_state(walk_state, *op, status);
 
-		default:	/* All other non-AE_OK status */
+		status2 = acpi_ps_complete_this_op(walk_state, *op);
+		if (ACPI_FAILURE(status2)) {
+			return_ACPI_STATUS(status2);
+		}
 
-			do {
-				if (op) {
-					status2 =
-					    acpi_ps_complete_this_op(walk_state,
-								     op);
-					if (ACPI_FAILURE(status2)) {
-						return_ACPI_STATUS(status2);
-					}
+		status = AE_OK;
+		break;
+
+	case AE_CTRL_TERMINATE:
+
+		/* Clean up */
+		do {
+			if (*op) {
+				status2 =
+				    acpi_ps_complete_this_op(walk_state, *op);
+				if (ACPI_FAILURE(status2)) {
+					return_ACPI_STATUS(status2);
+				}
+				status2 = acpi_ds_result_stack_pop(walk_state);
+				if (ACPI_FAILURE(status2)) {
+					return_ACPI_STATUS(status2);
 				}
 
-				acpi_ps_pop_scope(parser_state, &op,
-						  &walk_state->arg_types,
-						  &walk_state->arg_count);
+				acpi_ut_delete_generic_state
+				    (acpi_ut_pop_generic_state
+				     (&walk_state->control_state));
+			}
 
-			} while (op);
+			acpi_ps_pop_scope(&(walk_state->parser_state), op,
+					  &walk_state->arg_types,
+					  &walk_state->arg_count);
 
-			/*
-			 * 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);
+		} while (*op);
+
+		return_ACPI_STATUS(AE_OK);
+
+	default:		/* All other non-AE_OK status */
+
+		do {
+			if (*op) {
+				status2 =
+				    acpi_ps_complete_this_op(walk_state, *op);
+				if (ACPI_FAILURE(status2)) {
+					return_ACPI_STATUS(status2);
+				}
 			}
-#endif
-			walk_state->prev_op = op;
-			walk_state->prev_arg_types = walk_state->arg_types;
-			return_ACPI_STATUS(status);
-		}
 
-		/* This scope complete? */
+			acpi_ps_pop_scope(&(walk_state->parser_state), op,
+					  &walk_state->arg_types,
+					  &walk_state->arg_count);
 
-		if (acpi_ps_has_completed_scope(parser_state)) {
-			acpi_ps_pop_scope(parser_state, &op,
+		} while (*op);
+
+#if 0
+		/*
+		 * TBD: Cleanup parse ops on error
+		 */
+		if (*op == NULL) {
+			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;
 		}
+#endif
+		walk_state->prev_op = NULL;
+		walk_state->prev_arg_types = walk_state->arg_types;
+		return_ACPI_STATUS(status);
+	}
 
-	}			/* while parser_state->Aml */
+	/* This scope complete? */
+
+	if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
+		acpi_ps_pop_scope(&(walk_state->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;
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_complete_final_op
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *              Op                  - Current Op
+ *              Status              - Current parse status before complete last
+ *                                    Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Complete last Op.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
+			  union acpi_parse_object *op, acpi_status status)
+{
+	acpi_status status2;
+
+	ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
 
 	/*
 	 * 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.
+	 * sequential closing braces). We want to terminate each one cleanly.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
 			  op));
@@ -838,8 +750,12 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
 				    acpi_ps_next_parse_state(walk_state, op,
 							     status);
 				if (status == AE_CTRL_PENDING) {
-					status = AE_OK;
-					goto close_this_op;
+					status =
+					    acpi_ps_complete_op(walk_state, &op,
+								AE_OK);
+					if (ACPI_FAILURE(status)) {
+						return_ACPI_STATUS(status);
+					}
 				}
 
 				if (status == AE_CTRL_TERMINATE) {
@@ -858,7 +774,9 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
 							}
 						}
 
-						acpi_ps_pop_scope(parser_state,
+						acpi_ps_pop_scope(&
+								  (walk_state->
+								   parser_state),
 								  &op,
 								  &walk_state->
 								  arg_types,
@@ -887,10 +805,252 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
 			}
 		}
 
-		acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types,
+		acpi_ps_pop_scope(&(walk_state->parser_state), &op,
+				  &walk_state->arg_types,
 				  &walk_state->arg_count);
 
 	} while (op);
 
 	return_ACPI_STATUS(status);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_parse_loop
+ *
+ * PARAMETERS:  walk_state          - Current state
+ *
+ * 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 */
+	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_EXCEPTION((AE_INFO, status,
+								"Invoked method did not return a value"));
+
+					}
+
+					ACPI_EXCEPTION((AE_INFO, status,
+							"GetPredicate Failed"));
+					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) {
+			status =
+			    acpi_ps_create_op(walk_state, aml_op_start, &op);
+			if (ACPI_FAILURE(status)) {
+				if (status == AE_CTRL_PARSE_CONTINUE) {
+					continue;
+				}
+
+				if (status == AE_CTRL_PARSE_PENDING) {
+					status = AE_OK;
+				}
+
+				status =
+				    acpi_ps_complete_op(walk_state, &op,
+							status);
+				if (ACPI_FAILURE(status)) {
+					return_ACPI_STATUS(status);
+				}
+
+				continue;
+			}
+
+			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 AmlOffset %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;
+
+		/* Are there any arguments that must be processed? */
+
+		if (walk_state->arg_types) {
+
+			/* Get arguments */
+
+			status =
+			    acpi_ps_get_arguments(walk_state, aml_op_start, op);
+			if (ACPI_FAILURE(status)) {
+				status =
+				    acpi_ps_complete_op(walk_state, &op,
+							status);
+				if (ACPI_FAILURE(status)) {
+					return_ACPI_STATUS(status);
+				}
+
+				continue;
+			}
+		}
+
+		/* 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)) {
+				status =
+				    acpi_ps_complete_op(walk_state, &op,
+							status);
+				if (ACPI_FAILURE(status)) {
+					return_ACPI_STATUS(status);
+				}
+
+				continue;
+			}
+
+			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;
+			}
+		}
+
+		status = acpi_ps_complete_op(walk_state, &op, status);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+
+	}			/* while parser_state->Aml */
+
+	status = acpi_ps_complete_final_op(walk_state, op, status);
+	return_ACPI_STATUS(status);
+}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 4bd25e32769f..16d8b6cc3c22 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index a02aa62fe1e5..5d63f48e56b5 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -540,6 +540,11 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
 
 			if ((status == AE_ALREADY_EXISTS) &&
 			    (!walk_state->method_desc->method.mutex)) {
+				ACPI_INFO((AE_INFO,
+					   "Marking method %4.4s as Serialized",
+					   walk_state->method_node->name.
+					   ascii));
+
 				/*
 				 * Method tried to create an object twice. The probable cause is
 				 * that the method cannot handle reentrancy.
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
index a3e0314de24d..77cfa4ed0cfe 100644
--- a/drivers/acpi/parser/psscope.c
+++ b/drivers/acpi/parser/psscope.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
index 0015717ef096..966e7ea2a0c4 100644
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index d405387b7414..8ca52002db55 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index a84a547a0f1b..49f9757434e4 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 5d996c1140af..94103bced75e 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,6 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info);
 
 static void acpi_ps_stop_trace(struct acpi_evaluate_info *info);
 
-static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info);
-
 static void
 acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
 
@@ -215,6 +213,8 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info)
 acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
 {
 	acpi_status status;
+	union acpi_parse_object *op;
+	struct acpi_walk_state *walk_state;
 
 	ACPI_FUNCTION_TRACE(ps_execute_method);
 
@@ -234,8 +234,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
 	}
 
 	/*
-	 * The caller "owns" the parameters, so give each one an extra
-	 * reference
+	 * The caller "owns" the parameters, so give each one an extra reference
 	 */
 	acpi_ps_update_parameter_list(info, REF_INCREMENT);
 
@@ -244,30 +243,50 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
 	acpi_ps_start_trace(info);
 
 	/*
-	 * 1) Perform the first pass parse of the method to enter any
-	 *    named objects that it creates into the namespace
+	 * Execute the method. Performs parse simultaneously
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-			  "**** Begin Method Parse **** Entry=%p obj=%p\n",
-			  info->resolved_node, info->obj_desc));
+			  "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
+			  info->resolved_node->name.ascii, info->resolved_node,
+			  info->obj_desc));
+
+	/* Create and init a Root Node */
+
+	op = acpi_ps_create_scope_op();
+	if (!op) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/* Create and initialize a new walk state */
+
+	info->pass_number = ACPI_IMODE_EXECUTE;
+	walk_state =
+	    acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
+				      NULL, NULL);
+	if (!walk_state) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
 
-	info->pass_number = 1;
-	status = acpi_ps_execute_pass(info);
+	status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
+				       info->obj_desc->method.aml_start,
+				       info->obj_desc->method.aml_length, info,
+				       info->pass_number);
 	if (ACPI_FAILURE(status)) {
+		acpi_ds_delete_walk_state(walk_state);
 		goto cleanup;
 	}
 
-	/*
-	 * 2) Execute the method. Performs second pass parse simultaneously
-	 */
-	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-			  "**** Begin Method Execution **** Entry=%p obj=%p\n",
-			  info->resolved_node, info->obj_desc));
+	/* Parse the AML */
 
-	info->pass_number = 3;
-	status = acpi_ps_execute_pass(info);
+	status = acpi_ps_parse_aml(walk_state);
+
+	/* walk_state was deleted by parse_aml */
 
       cleanup:
+	acpi_ps_delete_parse_tree(op);
+
 	/* End optional tracing */
 
 	acpi_ps_stop_trace(info);
@@ -330,62 +349,3 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
 		}
 	}
 }
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_execute_pass
- *
- * PARAMETERS:  Info            - See struct acpi_evaluate_info
- *                                (Used: pass_number, Node, and obj_desc)
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Single AML pass: Parse or Execute a control method
- *
- ******************************************************************************/
-
-static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info)
-{
-	acpi_status status;
-	union acpi_parse_object *op;
-	struct acpi_walk_state *walk_state;
-
-	ACPI_FUNCTION_TRACE(ps_execute_pass);
-
-	/* Create and init a Root Node */
-
-	op = acpi_ps_create_scope_op();
-	if (!op) {
-		return_ACPI_STATUS(AE_NO_MEMORY);
-	}
-
-	/* Create and initialize a new walk state */
-
-	walk_state =
-	    acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
-				      NULL, NULL);
-	if (!walk_state) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
-
-	status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
-				       info->obj_desc->method.aml_start,
-				       info->obj_desc->method.aml_length,
-				       info->pass_number == 1 ? NULL : info,
-				       info->pass_number);
-	if (ACPI_FAILURE(status)) {
-		acpi_ds_delete_walk_state(walk_state);
-		goto cleanup;
-	}
-
-	/* Parse the AML */
-
-	status = acpi_ps_parse_aml(walk_state);
-
-	/* Walk state was deleted by parse_aml */
-
-      cleanup:
-	acpi_ps_delete_parse_tree(op);
-	return_ACPI_STATUS(status);
-}
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 481e633bbf41..0f683c8c6fbc 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -513,7 +513,7 @@ int __init acpi_irq_penalty_init(void)
 		}
 	}
 	/* Add a penalty for the SCI */
-	acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING;
+	acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
 
 	return 0;
 }
@@ -785,7 +785,7 @@ static int irqrouter_resume(struct sys_device *dev)
 
 
 	/* Make sure SCI is enabled again (Apple firmware bug?) */
-	acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1, ACPI_MTX_DO_NOT_LOCK);
+	acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
 
 	list_for_each(node, &acpi_link.entries) {
 		link = list_entry(node, struct acpi_pci_link, node);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 5f9496d59ed6..eacf9a252019 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -375,30 +375,126 @@ static int acpi_processor_remove_fs(struct acpi_device *device)
 }
 
 /* Use the acpiid in MADT to map cpus in case of SMP */
+
 #ifndef CONFIG_SMP
-#define convert_acpiid_to_cpu(acpi_id) (-1)
+static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;}
 #else
 
+static struct acpi_table_madt *madt;
+
+static int map_lapic_id(struct acpi_subtable_header *entry,
+		 u32 acpi_id, int *apic_id)
+{
+	struct acpi_madt_local_apic *lapic =
+		(struct acpi_madt_local_apic *)entry;
+	if ((lapic->lapic_flags & ACPI_MADT_ENABLED) &&
+	    lapic->processor_id == acpi_id) {
+		*apic_id = lapic->id;
+		return 1;
+	}
+	return 0;
+}
+
+static int map_lsapic_id(struct acpi_subtable_header *entry,
+		  u32 acpi_id, int *apic_id)
+{
+	struct acpi_madt_local_sapic *lsapic =
+		(struct acpi_madt_local_sapic *)entry;
+	/* Only check enabled APICs*/
+	if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
+		/* First check against id */
+		if (lsapic->processor_id == acpi_id) {
+			*apic_id = lsapic->id;
+			return 1;
+		/* Check against optional uid */
+		} else if (entry->length >= 16 &&
+			lsapic->uid == acpi_id) {
+			*apic_id = lsapic->uid;
+			return 1;
+		}
+	}
+	return 0;
+}
+
 #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 int convert_acpiid_to_cpu(u8 acpi_id)
+static int map_madt_entry(u32 acpi_id)
+{
+	unsigned long madt_end, entry;
+	int apic_id = -1;
+
+	if (!madt)
+		return apic_id;
+
+	entry = (unsigned long)madt;
+	madt_end = entry + madt->header.length;
+
+	/* Parse all entries looking for a match. */
+
+	entry += sizeof(struct acpi_table_madt);
+	while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
+		struct acpi_subtable_header *header =
+			(struct acpi_subtable_header *)entry;
+		if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
+			if (map_lapic_id(header, acpi_id, &apic_id))
+				break;
+		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
+			if (map_lsapic_id(header, acpi_id, &apic_id))
+				break;
+		}
+		entry += header->length;
+	}
+	return apic_id;
+}
+
+static int map_mat_entry(acpi_handle handle, u32 acpi_id)
+{
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+	struct acpi_subtable_header *header;
+	int apic_id = -1;
+
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
+		goto exit;
+
+	if (!buffer.length || !buffer.pointer)
+		goto exit;
+
+	obj = buffer.pointer;
+	if (obj->type != ACPI_TYPE_BUFFER ||
+	    obj->buffer.length < sizeof(struct acpi_subtable_header)) {
+		goto exit;
+	}
+
+	header = (struct acpi_subtable_header *)obj->buffer.pointer;
+	if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
+		map_lapic_id(header, acpi_id, &apic_id);
+	} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
+		map_lsapic_id(header, acpi_id, &apic_id);
+	}
+
+exit:
+	if (buffer.pointer)
+		kfree(buffer.pointer);
+	return apic_id;
+}
+
+static int get_cpu_id(acpi_handle handle, u32 acpi_id)
 {
-	u16 apic_id;
 	int i;
+	int apic_id = -1;
 
-	apic_id = arch_acpiid_to_apicid[acpi_id];
-	if (apic_id == ARCH_BAD_APICID)
-		return -1;
+	apic_id = map_mat_entry(handle, acpi_id);
+	if (apic_id == -1)
+		apic_id = map_madt_entry(acpi_id);
+	if (apic_id == -1)
+		return apic_id;
 
-	for (i = 0; i < NR_CPUS; i++) {
+	for (i = 0; i < NR_CPUS; ++i) {
 		if (arch_cpu_to_apicid[i] == apic_id)
 			return i;
 	}
@@ -410,7 +506,7 @@ static int convert_acpiid_to_cpu(u8 acpi_id)
                                  Driver Interface
    -------------------------------------------------------------------------- */
 
-static int acpi_processor_get_info(struct acpi_processor *pr)
+static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
 {
 	acpi_status status = 0;
 	union acpi_object object = { 0 };
@@ -431,7 +527,7 @@ static int acpi_processor_get_info(struct acpi_processor *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) {
+	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
 		pr->flags.bm_control = 1;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Bus mastering arbitration control present\n"));
@@ -439,24 +535,35 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
 		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)) {
-		printk(KERN_ERR PREFIX "Evaluating processor object\n");
-		return -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;
+	/* Check if it is a Device with HID and UID */
+	if (has_uid) {
+		unsigned long value;
+		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
+						NULL, &value);
+		if (ACPI_FAILURE(status)) {
+			printk(KERN_ERR PREFIX "Evaluating processor _UID\n");
+			return -ENODEV;
+		}
+		pr->acpi_id = value;
+	} else {
+		/*
+		* 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)) {
+			printk(KERN_ERR PREFIX "Evaluating processor object\n");
+			return -ENODEV;
+		}
 
-	cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
+		/*
+		* 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 = get_cpu_id(pr->handle, pr->acpi_id);
 
 	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
 	if (!cpu0_initialized && (cpu_index == -1) &&
@@ -473,7 +580,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
 	 *  less than the max # of CPUs. They should be ignored _iff
 	 *  they are physically not present.
 	 */
-	if (cpu_index == -1) {
+	if (pr->id == -1) {
 		if (ACPI_FAILURE
 		    (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
 			return -ENODEV;
@@ -490,8 +597,8 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
 			    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->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
+		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
 
 		pr->pblk = object.processor.pblk_address;
 
@@ -525,7 +632,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
 
 	pr = acpi_driver_data(device);
 
-	result = acpi_processor_get_info(pr);
+	result = acpi_processor_get_info(pr, device->flags.unique_id);
 	if (result) {
 		/* Processor is physically not present */
 		return 0;
@@ -895,6 +1002,12 @@ static int __init acpi_processor_init(void)
 	memset(&processors, 0, sizeof(processors));
 	memset(&errata, 0, sizeof(errata));
 
+#ifdef CONFIG_SMP
+	if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
+				(struct acpi_table_header **)&madt)))
+		madt = 0;
+#endif
+
 	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 	if (!acpi_processor_dir)
 		return -ENOMEM;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 3f30af21574e..6c6751b1405b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -160,7 +160,7 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2)
 {
 	if (t2 >= t1)
 		return (t2 - t1);
-	else if (!acpi_fadt.tmr_val_ext)
+	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
 		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
 	else
 		return ((0xFFFFFFFF - t1) + t2);
@@ -187,8 +187,7 @@ acpi_processor_power_activate(struct acpi_processor *pr,
 		case ACPI_STATE_C3:
 			/* Disable bus master reload */
 			if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
-				acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0,
-						  ACPI_MTX_DO_NOT_LOCK);
+				acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
 			break;
 		}
 	}
@@ -198,8 +197,7 @@ acpi_processor_power_activate(struct acpi_processor *pr,
 	case ACPI_STATE_C3:
 		/* Enable bus master reload */
 		if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1,
-					  ACPI_MTX_DO_NOT_LOCK);
+			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
 		break;
 	}
 
@@ -236,7 +234,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
 		/* Dummy wait op - must do something useless after P_LVL2 read
 		   because chipsets cannot guarantee that STPCLK# signal
 		   gets asserted in time to freeze execution properly. */
-		unused = inl(acpi_fadt.xpm_tmr_blk.address);
+		unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
 	}
 }
 
@@ -291,12 +289,10 @@ static void acpi_processor_idle(void)
 
 		pr->power.bm_activity <<= diff;
 
-		acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,
-				  &bm_status, ACPI_MTX_DO_NOT_LOCK);
+		acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
 		if (bm_status) {
 			pr->power.bm_activity |= 0x1;
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,
-					  1, ACPI_MTX_DO_NOT_LOCK);
+			acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
 		}
 		/*
 		 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
@@ -338,7 +334,7 @@ static void acpi_processor_idle(void)
 	 * detection phase, to work cleanly with logical CPU hotplug.
 	 */
 	if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && 
-	    !pr->flags.has_cst && !acpi_fadt.plvl2_up)
+	    !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
 		cx = &pr->power.states[ACPI_STATE_C1];
 #endif
 
@@ -384,11 +380,11 @@ static void acpi_processor_idle(void)
 
 	case ACPI_STATE_C2:
 		/* Get start time (ticks) */
-		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
+		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 		/* Invoke C2 */
 		acpi_cstate_enter(cx);
 		/* Get end time (ticks) */
-		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
 #ifdef CONFIG_GENERIC_TIME
 		/* TSC halts in C2, so notify users */
@@ -411,8 +407,7 @@ static void acpi_processor_idle(void)
 				 * All CPUs are trying to go to C3
 				 * Disable bus master arbitration
 				 */
-				acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
-						  ACPI_MTX_DO_NOT_LOCK);
+				acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
 			}
 		} else {
 			/* SMP with no shared cache... Invalidate cache  */
@@ -420,16 +415,15 @@ static void acpi_processor_idle(void)
 		}
 
 		/* Get start time (ticks) */
-		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
+		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 		/* Invoke C3 */
 		acpi_cstate_enter(cx);
 		/* Get end time (ticks) */
-		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 		if (pr->flags.bm_check) {
 			/* Enable bus master arbitration */
 			atomic_dec(&c3_cpu_count);
-			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
-					  ACPI_MTX_DO_NOT_LOCK);
+			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
 		}
 
 #ifdef CONFIG_GENERIC_TIME
@@ -457,7 +451,7 @@ static void acpi_processor_idle(void)
 #ifdef CONFIG_HOTPLUG_CPU
 	/* Don't do promotion/demotion */
 	if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) &&
-	    !pr->flags.has_cst && !acpi_fadt.plvl2_up) {
+	    !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) {
 		next_state = cx;
 		goto end;
 	}
@@ -627,7 +621,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
 	 * Check for P_LVL2_UP flag before entering C2 and above on
 	 * an SMP system. 
 	 */
-	if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up)
+	if ((num_online_cpus() > 1) &&
+	    !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
 		return -ENODEV;
 #endif
 
@@ -636,8 +631,8 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
 	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;
+	pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency;
+	pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "lvl2[0x%08x] lvl3[0x%08x]\n",
@@ -883,14 +878,13 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
 		 * WBINVD should be set in fadt, for C3 state to be
 		 * supported on when bm_check is not required.
 		 */
-		if (acpi_fadt.wb_invd != 1) {
+		if (!(acpi_gbl_FADT.flags & ACPI_FADT_WBINVD)) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					  "Cache invalidation should work properly"
 					  " for C3 to be enabled on SMP systems\n"));
 			return;
 		}
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD,
-				  0, ACPI_MTX_DO_NOT_LOCK);
+		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
 	}
 
 	/*
@@ -1096,7 +1090,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
 		seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n",
 			   pr->power.states[i].latency,
 			   pr->power.states[i].usage,
-			   pr->power.states[i].time);
+			   (unsigned long long)pr->power.states[i].time);
 	}
 
       end:
@@ -1164,9 +1158,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 	if (!pr)
 		return -EINVAL;
 
-	if (acpi_fadt.cst_cnt && !nocst) {
+	if (acpi_gbl_FADT.cst_control && !nocst) {
 		status =
-		    acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8);
+		    acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8);
 		if (ACPI_FAILURE(status)) {
 			ACPI_EXCEPTION((AE_INFO, status,
 					"Notifying BIOS of _CST ability failed"));
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index cbb6f0814ce2..058f13cf3b79 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -352,31 +352,24 @@ int acpi_processor_notify_smm(struct module *calling_module)
 
 	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"));
+	/* Can't write pstate_control to smi_command if either value is zero */
+	if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n"));
 		module_put(calling_module);
 		return 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));
+			  "Writing pstate_control [0x%x] to smi_command [0x%x]\n",
+			  acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
 
-	/* 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);
+	status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+				    (u32) acpi_gbl_FADT.pstate_control, 8);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
-				"Failed to write pstate_cnt [0x%x] to "
-				"smi_cmd [0x%x]", acpi_fadt.pstate_cnt,
-				acpi_fadt.smi_cmd));
+				"Failed to write pstate_control [0x%x] to "
+				"smi_command [0x%x]", acpi_gbl_FADT.pstate_control,
+				acpi_gbl_FADT.smi_command));
 		module_put(calling_module);
 		return status;
 	}
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 0ec7dcde0063..89dff3639abe 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -125,7 +125,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
 		/* Used to clear all duty_value bits */
 		duty_mask = pr->throttling.state_count - 1;
 
-		duty_mask <<= acpi_fadt.duty_offset;
+		duty_mask <<= acpi_gbl_FADT.duty_offset;
 		duty_mask = ~duty_mask;
 	}
 
@@ -208,7 +208,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 		return 0;
 	}
 
-	pr->throttling.state_count = 1 << acpi_fadt.duty_width;
+	pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
 
 	/*
 	 * Compute state values. Note that throttling displays a linear power/
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 8fa3213ce000..271e61509eeb 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index cf87b0230026..8c6d3fdec38a 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 008058acdd39..1358c06a969c 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index 9c99a723a860..de20a5d6decf 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c
index 9e7ae2f8a1d3..7e3c335ab320 100644
--- a/drivers/acpi/resources/rsinfo.c
+++ b/drivers/acpi/resources/rsinfo.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
index ea567167c4f2..b297bc3e4419 100644
--- a/drivers/acpi/resources/rsio.c
+++ b/drivers/acpi/resources/rsio.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
index 1fa63bc2e36f..5657f7b95039 100644
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index 29423ce030ca..a92755c8877d 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
index a5131936d690..521eab7dd8df 100644
--- a/drivers/acpi/resources/rsmemory.c
+++ b/drivers/acpi/resources/rsmemory.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index faf6e106b785..3b63b561b94e 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index a9cbee8e8b44..2442a8f8df57 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index 1999e2ab7daa..991f8901498c 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 283d87522c5d..0de458664642 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1333,7 +1333,7 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
 	/*
 	 * Enumerate all fixed-feature devices.
 	 */
-	if (acpi_fadt.pwr_button == 0) {
+	if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
 		result = acpi_add_single_object(&device, acpi_root,
 						NULL,
 						ACPI_BUS_TYPE_POWER_BUTTON);
@@ -1341,7 +1341,7 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
 			result = acpi_start_single_object(device);
 	}
 
-	if (acpi_fadt.sleep_button == 0) {
+	if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
 		result = acpi_add_single_object(&device, acpi_root,
 						NULL,
 						ACPI_BUS_TYPE_SLEEP_BUTTON);
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 34962578039d..ccc11b33d89c 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -73,7 +73,7 @@ acpi_system_write_sleep(struct file *file,
 static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 {
 	u32 sec, min, hr;
-	u32 day, mo, yr;
+	u32 day, mo, yr, cent = 0;
 	unsigned char rtc_control = 0;
 	unsigned long flags;
 
@@ -87,20 +87,19 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 	rtc_control = CMOS_READ(RTC_CONTROL);
 
 	/* If we ever get an FACP with proper values... */
-	if (acpi_gbl_FADT->day_alrm)
+	if (acpi_gbl_FADT.day_alarm)
 		/* ACPI spec: only low 6 its should be cared */
-		day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F;
+		day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F;
 	else
 		day = CMOS_READ(RTC_DAY_OF_MONTH);
-	if (acpi_gbl_FADT->mon_alrm)
-		mo = CMOS_READ(acpi_gbl_FADT->mon_alrm);
+	if (acpi_gbl_FADT.month_alarm)
+		mo = CMOS_READ(acpi_gbl_FADT.month_alarm);
 	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);
+	if (acpi_gbl_FADT.century)
+		cent = CMOS_READ(acpi_gbl_FADT.century);
+
+	yr = CMOS_READ(RTC_YEAR);
 
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
@@ -111,10 +110,11 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 		BCD_TO_BIN(day);
 		BCD_TO_BIN(mo);
 		BCD_TO_BIN(yr);
+		BCD_TO_BIN(cent);
 	}
 
 	/* we're trusting the FADT (see above) */
-	if (!acpi_gbl_FADT->century)
+	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?
 		 *
@@ -134,6 +134,8 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 		 *
 		 */
 		yr += 2000;
+	else
+		yr += cent * 100;
 
 	seq_printf(seq, "%4.4u-", yr);
 	(mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo);
@@ -317,12 +319,12 @@ acpi_system_write_alarm(struct file *file,
 	 * 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);
+	if (acpi_gbl_FADT.day_alarm)
+		CMOS_WRITE(day, acpi_gbl_FADT.day_alarm);
+	if (acpi_gbl_FADT.month_alarm)
+		CMOS_WRITE(mo, acpi_gbl_FADT.month_alarm);
+	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);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index d86dcb3c2366..2d425d845821 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -39,7 +39,6 @@ ACPI_MODULE_NAME("acpi_system")
 #define ACPI_SYSTEM_FILE_EVENT		"event"
 #define ACPI_SYSTEM_FILE_DSDT		"dsdt"
 #define ACPI_SYSTEM_FILE_FADT		"fadt"
-extern struct fadt_descriptor acpi_fadt;
 
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
@@ -76,17 +75,16 @@ 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 };
+	struct acpi_table_header *dsdt = NULL;
 	ssize_t res;
 
 
-	status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt);
+	status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
 	res = simple_read_from_buffer(buffer, count, ppos,
-				      dsdt.pointer, dsdt.length);
-	kfree(dsdt.pointer);
+				      dsdt, dsdt->length);
 
 	return res;
 }
@@ -103,17 +101,16 @@ 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 };
+	struct acpi_table_header *fadt = NULL;
 	ssize_t res;
 
 
-	status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt);
+	status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
 	res = simple_read_from_buffer(buffer, count, ppos,
-				      fadt.pointer, fadt.length);
-	kfree(fadt.pointer);
+				      fadt, fadt->length);
 
 	return res;
 }
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index ffa30c9fccbf..ba4cb200314a 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -38,154 +38,97 @@
 
 #define ACPI_MAX_TABLES		128
 
-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_desc initial_tables[ACPI_MAX_TABLES] __initdata;
 
-static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata;
-
-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)
+void acpi_table_print_madt_entry(struct acpi_subtable_header * header)
 {
 	if (!header)
 		return;
 
 	switch (header->type) {
 
-	case ACPI_MADT_LAPIC:
+	case ACPI_MADT_TYPE_LOCAL_APIC:
 		{
-			struct acpi_table_lapic *p =
-			    (struct acpi_table_lapic *)header;
+			struct acpi_madt_local_apic *p =
+			    (struct acpi_madt_local_apic *)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");
+			       p->processor_id, p->id,
+			       (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
 		}
 		break;
 
-	case ACPI_MADT_IOAPIC:
+	case ACPI_MADT_TYPE_IO_APIC:
 		{
-			struct acpi_table_ioapic *p =
-			    (struct acpi_table_ioapic *)header;
+			struct acpi_madt_io_apic *p =
+			    (struct acpi_madt_io_apic *)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:
+	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
 		{
-			struct acpi_table_int_src_ovr *p =
-			    (struct acpi_table_int_src_ovr *)header;
+			struct acpi_madt_interrupt_override *p =
+			    (struct acpi_madt_interrupt_override *)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)
+			       p->bus, p->source_irq, p->global_irq,
+			       mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
+			       mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]);
+			if (p->inti_flags  &
+			    ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK))
 				printk(KERN_INFO PREFIX
 				       "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
-				       p->flags.reserved);
+				       p->inti_flags  &
+					~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK));
 
 		}
 		break;
 
-	case ACPI_MADT_NMI_SRC:
+	case ACPI_MADT_TYPE_NMI_SOURCE:
 		{
-			struct acpi_table_nmi_src *p =
-			    (struct acpi_table_nmi_src *)header;
+			struct acpi_madt_nmi_source *p =
+			    (struct acpi_madt_nmi_source *)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],
+			       mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
+			       mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
 			       p->global_irq);
 		}
 		break;
 
-	case ACPI_MADT_LAPIC_NMI:
+	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
 		{
-			struct acpi_table_lapic_nmi *p =
-			    (struct acpi_table_lapic_nmi *)header;
+			struct acpi_madt_local_apic_nmi *p =
+			    (struct acpi_madt_local_apic_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->processor_id,
+			       mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK	],
+			       mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
 			       p->lint);
 		}
 		break;
 
-	case ACPI_MADT_LAPIC_ADDR_OVR:
+	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
 		{
-			struct acpi_table_lapic_addr_ovr *p =
-			    (struct acpi_table_lapic_addr_ovr *)header;
+			struct acpi_madt_local_apic_override *p =
+			    (struct acpi_madt_local_apic_override *)header;
 			printk(KERN_INFO PREFIX
 			       "LAPIC_ADDR_OVR (address[%p])\n",
 			       (void *)(unsigned long)p->address);
 		}
 		break;
 
-	case ACPI_MADT_IOSAPIC:
+	case ACPI_MADT_TYPE_IO_SAPIC:
 		{
-			struct acpi_table_iosapic *p =
-			    (struct acpi_table_iosapic *)header;
+			struct acpi_madt_io_sapic *p =
+			    (struct acpi_madt_io_sapic *)header;
 			printk(KERN_INFO PREFIX
 			       "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
 			       p->id, (void *)(unsigned long)p->address,
@@ -193,26 +136,26 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header)
 		}
 		break;
 
-	case ACPI_MADT_LSAPIC:
+	case ACPI_MADT_TYPE_LOCAL_SAPIC:
 		{
-			struct acpi_table_lsapic *p =
-			    (struct acpi_table_lsapic *)header;
+			struct acpi_madt_local_sapic *p =
+			    (struct acpi_madt_local_sapic *)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");
+			       p->processor_id, p->id, p->eid,
+			       (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
 		}
 		break;
 
-	case ACPI_MADT_PLAT_INT_SRC:
+	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
 		{
-			struct acpi_table_plat_int_src *p =
-			    (struct acpi_table_plat_int_src *)header;
+			struct acpi_madt_interrupt_source *p =
+			    (struct acpi_madt_interrupt_source *)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,
+			       mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
+			       mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
+			       p->type, p->id, p->eid, p->io_sapic_vector,
 			       p->global_irq);
 		}
 		break;
@@ -225,342 +168,76 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header)
 	}
 }
 
-static int
-acpi_table_compute_checksum(void *table_pointer, unsigned long length)
-{
-	u8 *p = 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 *fadt =
-		    (struct fadt_descriptor *)*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,
+acpi_table_parse_madt_family(char *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;
+	struct acpi_table_header *madt = NULL;
+	struct acpi_subtable_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;
-	}
+	acpi_get_table(id, 0, &madt);
 
 	if (!madt) {
-		printk(KERN_WARNING PREFIX "%s not present\n",
-		       acpi_table_signatures[id]);
+		printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
 		return -ENODEV;
 	}
 
-	madt_end = (unsigned long)madt + sdt_entry[i].size;
+	madt_end = (unsigned long)madt + madt->length;
 
 	/* Parse all entries looking for a match. */
 
-	entry = (acpi_table_entry_header *)
+	entry = (struct acpi_subtable_header *)
 	    ((unsigned long)madt + madt_size);
 
-	while (((unsigned long)entry) + sizeof(acpi_table_entry_header) <
+	while (((unsigned long)entry) + sizeof(struct acpi_subtable_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 *)
+		entry = (struct acpi_subtable_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);
+		printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of "
+		       "%i found\n", id, entry_id, count - max_entries, count);
 	}
 
 	return count;
 }
 
 int __init
-acpi_table_parse_madt(enum acpi_madt_entry_id id,
+acpi_table_parse_madt(enum acpi_madt_type id,
 		      acpi_madt_entry_handler handler, unsigned int max_entries)
 {
-	return acpi_table_parse_madt_family(ACPI_APIC,
+	return acpi_table_parse_madt_family(ACPI_SIG_MADT,
 					    sizeof(struct acpi_table_madt), id,
 					    handler, max_entries);
 }
 
-int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler)
+int __init acpi_table_parse(char *id, acpi_table_handler handler)
 {
-	int count = 0;
-	unsigned int i = 0;
-
+	struct acpi_table_header *table = NULL;
 	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_get_table(id, 0, &table);
+	if (table) {
+		handler(table);
+		return 1;
+	} else
+		return 0;
 }
 
 /*
@@ -568,54 +245,13 @@ static int __init acpi_table_get_sdt(struct acpi_table_rsdp *rsdp)
  *
  * 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 *)__acpi_map_table(rsdp_phys,
-		sizeof(struct acpi_table_rsdp));
-	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;
-
+	acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
 	return 0;
 }
diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile
index aa4c69594d97..0a7d7afac255 100644
--- a/drivers/acpi/tables/Makefile
+++ b/drivers/acpi/tables/Makefile
@@ -2,7 +2,6 @@
 # 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
+obj-y := tbxface.o tbinstal.o  tbutils.o tbfind.o tbfadt.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
deleted file mode 100644
index d697fcb35d52..000000000000
--- a/drivers/acpi/tables/tbconvrt.c
+++ /dev/null
@@ -1,622 +0,0 @@
-/******************************************************************************
- *
- * Module Name: tbconvrt - ACPI Table conversion utilities
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2006, 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("tbconvrt")
-
-/* Local prototypes */
-static void
-acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct,
-			     u8 register_bit_width,
-			     acpi_physical_address address);
-
-static void
-acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt,
-		      struct fadt_descriptor_rev1 *original_fadt);
-
-static void
-acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt,
-		      struct fadt_descriptor *original_fadt);
-
-u8 acpi_fadt_is_v1;
-ACPI_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();
-
-	/* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
-
-	if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
-		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;
-	struct 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_ALLOCATE_ZEROED(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++) {
-
-		/* RSDT pointers are 32 bits, XSDT pointers are 64 bits */
-
-		if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
-			ACPI_STORE_ADDRESS(new_table->table_offset_entry[i],
-					   (ACPI_CAST_PTR
-					    (struct rsdt_descriptor,
-					     table_info->pointer))->
-					   table_offset_entry[i]);
-		} else {
-			new_table->table_offset_entry[i] =
-			    (ACPI_CAST_PTR(struct 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:      None, populates local_fadt
- *
- * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format
- *
- ******************************************************************************/
-
-static void
-acpi_tb_convert_fadt1(struct fadt_descriptor *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:      None, 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 *local_fadt,
-		      struct fadt_descriptor *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));
-
-	/*
-	 * "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 *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_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X",
-			    acpi_gbl_FADT->length));
-		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
-	}
-
-	/* Allocate buffer for the ACPI 2.0(+) FADT */
-
-	local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor));
-	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)) {
-
-			/* Length is too short to be a V2.0 table */
-
-			ACPI_WARNING((AE_INFO,
-				      "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table",
-				      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(struct fadt_descriptor);
-
-	/* Free the original table */
-
-	table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_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);
-
-	/* 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(ACPI_CAST_PTR(u8, acpi_gbl_FADT),
-			 acpi_gbl_FADT->length);
-
-	return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_build_common_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_ERROR((AE_INFO, "Invalid FACS table length: 0x%X",
-			    acpi_gbl_FACS->length));
-		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
-	}
-
-	if (acpi_gbl_FACS->length < 64) {
-		ACPI_WARNING((AE_INFO,
-			      "FACS is shorter than the ACPI specification allows: 0x%X, using anyway",
-			      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/tbfadt.c b/drivers/acpi/tables/tbfadt.c
new file mode 100644
index 000000000000..807c7116e94b
--- /dev/null
+++ b/drivers/acpi/tables/tbfadt.c
@@ -0,0 +1,434 @@
+/******************************************************************************
+ *
+ * Module Name: tbfadt   - FADT table utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2007, 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("tbfadt")
+
+/* Local prototypes */
+static void inline
+acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
+			     u8 bit_width, u64 address);
+
+static void acpi_tb_convert_fadt(void);
+
+static void acpi_tb_validate_fadt(void);
+
+/* Table for conversion of FADT to common internal format and FADT validation */
+
+typedef struct acpi_fadt_info {
+	char *name;
+	u8 target;
+	u8 source;
+	u8 length;
+	u8 type;
+
+} acpi_fadt_info;
+
+#define ACPI_FADT_REQUIRED          1
+#define ACPI_FADT_SEPARATE_LENGTH   2
+
+static struct acpi_fadt_info fadt_info_table[] = {
+	{"Pm1aEventBlock", ACPI_FADT_OFFSET(xpm1a_event_block),
+	 ACPI_FADT_OFFSET(pm1a_event_block),
+	 ACPI_FADT_OFFSET(pm1_event_length), ACPI_FADT_REQUIRED},
+
+	{"Pm1bEventBlock", ACPI_FADT_OFFSET(xpm1b_event_block),
+	 ACPI_FADT_OFFSET(pm1b_event_block),
+	 ACPI_FADT_OFFSET(pm1_event_length), 0},
+
+	{"Pm1aControlBlock", ACPI_FADT_OFFSET(xpm1a_control_block),
+	 ACPI_FADT_OFFSET(pm1a_control_block),
+	 ACPI_FADT_OFFSET(pm1_control_length), ACPI_FADT_REQUIRED},
+
+	{"Pm1bControlBlock", ACPI_FADT_OFFSET(xpm1b_control_block),
+	 ACPI_FADT_OFFSET(pm1b_control_block),
+	 ACPI_FADT_OFFSET(pm1_control_length), 0},
+
+	{"Pm2ControlBlock", ACPI_FADT_OFFSET(xpm2_control_block),
+	 ACPI_FADT_OFFSET(pm2_control_block),
+	 ACPI_FADT_OFFSET(pm2_control_length), ACPI_FADT_SEPARATE_LENGTH},
+
+	{"PmTimerBlock", ACPI_FADT_OFFSET(xpm_timer_block),
+	 ACPI_FADT_OFFSET(pm_timer_block),
+	 ACPI_FADT_OFFSET(pm_timer_length), ACPI_FADT_REQUIRED},
+
+	{"Gpe0Block", ACPI_FADT_OFFSET(xgpe0_block),
+	 ACPI_FADT_OFFSET(gpe0_block),
+	 ACPI_FADT_OFFSET(gpe0_block_length), ACPI_FADT_SEPARATE_LENGTH},
+
+	{"Gpe1Block", ACPI_FADT_OFFSET(xgpe1_block),
+	 ACPI_FADT_OFFSET(gpe1_block),
+	 ACPI_FADT_OFFSET(gpe1_block_length), ACPI_FADT_SEPARATE_LENGTH}
+};
+
+#define ACPI_FADT_INFO_ENTRIES        (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_init_generic_address
+ *
+ * PARAMETERS:  generic_address     - GAS struct to be initialized
+ *              bit_width           - Width of this register
+ *              Address             - Address of the register
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize a Generic Address Structure (GAS)
+ *              See the ACPI specification for a full description and
+ *              definition of this structure.
+ *
+ ******************************************************************************/
+
+static void inline
+acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
+			     u8 bit_width, u64 address)
+{
+
+	/*
+	 * The 64-bit Address field is non-aligned in the byte packed
+	 * GAS struct.
+	 */
+	ACPI_MOVE_64_TO_64(&generic_address->address, &address);
+
+	/* All other fields are byte-wide */
+
+	generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO;
+	generic_address->bit_width = bit_width;
+	generic_address->bit_offset = 0;
+	generic_address->access_width = 0;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_parse_fadt
+ *
+ * PARAMETERS:  table_index         - Index for the FADT
+ *              Flags               - Flags
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
+ *              (FADT contains the addresses of the DSDT and FACS)
+ *
+ ******************************************************************************/
+
+void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
+{
+	u32 length;
+	struct acpi_table_header *table;
+
+	/*
+	 * The FADT has multiple versions with different lengths,
+	 * and it contains pointers to both the DSDT and FACS tables.
+	 *
+	 * Get a local copy of the FADT and convert it to a common format
+	 * Map entire FADT, assumed to be smaller than one page.
+	 */
+	length = acpi_gbl_root_table_list.tables[table_index].length;
+
+	table =
+	    acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
+			       address, length);
+	if (!table) {
+		return;
+	}
+
+	/*
+	 * Validate the FADT checksum before we copy the table. Ignore
+	 * checksum error as we want to try to get the DSDT and FACS.
+	 */
+	(void)acpi_tb_verify_checksum(table, length);
+
+	/* Obtain a local copy of the FADT in common ACPI 2.0+ format */
+
+	acpi_tb_create_local_fadt(table, length);
+
+	/* All done with the real FADT, unmap it */
+
+	acpi_os_unmap_memory(table, length);
+
+	/* Obtain the DSDT and FACS tables via their addresses within the FADT */
+
+	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
+			      flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+
+	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
+			      flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_create_local_fadt
+ *
+ * PARAMETERS:  Table               - Pointer to BIOS FADT
+ *              Length              - Length of the table
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
+ *              Performs validation on some important FADT fields.
+ *
+ ******************************************************************************/
+
+void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
+{
+
+	/*
+	 * Check if the FADT is larger than what we know about (ACPI 2.0 version).
+	 * Truncate the table, but make some noise.
+	 */
+	if (length > sizeof(struct acpi_table_fadt)) {
+		ACPI_WARNING((AE_INFO,
+			      "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX",
+			      table->revision, (unsigned)length,
+			      sizeof(struct acpi_table_fadt)));
+	}
+
+	/* Copy the entire FADT locally. Zero first for tb_convert_fadt */
+
+	ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
+
+	ACPI_MEMCPY(&acpi_gbl_FADT, table,
+		    ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
+
+	/*
+	 * 1) Convert the local copy of the FADT to the common internal format
+	 * 2) Validate some of the important values within the FADT
+	 */
+	acpi_tb_convert_fadt();
+	acpi_tb_validate_fadt();
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_convert_fadt
+ *
+ * PARAMETERS:  None, uses acpi_gbl_FADT
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Converts all versions of the FADT to a common internal format.
+ *              -> Expand all 32-bit addresses to 64-bit.
+ *
+ * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt),
+ *              and must contain a copy of the actual FADT.
+ *
+ * ACPICA will use the "X" fields of the FADT for all addresses.
+ *
+ * "X" fields are optional extensions to the original V1.0 fields. Even if
+ * they are present in the structure, they can be optionally not used by
+ * setting them to zero. Therefore, we must selectively expand V1.0 fields
+ * if the corresponding X field is zero.
+ *
+ * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
+ * "X" fields.
+ *
+ * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
+ * expanding the corresponding ACPI 1.0 field.
+ *
+ ******************************************************************************/
+
+static void acpi_tb_convert_fadt(void)
+{
+	u8 pm1_register_length;
+	struct acpi_generic_address *target;
+	acpi_native_uint i;
+
+	/* Update the local FADT table header length */
+
+	acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
+
+	/* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */
+
+	if (!acpi_gbl_FADT.Xfacs) {
+		acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
+	}
+
+	if (!acpi_gbl_FADT.Xdsdt) {
+		acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
+	}
+
+	/*
+	 * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address
+	 * structures as necessary.
+	 */
+	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+		target =
+		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+				 fadt_info_table[i].target);
+
+		/* Expand only if the X target is null */
+
+		if (!target->address) {
+			acpi_tb_init_generic_address(target,
+						     *ACPI_ADD_PTR(u8,
+								   &acpi_gbl_FADT,
+								   fadt_info_table
+								   [i].length),
+						     (u64) * ACPI_ADD_PTR(u32,
+									  &acpi_gbl_FADT,
+									  fadt_info_table
+									  [i].
+									  source));
+		}
+	}
+
+	/*
+	 * Calculate separate GAS structs for the PM1 Enable registers.
+	 * These addresses do not appear (directly) in the FADT, so it is
+	 * useful to calculate them once, here.
+	 *
+	 * The PM event blocks are split into two register blocks, first is the
+	 * PM Status Register block, followed immediately by the PM Enable Register
+	 * block. Each is of length (pm1_event_length/2)
+	 */
+	pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length);
+
+	/* The PM1A register block is required */
+
+	acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
+				     pm1_register_length,
+				     (acpi_gbl_FADT.xpm1a_event_block.address +
+				      pm1_register_length));
+	/* Don't forget to copy space_id of the GAS */
+	acpi_gbl_xpm1a_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id;
+
+	/* The PM1B register block is optional, ignore if not present */
+
+	if (acpi_gbl_FADT.xpm1b_event_block.address) {
+		acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
+					     pm1_register_length,
+					     (acpi_gbl_FADT.xpm1b_event_block.
+					      address + pm1_register_length));
+		/* Don't forget to copy space_id of the GAS */
+		acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id;
+
+	}
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_validate_fadt
+ *
+ * PARAMETERS:  Table           - Pointer to the FADT to be validated
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Validate various important fields within the FADT. If a problem
+ *              is found, issue a message, but no status is returned.
+ *              Used by both the table manager and the disassembler.
+ *
+ * Possible additional checks:
+ * (acpi_gbl_FADT.pm1_event_length >= 4)
+ * (acpi_gbl_FADT.pm1_control_length >= 2)
+ * (acpi_gbl_FADT.pm_timer_length >= 4)
+ * Gpe block lengths must be multiple of 2
+ *
+ ******************************************************************************/
+
+static void acpi_tb_validate_fadt(void)
+{
+	u32 *address32;
+	struct acpi_generic_address *address64;
+	u8 length;
+	acpi_native_uint i;
+
+	/* Examine all of the 64-bit extended address fields (X fields) */
+
+	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+
+		/* Generate pointers to the 32-bit and 64-bit addresses and get the length */
+
+		address64 =
+		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+				 fadt_info_table[i].target);
+		address32 =
+		    ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
+				 fadt_info_table[i].source);
+		length =
+		    *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
+				  fadt_info_table[i].length);
+
+		if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
+			/*
+			 * Field is required (Pm1a_event, Pm1a_control, pm_timer).
+			 * Both the address and length must be non-zero.
+			 */
+			if (!address64->address || !length) {
+				ACPI_ERROR((AE_INFO,
+					    "Required field \"%s\" has zero address and/or length: %8.8X%8.8X/%X",
+					    fadt_info_table[i].name,
+					    ACPI_FORMAT_UINT64(address64->
+							       address),
+					    length));
+			}
+		} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
+			/*
+			 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
+			 * length field. If present, both the address and length must be valid.
+			 */
+			if ((address64->address && !length)
+			    || (!address64->address && length)) {
+				ACPI_WARNING((AE_INFO,
+					      "Optional field \"%s\" has zero address or length: %8.8X%8.8X/%X",
+					      fadt_info_table[i].name,
+					      ACPI_FORMAT_UINT64(address64->
+								 address),
+					      length));
+			}
+		}
+
+		/* If both 32- and 64-bit addresses are valid (non-zero), they must match */
+
+		if (address64->address && *address32 &&
+		    (address64->address != (u64) * address32)) {
+			ACPI_ERROR((AE_INFO,
+				    "32/64X address mismatch in \"%s\": [%8.8X] [%8.8X%8.8X], using 64X",
+				    fadt_info_table[i].name, *address32,
+				    ACPI_FORMAT_UINT64(address64->address)));
+		}
+	}
+}
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c
new file mode 100644
index 000000000000..058c064948e1
--- /dev/null
+++ b/drivers/acpi/tables/tbfind.c
@@ -0,0 +1,126 @@
+/******************************************************************************
+ *
+ * Module Name: tbfind   - find table
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2007, 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("tbfind")
+
+/*******************************************************************************
+ *
+ * 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
+ *              table_index         - Where the table index is returned
+ *
+ * RETURN:      Status and table index
+ *
+ * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
+ *              Signature, OEM ID and OEM Table ID. Returns an index that can
+ *              be used to get the table header or entire table.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_tb_find_table(char *signature,
+		   char *oem_id,
+		   char *oem_table_id, acpi_native_uint * table_index)
+{
+	acpi_native_uint i;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(tb_find_table);
+
+	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
+		if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature),
+				signature, ACPI_NAME_SIZE)) {
+
+			/* Not the requested table */
+
+			continue;
+		}
+
+		/* Table with matching signature has been found */
+
+		if (!acpi_gbl_root_table_list.tables[i].pointer) {
+
+			/* Table is not currently mapped, map it */
+
+			status =
+			    acpi_tb_verify_table(&acpi_gbl_root_table_list.
+						 tables[i]);
+			if (ACPI_FAILURE(status)) {
+				return_ACPI_STATUS(status);
+			}
+
+			if (!acpi_gbl_root_table_list.tables[i].pointer) {
+				continue;
+			}
+		}
+
+		/* Check for table match on all IDs */
+
+		if (!ACPI_MEMCMP
+		    (acpi_gbl_root_table_list.tables[i].pointer->signature,
+		     signature, ACPI_NAME_SIZE) && (!oem_id[0]
+						    ||
+						    !ACPI_MEMCMP
+						    (acpi_gbl_root_table_list.
+						     tables[i].pointer->oem_id,
+						     oem_id, ACPI_OEM_ID_SIZE))
+		    && (!oem_table_id[0]
+			|| !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i].
+					pointer->oem_table_id, oem_table_id,
+					ACPI_OEM_TABLE_ID_SIZE))) {
+			*table_index = i;
+
+			ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
+					  "Found table [%4.4s]\n", signature));
+			return_ACPI_STATUS(AE_OK);
+		}
+	}
+
+	return_ACPI_STATUS(AE_NOT_FOUND);
+}
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
deleted file mode 100644
index 11e2d4454e05..000000000000
--- a/drivers/acpi/tables/tbget.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/******************************************************************************
- *
- * Module Name: tbget - ACPI Table get* routines
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2006, 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")
-
-/* Local prototypes */
-static acpi_status
-acpi_tb_get_this_table(struct acpi_pointer *address,
-		       struct acpi_table_header *header,
-		       struct acpi_table_desc *table_info);
-
-static acpi_status
-acpi_tb_table_override(struct acpi_table_header *header,
-		       struct acpi_table_desc *table_info);
-
-/*******************************************************************************
- *
- * 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_EXCEPTION((AE_INFO, status,
-				"Could not get ACPI table (size %X)",
-				header.length));
-		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_ERROR((AE_INFO,
-				    "Could not map memory at %8.8X%8.8X for table header",
-				    ACPI_FORMAT_UINT64(address->pointer.
-						       physical)));
-			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_ERROR((AE_INFO, "Invalid address flags %X",
-			    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.
- *
- ******************************************************************************/
-
-static 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_EXCEPTION((AE_INFO, status,
-				"Could not override ACPI table"));
-		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_EXCEPTION((AE_INFO, status, "Could not copy ACPI table"));
-		return_ACPI_STATUS(status);
-	}
-
-	/* Copy the table info */
-
-	ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS",
-		   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.
- *
- ******************************************************************************/
-
-static 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);
-
-	/* Validate minimum length */
-
-	if (header->length < sizeof(struct acpi_table_header)) {
-		ACPI_ERROR((AE_INFO,
-			    "Table length (%X) is smaller than minimum (%zX)",
-			    header->length, sizeof(struct acpi_table_header)));
-
-		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
-	}
-
-	/*
-	 * 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_ALLOCATE(header->length);
-		if (!full_table) {
-			ACPI_ERROR((AE_INFO,
-				    "Could not allocate table memory for [%4.4s] length %X",
-				    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,
-					    ACPI_CAST_PTR(void, &full_table));
-		if (ACPI_FAILURE(status)) {
-			ACPI_ERROR((AE_INFO,
-				    "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X",
-				    header->signature,
-				    ACPI_FORMAT_UINT64(address->pointer.
-						       physical),
-				    header->length));
-			return (status);
-		}
-
-		/* Save allocation type */
-
-		allocation = ACPI_MEM_MAPPED;
-		break;
-
-	default:
-
-		ACPI_ERROR((AE_INFO, "Invalid address flags %X",
-			    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_ID_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
- *              return_table    - 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 **return_table)
-{
-	struct acpi_table_desc *table_desc;
-	u32 i;
-
-	ACPI_FUNCTION_TRACE(tb_get_table_ptr);
-
-	if (table_type > ACPI_TABLE_ID_MAX) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
-
-	/* Check for instance out of range of the current table count */
-
-	if (instance > acpi_gbl_table_lists[table_type].count) {
-		return_ACPI_STATUS(AE_NOT_EXIST);
-	}
-
-	/*
-	 * Walk the list to get the desired table
-	 * Note: Instance is one-based
-	 */
-	table_desc = acpi_gbl_table_lists[table_type].next;
-	for (i = 1; i < instance; i++) {
-		table_desc = table_desc->next;
-	}
-
-	/* We are now pointing to the requested table's descriptor */
-
-	*return_table = table_desc->pointer;
-	return_ACPI_STATUS(AE_OK);
-}
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
deleted file mode 100644
index ad982112e4c6..000000000000
--- a/drivers/acpi/tables/tbgetall.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/******************************************************************************
- *
- * Module Name: tbgetall - Get all required ACPI tables
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2006, 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")
-
-/* Local prototypes */
-static acpi_status
-acpi_tb_get_primary_table(struct acpi_pointer *address,
-			  struct acpi_table_desc *table_info);
-
-static acpi_status
-acpi_tb_get_secondary_table(struct acpi_pointer *address,
-			    acpi_string signature,
-			    struct acpi_table_desc *table_info);
-
-/*******************************************************************************
- *
- * 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
- *
- ******************************************************************************/
-
-static 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
- *
- ******************************************************************************/
-
-static 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_COMPARE_NAME(header.signature, signature)) {
-		ACPI_ERROR((AE_INFO,
-			    "Incorrect table signature - wanted [%s] found [%4.4s]",
-			    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_WARNING((AE_INFO,
-				      "%s, while getting table at %8.8X%8.8X",
-				      acpi_format_exception(status),
-				      ACPI_FORMAT_UINT64(address.pointer.
-							 value)));
-		}
-	}
-
-	/* We must have a FADT to continue */
-
-	if (!acpi_gbl_FADT) {
-		ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT"));
-		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_ERROR((AE_INFO,
-			    "Could not convert FADT to internal common format"));
-		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_EXCEPTION((AE_INFO, status,
-				"Could not get/install the FACS"));
-		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_ERROR((AE_INFO, "Could not get/install the DSDT"));
-		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(ACPI_CAST_PTR(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_ID_RSDP);
-	return_ACPI_STATUS(status);
-}
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 1668a232fb67..0e7b121a99ce 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,510 +42,498 @@
  */
 
 #include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 #include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbinstal")
 
-/* Local prototypes */
-static acpi_status
-acpi_tb_match_signature(char *signature,
-			struct acpi_table_desc *table_info, u8 search_type);
-
-/*******************************************************************************
+/******************************************************************************
  *
- * FUNCTION:    acpi_tb_match_signature
+ * FUNCTION:    acpi_tb_verify_table
  *
- * PARAMETERS:  Signature           - Table signature to match
- *              table_info          - Return data
- *              search_type         - Table type to match (primary/secondary)
+ * PARAMETERS:  table_desc          - table
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned"
- *              tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match.
+ * DESCRIPTION: this function is called to verify and map table
  *
- ******************************************************************************/
-
-static acpi_status
-acpi_tb_match_signature(char *signature,
-			struct acpi_table_desc *table_info, u8 search_type)
+ *****************************************************************************/
+acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
 {
-	acpi_native_uint i;
+	acpi_status status = AE_OK;
 
-	ACPI_FUNCTION_TRACE(tb_match_signature);
+	ACPI_FUNCTION_TRACE(tb_verify_table);
 
-	/* Search for a signature match among the known table types */
+	/* Map the table if necessary */
 
-	for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) {
-		if (!(acpi_gbl_table_data[i].flags & search_type)) {
-			continue;
+	if (!table_desc->pointer) {
+		if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
+		    ACPI_TABLE_ORIGIN_MAPPED) {
+			table_desc->pointer =
+			    acpi_os_map_memory(table_desc->address,
+					       table_desc->length);
 		}
+		if (!table_desc->pointer) {
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+	}
 
-		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 */
+	/* FACS is the odd table, has no standard ACPI header and no checksum */
 
-			if (table_info) {
-				table_info->type = (u8) i;
-			}
+	if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {
 
-			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));
+		/* Always calculate checksum, ignore bad checksum if requested */
 
-			return_ACPI_STATUS(AE_OK);
-		}
+		status =
+		    acpi_tb_verify_checksum(table_desc->pointer,
+					    table_desc->length);
 	}
 
-	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);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_install_table
+ * FUNCTION:    acpi_tb_add_table
  *
- * PARAMETERS:  table_info          - Return value from acpi_tb_get_table_body
+ * PARAMETERS:  table_desc          - Table descriptor
+ *              table_index         - Where the table index is returned
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Install the table into the global data structures.
+ * DESCRIPTION: This function is called to add the ACPI table
  *
  ******************************************************************************/
 
-acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info)
+acpi_status
+acpi_tb_add_table(struct acpi_table_desc *table_desc,
+		  acpi_native_uint * table_index)
 {
-	acpi_status status;
-
-	ACPI_FUNCTION_TRACE(tb_install_table);
+	acpi_native_uint i;
+	acpi_native_uint length;
+	acpi_status status = AE_OK;
 
-	/* Lock tables while installing */
+	ACPI_FUNCTION_TRACE(tb_add_table);
 
-	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Could not acquire table mutex"));
-		return_ACPI_STATUS(status);
+	if (!table_desc->pointer) {
+		status = acpi_tb_verify_table(table_desc);
+		if (ACPI_FAILURE(status) || !table_desc->pointer) {
+			return_ACPI_STATUS(status);
+		}
 	}
 
-	/*
-	 * Ignore a table that is already installed. For example, some BIOS
-	 * ASL code will repeatedly attempt to load the same SSDT.
-	 */
-	status = acpi_tb_is_table_installed(table_info);
-	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
+	/* The table must be either an SSDT or a PSDT */
+
+	if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
+	    &&
+	    (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)))
+	{
+		ACPI_ERROR((AE_INFO,
+			    "Table has invalid signature [%4.4s], must be SSDT or PSDT",
+			    table_desc->pointer->signature));
+		return_ACPI_STATUS(AE_BAD_SIGNATURE);
 	}
 
-	/* Install the table into the global data structure */
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+
+	/* Check if table is already registered */
+
+	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
+		if (!acpi_gbl_root_table_list.tables[i].pointer) {
+			status =
+			    acpi_tb_verify_table(&acpi_gbl_root_table_list.
+						 tables[i]);
+			if (ACPI_FAILURE(status)
+			    || !acpi_gbl_root_table_list.tables[i].pointer) {
+				continue;
+			}
+		}
+
+		length = ACPI_MIN(table_desc->length,
+				  acpi_gbl_root_table_list.tables[i].length);
+		if (ACPI_MEMCMP(table_desc->pointer,
+				acpi_gbl_root_table_list.tables[i].pointer,
+				length)) {
+			continue;
+		}
+
+		/* Table is already registered */
+
+		acpi_tb_delete_table(table_desc);
+		*table_index = i;
+		goto release;
+	}
 
-	status = acpi_tb_init_table_descriptor(table_info->type, table_info);
+	/*
+	 * Add the table to the global table list
+	 */
+	status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
+				     table_desc->length, table_desc->flags,
+				     table_index);
 	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Could not install table [%4.4s]",
-				table_info->pointer->signature));
+		goto release;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n",
-			  acpi_gbl_table_data[table_info->type].name,
-			  table_info->pointer));
+	acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
 
-      unlock_and_exit:
+      release:
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_recognize_table
+ * FUNCTION:    acpi_tb_resize_root_table_list
  *
- * PARAMETERS:  table_info          - Return value from acpi_tb_get_table_body
- *              search_type         - Table type to match (primary/secondary)
+ * PARAMETERS:  None
  *
  * 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)
+ * DESCRIPTION: Expand the size of global table array
  *
  ******************************************************************************/
 
-acpi_status
-acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type)
+acpi_status acpi_tb_resize_root_table_list(void)
 {
-	struct acpi_table_header *table_header;
-	acpi_status status;
+	struct acpi_table_desc *tables;
 
-	ACPI_FUNCTION_TRACE(tb_recognize_table);
+	ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
 
-	/* Ensure that we have a valid table pointer */
+	/* allow_resize flag is a parameter to acpi_initialize_tables */
 
-	table_header = (struct acpi_table_header *)table_info->pointer;
-	if (!table_header) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
+		ACPI_ERROR((AE_INFO,
+			    "Resize of Root Table Array is not allowed"));
+		return_ACPI_STATUS(AE_SUPPORT);
 	}
 
-	/*
-	 * 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);
+	/* Increase the Table Array size */
+
+	tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
+				       ACPI_ROOT_TABLE_SIZE_INCREMENT)
+				      * sizeof(struct acpi_table_desc));
+	if (!tables) {
+		ACPI_ERROR((AE_INFO,
+			    "Could not allocate new root table array"));
+		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	status = acpi_tb_validate_table_header(table_header);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+	/* Copy and free the previous table array */
+
+	if (acpi_gbl_root_table_list.tables) {
+		ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
+			    acpi_gbl_root_table_list.size *
+			    sizeof(struct acpi_table_desc));
+
+		if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
+			ACPI_FREE(acpi_gbl_root_table_list.tables);
+		}
 	}
 
-	/* Return the table type and length via the info struct */
+	acpi_gbl_root_table_list.tables = tables;
+	acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
+	acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED;
 
-	table_info->length = (acpi_size) table_header->length;
-	return_ACPI_STATUS(status);
+	return_ACPI_STATUS(AE_OK);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_init_table_descriptor
+ * FUNCTION:    acpi_tb_store_table
  *
- * PARAMETERS:  table_type          - The type of the table
- *              table_info          - A table info struct
+ * PARAMETERS:  Address             - Table address
+ *              Table               - Table header
+ *              Length              - Table length
+ *              Flags               - flags
  *
- * RETURN:      None.
+ * RETURN:      Status and table index.
  *
- * DESCRIPTION: Install a table into the global data structs.
+ * DESCRIPTION: Add an ACPI table to the global table list
  *
  ******************************************************************************/
 
 acpi_status
-acpi_tb_init_table_descriptor(acpi_table_type table_type,
-			      struct acpi_table_desc *table_info)
+acpi_tb_store_table(acpi_physical_address address,
+		    struct acpi_table_header *table,
+		    u32 length, u8 flags, acpi_native_uint * table_index)
 {
-	struct acpi_table_list *list_head;
-	struct acpi_table_desc *table_desc;
-	acpi_status status;
-
-	ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type);
+	acpi_status status = AE_OK;
 
-	/* Allocate a descriptor for this table */
+	/* Ensure that there is room for the table in the Root Table List */
 
-	table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc));
-	if (!table_desc) {
-		return_ACPI_STATUS(AE_NO_MEMORY);
+	if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) {
+		status = acpi_tb_resize_root_table_list();
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
 	}
 
-	/* Get a new owner ID for the table */
+	/* Initialize added table */
+
+	acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
+	    address = address;
+	acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
+	    pointer = table;
+	acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length =
+	    length;
+	acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
+	    owner_id = 0;
+	acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags =
+	    flags;
+
+	ACPI_MOVE_32_TO_32(&
+			   (acpi_gbl_root_table_list.
+			    tables[acpi_gbl_root_table_list.count].signature),
+			   table->signature);
+
+	*table_index = acpi_gbl_root_table_list.count;
+	acpi_gbl_root_table_list.count++;
+	return (status);
+}
 
-	status = acpi_ut_allocate_owner_id(&table_desc->owner_id);
-	if (ACPI_FAILURE(status)) {
-		goto error_exit1;
-	}
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_delete_table
+ *
+ * PARAMETERS:  table_index         - Table index
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete one internal ACPI table
+ *
+ ******************************************************************************/
 
-	/* Install the table into the global data structure */
+void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
+{
+	/* Table must be mapped or allocated */
+	if (!table_desc->pointer) {
+		return;
+	}
+	switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
+	case ACPI_TABLE_ORIGIN_MAPPED:
+		acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
+		break;
+	case ACPI_TABLE_ORIGIN_ALLOCATED:
+		ACPI_FREE(table_desc->pointer);
+		break;
+	default:;
+	}
 
-	list_head = &acpi_gbl_table_lists[table_type];
+	table_desc->pointer = NULL;
+}
 
-	/*
-	 * 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) {
-			status = AE_ALREADY_EXISTS;
-			goto error_exit2;
-		}
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_terminate
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete all internal ACPI tables
+ *
+ ******************************************************************************/
 
-		table_desc->next = list_head->next;
-		list_head->next = table_desc;
+void acpi_tb_terminate(void)
+{
+	acpi_native_uint i;
 
-		if (table_desc->next) {
-			table_desc->next->prev = table_desc;
-		}
+	ACPI_FUNCTION_TRACE(tb_terminate);
 
-		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;
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-			while (table_desc->next->next) {
-				table_desc->next = table_desc->next->next;
-			}
+	/* Delete the individual tables */
 
-			table_desc->next->next = table_desc;
-			table_desc->prev = table_desc->next;
-			table_desc->next = NULL;
-		}
+	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
+		acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
 	}
 
-	/* Finish initialization of the table descriptor */
-
-	table_desc->loaded_into_namespace = FALSE;
-	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));
-
 	/*
-	 * Set the appropriate global pointer (if there is one) to point to the
-	 * newly installed table
+	 * Delete the root table array if allocated locally. Array cannot be
+	 * mapped, so we don't need to check for that flag.
 	 */
-	if (acpi_gbl_table_data[table_type].global_ptr) {
-		*(acpi_gbl_table_data[table_type].global_ptr) =
-		    table_info->pointer;
+	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
+		ACPI_FREE(acpi_gbl_root_table_list.tables);
 	}
 
-	/* Return Data */
-
-	table_info->owner_id = table_desc->owner_id;
-	table_info->installed_desc = table_desc;
-	return_ACPI_STATUS(AE_OK);
-
-	/* Error exit with cleanup */
-
-      error_exit2:
-
-	acpi_ut_release_owner_id(&table_desc->owner_id);
+	acpi_gbl_root_table_list.tables = NULL;
+	acpi_gbl_root_table_list.flags = 0;
+	acpi_gbl_root_table_list.count = 0;
 
-      error_exit1:
-
-	ACPI_FREE(table_desc);
-	return_ACPI_STATUS(status);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_delete_all_tables
+ * FUNCTION:    acpi_tb_delete_namespace_by_owner
  *
- * PARAMETERS:  None.
+ * PARAMETERS:  table_index         - Table index
  *
- * RETURN:      None.
+ * RETURN:      None
  *
- * DESCRIPTION: Delete all internal ACPI tables
+ * DESCRIPTION: Delete all namespace objects created when this table was loaded.
  *
  ******************************************************************************/
 
-void acpi_tb_delete_all_tables(void)
+void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
 {
-	acpi_table_type type;
+	acpi_owner_id owner_id;
 
-	/*
-	 * Free memory allocated for ACPI tables
-	 * Memory can either be mapped or allocated
-	 */
-	for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) {
-		acpi_tb_delete_tables_by_type(type);
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (table_index < acpi_gbl_root_table_list.count) {
+		owner_id =
+		    acpi_gbl_root_table_list.tables[table_index].owner_id;
+	} else {
+		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+		return;
 	}
+
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+	acpi_ns_delete_namespace_by_owner(owner_id);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_delete_tables_by_type
+ * FUNCTION:    acpi_tb_allocate_owner_id
  *
- * PARAMETERS:  Type                - The table type to be deleted
+ * PARAMETERS:  table_index         - Table index
  *
- * RETURN:      None.
+ * RETURN:      Status
  *
- * DESCRIPTION: Delete an internal ACPI table
- *              Locks the ACPI table mutex
+ * DESCRIPTION: Allocates owner_id in table_desc
  *
  ******************************************************************************/
 
-void acpi_tb_delete_tables_by_type(acpi_table_type type)
+acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
 {
-	struct acpi_table_desc *table_desc;
-	u32 count;
-	u32 i;
+	acpi_status status = AE_BAD_PARAMETER;
 
-	ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type);
+	ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
 
-	if (type > ACPI_TABLE_ID_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_ID_RSDP:
-		acpi_gbl_RSDP = NULL;
-		break;
-
-	case ACPI_TABLE_ID_DSDT:
-		acpi_gbl_DSDT = NULL;
-		break;
-
-	case ACPI_TABLE_ID_FADT:
-		acpi_gbl_FADT = NULL;
-		break;
-
-	case ACPI_TABLE_ID_FACS:
-		acpi_gbl_FACS = NULL;
-		break;
-
-	case ACPI_TABLE_ID_XSDT:
-		acpi_gbl_XSDT = NULL;
-		break;
-
-	case ACPI_TABLE_ID_SSDT:
-	case ACPI_TABLE_ID_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_acquire_mutex(ACPI_MTX_TABLES);
+	if (table_index < acpi_gbl_root_table_list.count) {
+		status = acpi_ut_allocate_owner_id
+		    (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-	return_VOID;
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_delete_single_table
+ * FUNCTION:    acpi_tb_release_owner_id
  *
- * PARAMETERS:  table_info          - A table info struct
+ * PARAMETERS:  table_index         - Table index
  *
- * RETURN:      None.
+ * RETURN:      Status
  *
- * DESCRIPTION: Low-level free for a single ACPI table.  Handles cases where
- *              the table was allocated a buffer or was mapped.
+ * DESCRIPTION: Releases owner_id in table_desc
  *
  ******************************************************************************/
 
-void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc)
+acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
 {
+	acpi_status status = AE_BAD_PARAMETER;
 
-	/* Must have a valid table descriptor and pointer */
+	ACPI_FUNCTION_TRACE(tb_release_owner_id);
 
-	if ((!table_desc) || (!table_desc->pointer)) {
-		return;
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (table_index < acpi_gbl_root_table_list.count) {
+		acpi_ut_release_owner_id(&
+					 (acpi_gbl_root_table_list.
+					  tables[table_index].owner_id));
+		status = AE_OK;
 	}
 
-	/* Valid table, determine type of memory allocation */
-
-	switch (table_desc->allocation) {
-	case ACPI_MEM_NOT_ALLOCATED:
-		break;
-
-	case ACPI_MEM_ALLOCATED:
-
-		ACPI_FREE(table_desc->pointer);
-		break;
-
-	case ACPI_MEM_MAPPED:
-
-		acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
-		break;
-
-	default:
-		break;
-	}
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_uninstall_table
+ * FUNCTION:    acpi_tb_get_owner_id
  *
- * PARAMETERS:  table_info          - A table info struct
+ * PARAMETERS:  table_index         - Table index
+ *              owner_id            - Where the table owner_id is returned
  *
- * RETURN:      Pointer to the next table in the list (of same type)
+ * RETURN:      Status
  *
- * DESCRIPTION: Free the memory associated with an internal ACPI table that
- *              is either installed or has never been installed.
- *              Table mutex should be locked.
+ * DESCRIPTION: returns owner_id for the ACPI table
  *
  ******************************************************************************/
 
-struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc
-						*table_desc)
+acpi_status
+acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
 {
-	struct acpi_table_desc *next_desc;
+	acpi_status status = AE_BAD_PARAMETER;
 
-	ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc);
+	ACPI_FUNCTION_TRACE(tb_get_owner_id);
 
-	if (!table_desc) {
-		return_PTR(NULL);
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (table_index < acpi_gbl_root_table_list.count) {
+		*owner_id =
+		    acpi_gbl_root_table_list.tables[table_index].owner_id;
+		status = AE_OK;
 	}
 
-	/* Unlink the descriptor from the doubly linked list */
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+	return_ACPI_STATUS(status);
+}
 
-	if (table_desc->prev) {
-		table_desc->prev->next = table_desc->next;
-	} else {
-		/* Is first on list, update list head */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_is_table_loaded
+ *
+ * PARAMETERS:  table_index         - Table index
+ *
+ * RETURN:      Table Loaded Flag
+ *
+ ******************************************************************************/
 
-		acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
-	}
+u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
+{
+	u8 is_loaded = FALSE;
 
-	if (table_desc->next) {
-		table_desc->next->prev = table_desc->prev;
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (table_index < acpi_gbl_root_table_list.count) {
+		is_loaded = (u8)
+		    (acpi_gbl_root_table_list.tables[table_index].
+		     flags & ACPI_TABLE_IS_LOADED);
 	}
 
-	/* Free the memory allocated for the table itself */
-
-	acpi_tb_delete_single_table(table_desc);
-
-	/* Free the owner ID associated with this table */
-
-	acpi_ut_release_owner_id(&table_desc->owner_id);
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+	return (is_loaded);
+}
 
-	/* Free the table descriptor */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_set_table_loaded_flag
+ *
+ * PARAMETERS:  table_index         - Table index
+ *              is_loaded           - TRUE if table is loaded, FALSE otherwise
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
+ *
+ ******************************************************************************/
 
-	next_desc = table_desc->next;
-	ACPI_FREE(table_desc);
+void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded)
+{
 
-	/* Return pointer to the next descriptor */
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (table_index < acpi_gbl_root_table_list.count) {
+		if (is_loaded) {
+			acpi_gbl_root_table_list.tables[table_index].flags |=
+			    ACPI_TABLE_IS_LOADED;
+		} else {
+			acpi_gbl_root_table_list.tables[table_index].flags &=
+			    ~ACPI_TABLE_IS_LOADED;
+		}
+	}
 
-	return_PTR(next_desc);
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 }
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
deleted file mode 100644
index 86a5fca9b739..000000000000
--- a/drivers/acpi/tables/tbrsdt.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/******************************************************************************
- *
- * Module Name: tbrsdt - ACPI RSDT table utilities
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2006, 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),
-					    ACPI_CAST_PTR(void, &rsdp));
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-		break;
-
-	default:
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-	}
-
-	/* Verify RSDP signature and checksum */
-
-	status = acpi_tb_validate_rsdp(rsdp);
-	if (ACPI_FAILURE(status)) {
-		goto cleanup;
-	}
-
-	/* RSDP is ok. Init the table info */
-
-	table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp);
-	table_info.length = sizeof(struct rsdp_descriptor);
-
-	if (address->pointer_type == ACPI_PHYSICAL_POINTER) {
-		table_info.allocation = ACPI_MEM_MAPPED;
-	} else {
-		table_info.allocation = ACPI_MEM_NOT_ALLOCATED;
-	}
-
-	/* Save the table pointers and allocation info */
-
-	status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_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:  out_address         - Where the address is returned
- *
- * RETURN:      None, Address
- *
- * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the
- *              version of the RSDP and whether the XSDT pointer is valid
- *
- ******************************************************************************/
-
-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;
-
-	/* Use XSDT if it is present */
-
-	if ((acpi_gbl_RSDP->revision >= 2) &&
-	    acpi_gbl_RSDP->xsdt_physical_address) {
-		out_address->pointer.value =
-		    acpi_gbl_RSDP->xsdt_physical_address;
-		acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT;
-	} else {
-		/* No XSDT, use the RSDT */
-
-		out_address->pointer.value =
-		    acpi_gbl_RSDP->rsdt_physical_address;
-		acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT;
-	}
-}
-
-/*******************************************************************************
- *
- * 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)
-{
-	char *signature;
-
-	ACPI_FUNCTION_ENTRY();
-
-	/* Validate minimum length */
-
-	if (table_ptr->length < sizeof(struct acpi_table_header)) {
-		ACPI_ERROR((AE_INFO,
-			    "RSDT/XSDT length (%X) is smaller than minimum (%zX)",
-			    table_ptr->length,
-			    sizeof(struct acpi_table_header)));
-
-		return (AE_INVALID_TABLE_LENGTH);
-	}
-
-	/* Search for appropriate signature, RSDT or XSDT */
-
-	if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
-		signature = RSDT_SIG;
-	} else {
-		signature = XSDT_SIG;
-	}
-
-	if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) {
-
-		/* Invalid RSDT or XSDT signature */
-
-		ACPI_ERROR((AE_INFO,
-			    "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:"));
-
-		ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20);
-
-		ACPI_ERROR((AE_INFO,
-			    "RSDT/XSDT signature at %X is invalid",
-			    acpi_gbl_RSDP->rsdt_physical_address));
-
-		if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
-			ACPI_ERROR((AE_INFO, "Looking for RSDT"));
-		} else {
-			ACPI_ERROR((AE_INFO, "Looking for XSDT"));
-		}
-
-		ACPI_DUMP_BUFFER(ACPI_CAST_PTR(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_ID_XSDT;
-	status = acpi_tb_get_table(&address, &table_info);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Could not get the RSDT/XSDT"));
-		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)) {
-		goto error_cleanup;
-	}
-
-	/* 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)) {
-		goto error_cleanup;
-	}
-
-	/* Save the table pointers and allocation info */
-
-	status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info);
-	if (ACPI_FAILURE(status)) {
-		goto error_cleanup;
-	}
-
-	acpi_gbl_XSDT =
-	    ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer);
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
-	return_ACPI_STATUS(status);
-
-      error_cleanup:
-
-	/* Free table allocated by acpi_tb_get_table */
-
-	acpi_tb_delete_single_table(&table_info);
-
-	return_ACPI_STATUS(status);
-}
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 209a401801e3..4a2f99e2fc44 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -1,11 +1,11 @@
 /******************************************************************************
  *
- * Module Name: tbutils - Table manipulation utilities
+ * Module Name: tbutils   - table utilities
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,137 +48,119 @@
 ACPI_MODULE_NAME("tbutils")
 
 /* Local prototypes */
-#ifdef ACPI_OBSOLETE_FUNCTIONS
-acpi_status
-acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc);
-#endif
+static acpi_physical_address
+acpi_tb_get_root_table_entry(u8 * table_entry,
+			     acpi_native_uint table_entry_size);
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_is_table_installed
- *
- * PARAMETERS:  new_table_desc      - Descriptor for new table being installed
+ * FUNCTION:    acpi_tb_tables_loaded
  *
- * RETURN:      Status - AE_ALREADY_EXISTS if the table is already installed
+ * PARAMETERS:  None
  *
- * DESCRIPTION: Determine if an ACPI table is already installed
+ * RETURN:      TRUE if required ACPI tables are loaded
  *
- * MUTEX:       Table data structures should be locked
+ * DESCRIPTION: Determine if the minimum required ACPI tables are present
+ *              (FADT, FACS, DSDT)
  *
  ******************************************************************************/
 
-acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc)
+u8 acpi_tb_tables_loaded(void)
 {
-	struct acpi_table_desc *table_desc;
-
-	ACPI_FUNCTION_TRACE(tb_is_table_installed);
 
-	/* Get the list descriptor and first table descriptor */
-
-	table_desc = acpi_gbl_table_lists[new_table_desc->type].next;
+	if (acpi_gbl_root_table_list.count >= 3) {
+		return (TRUE);
+	}
 
-	/* Examine all installed tables of this type */
+	return (FALSE);
+}
 
-	while (table_desc) {
-		/*
-		 * If the table lengths match, perform a full bytewise compare. This
-		 * means that we will allow tables with duplicate oem_table_id(s), as
-		 * long as the tables are different in some way.
-		 *
-		 * Checking if the table has been loaded into the namespace means that
-		 * we don't check for duplicate tables during the initial installation
-		 * of tables within the RSDT/XSDT.
-		 */
-		if ((table_desc->loaded_into_namespace) &&
-		    (table_desc->pointer->length ==
-		     new_table_desc->pointer->length)
-		    &&
-		    (!ACPI_MEMCMP
-		     (table_desc->pointer, new_table_desc->pointer,
-		      new_table_desc->pointer->length))) {
-
-			/* Match: this table is already installed */
-
-			ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
-					  "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n",
-					  new_table_desc->pointer->signature,
-					  new_table_desc->pointer->revision,
-					  new_table_desc->pointer->
-					  oem_table_id));
-
-			new_table_desc->owner_id = table_desc->owner_id;
-			new_table_desc->installed_desc = table_desc;
-
-			return_ACPI_STATUS(AE_ALREADY_EXISTS);
-		}
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_print_table_header
+ *
+ * PARAMETERS:  Address             - Table physical address
+ *              Header              - Table header
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
+ *
+ ******************************************************************************/
 
-		/* Get next table on the list */
+void
+acpi_tb_print_table_header(acpi_physical_address address,
+			   struct acpi_table_header *header)
+{
 
-		table_desc = table_desc->next;
+	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
+
+		/* FACS only has signature and length fields of common table header */
+
+		ACPI_INFO((AE_INFO, "%4.4s @ 0x%p/0x%04X",
+			   header->signature, ACPI_CAST_PTR(void, address),
+			   header->length));
+	} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
+
+		/* RSDP has no common fields */
+
+		ACPI_INFO((AE_INFO, "RSDP @ 0x%p/0x%04X (v%3.3d %6.6s)",
+			   ACPI_CAST_PTR(void, address),
+			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
+			    revision >
+			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
+					       header)->length : 20,
+			   ACPI_CAST_PTR(struct acpi_table_rsdp,
+					 header)->revision,
+			   ACPI_CAST_PTR(struct acpi_table_rsdp,
+					 header)->oem_id));
+	} else {
+		/* Standard ACPI table with full common header */
+
+		ACPI_INFO((AE_INFO,
+			   "%4.4s @ 0x%p/0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)",
+			   header->signature, ACPI_CAST_PTR(void, address),
+			   header->length, header->revision, header->oem_id,
+			   header->oem_table_id, header->oem_revision,
+			   header->asl_compiler_id,
+			   header->asl_compiler_revision));
 	}
-
-	return_ACPI_STATUS(AE_OK);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_validate_table_header
+ * FUNCTION:    acpi_tb_validate_checksum
  *
- * PARAMETERS:  table_header        - Logical pointer to the table
+ * PARAMETERS:  Table               - ACPI table to verify
+ *              Length              - Length of entire 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)
+ * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
+ *              exception on bad checksum.
  *
  ******************************************************************************/
 
-acpi_status
-acpi_tb_validate_table_header(struct acpi_table_header *table_header)
+acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
 {
-	acpi_name signature;
-
-	ACPI_FUNCTION_ENTRY();
-
-	/* Verify that this is a valid address */
-
-	if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) {
-		ACPI_ERROR((AE_INFO,
-			    "Cannot read table header at %p", table_header));
-
-		return (AE_BAD_ADDRESS);
-	}
+	u8 checksum;
 
-	/* Ensure that the signature is 4 ASCII characters */
+	/* Compute the checksum on the table */
 
-	ACPI_MOVE_32_TO_32(&signature, table_header->signature);
-	if (!acpi_ut_valid_acpi_name(signature)) {
-		ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X",
-			    signature));
+	checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
 
-		ACPI_DUMP_BUFFER(table_header,
-				 sizeof(struct acpi_table_header));
-		return (AE_BAD_SIGNATURE);
-	}
+	/* Checksum ok? (should be zero) */
 
-	/* Validate the table length */
+	if (checksum) {
+		ACPI_WARNING((AE_INFO,
+			      "Incorrect checksum in table [%4.4s] -  %2.2X, should be %2.2X",
+			      table->signature, table->checksum,
+			      (u8) (table->checksum - checksum)));
 
-	if (table_header->length < sizeof(struct acpi_table_header)) {
-		ACPI_ERROR((AE_INFO,
-			    "Invalid length 0x%X in table with signature %4.4s",
-			    (u32) table_header->length,
-			    ACPI_CAST_PTR(char, &signature)));
+#if (ACPI_CHECKSUM_ABORT)
 
-		ACPI_DUMP_BUFFER(table_header,
-				 sizeof(struct acpi_table_header));
-		return (AE_BAD_HEADER);
+		return (AE_BAD_CHECKSUM);
+#endif
 	}
 
 	return (AE_OK);
@@ -186,157 +168,320 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_sum_table
+ * FUNCTION:    acpi_tb_checksum
  *
- * PARAMETERS:  Buffer              - Buffer to sum
- *              Length              - Size of the buffer
+ * PARAMETERS:  Buffer          - Pointer to memory region to be checked
+ *              Length          - Length of this memory region
  *
- * RETURN:      8 bit sum of buffer
+ * RETURN:      Checksum (u8)
  *
- * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it.
+ * DESCRIPTION: Calculates circular checksum of memory region.
  *
  ******************************************************************************/
 
-u8 acpi_tb_sum_table(void *buffer, u32 length)
+u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
 {
-	acpi_native_uint i;
 	u8 sum = 0;
+	u8 *end = buffer + length;
 
-	if (!buffer || !length) {
-		return (0);
+	while (buffer < end) {
+		sum = (u8) (sum + *(buffer++));
 	}
 
-	for (i = 0; i < length; i++) {
-		sum = (u8) (sum + ((u8 *) buffer)[i]);
-	}
-	return (sum);
+	return sum;
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_generate_checksum
+ * FUNCTION:    acpi_tb_install_table
  *
- * PARAMETERS:  Table               - Pointer to a valid ACPI table (with a
- *                                    standard ACPI header)
+ * PARAMETERS:  Address                 - Physical address of DSDT or FACS
+ *              Flags                   - Flags
+ *              Signature               - Table signature, NULL if no need to
+ *                                        match
+ *              table_index             - Index into root table array
  *
- * RETURN:      8 bit checksum of buffer
+ * RETURN:      None
  *
- * DESCRIPTION: Computes an 8 bit checksum of the table.
+ * DESCRIPTION: Install an ACPI table into the global data structure.
  *
  ******************************************************************************/
 
-u8 acpi_tb_generate_checksum(struct acpi_table_header * table)
+void
+acpi_tb_install_table(acpi_physical_address address,
+		      u8 flags, char *signature, acpi_native_uint table_index)
 {
-	u8 checksum;
+	struct acpi_table_header *table;
+
+	if (!address) {
+		ACPI_ERROR((AE_INFO,
+			    "Null physical address for ACPI table [%s]",
+			    signature));
+		return;
+	}
+
+	/* Map just the table header */
+
+	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+	if (!table) {
+		return;
+	}
+
+	/* If a particular signature is expected, signature must match */
+
+	if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
+		ACPI_ERROR((AE_INFO,
+			    "Invalid signature 0x%X for ACPI table [%s]",
+			    *ACPI_CAST_PTR(u32, table->signature), signature));
+		goto unmap_and_exit;
+	}
 
-	/* Sum the entire table as-is */
+	/* Initialize the table entry */
 
-	checksum = acpi_tb_sum_table(table, table->length);
+	acpi_gbl_root_table_list.tables[table_index].address = address;
+	acpi_gbl_root_table_list.tables[table_index].length = table->length;
+	acpi_gbl_root_table_list.tables[table_index].flags = flags;
 
-	/* Subtract off the existing checksum value in the table */
+	ACPI_MOVE_32_TO_32(&
+			   (acpi_gbl_root_table_list.tables[table_index].
+			    signature), table->signature);
 
-	checksum = (u8) (checksum - table->checksum);
+	acpi_tb_print_table_header(address, table);
 
-	/* Compute the final checksum */
+	if (table_index == ACPI_TABLE_INDEX_DSDT) {
 
-	checksum = (u8) (0 - checksum);
-	return (checksum);
+		/* Global integer width is based upon revision of the DSDT */
+
+		acpi_ut_set_integer_width(table->revision);
+	}
+
+      unmap_and_exit:
+	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_set_checksum
+ * FUNCTION:    acpi_tb_get_root_table_entry
  *
- * PARAMETERS:  Table               - Pointer to a valid ACPI table (with a
- *                                    standard ACPI header)
+ * PARAMETERS:  table_entry         - Pointer to the RSDT/XSDT table entry
+ *              table_entry_size    - sizeof 32 or 64 (RSDT or XSDT)
  *
- * RETURN:      None. Sets the table checksum field
+ * RETURN:      Physical address extracted from the root table
  *
- * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the
- *              checksum into the table header.
+ * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
+ *              both 32-bit and 64-bit platforms
+ *
+ * NOTE:        acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on
+ *              64-bit platforms.
  *
  ******************************************************************************/
 
-void acpi_tb_set_checksum(struct acpi_table_header *table)
+static acpi_physical_address
+acpi_tb_get_root_table_entry(u8 * table_entry,
+			     acpi_native_uint table_entry_size)
 {
+	u64 address64;
+
+	/*
+	 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
+	 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
+	 */
+	if (table_entry_size == sizeof(u32)) {
+		/*
+		 * 32-bit platform, RSDT: Return 32-bit table entry
+		 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
+		 */
+		return ((acpi_physical_address)
+			(*ACPI_CAST_PTR(u32, table_entry)));
+	} else {
+		/*
+		 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
+		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
+		 */
+		ACPI_MOVE_64_TO_64(&address64, table_entry);
 
-	table->checksum = acpi_tb_generate_checksum(table);
+#if ACPI_MACHINE_WIDTH == 32
+		if (address64 > ACPI_UINT32_MAX) {
+
+			/* Will truncate 64-bit address to 32 bits, issue warning */
+
+			ACPI_WARNING((AE_INFO,
+				      "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
+				      ACPI_FORMAT_UINT64(address64)));
+		}
+#endif
+		return ((acpi_physical_address) (address64));
+	}
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_verify_table_checksum
+ * FUNCTION:    acpi_tb_parse_root_table
+ *
+ * PARAMETERS:  Rsdp                    - Pointer to the RSDP
+ *              Flags                   - Flags
  *
- * PARAMETERS:  *table_header           - ACPI table to verify
+ * RETURN:      Status
  *
- * RETURN:      8 bit checksum of table
+ * DESCRIPTION: This function is called to parse the Root System Description
+ *              Table (RSDT or XSDT)
  *
- * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares
- *              it to the existing checksum value.
+ * NOTE:        Tables are mapped (not copied) for efficiency. The FACS must
+ *              be mapped and cannot be copied because it contains the actual
+ *              memory location of the ACPI Global Lock.
  *
  ******************************************************************************/
 
-acpi_status
-acpi_tb_verify_table_checksum(struct acpi_table_header *table_header)
+acpi_status __init
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
 {
-	u8 checksum;
+	struct acpi_table_rsdp *rsdp;
+	acpi_native_uint table_entry_size;
+	acpi_native_uint i;
+	u32 table_count;
+	struct acpi_table_header *table;
+	acpi_physical_address address;
+	u32 length;
+	u8 *table_entry;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(tb_parse_root_table);
+
+	/*
+	 * Map the entire RSDP and extract the address of the RSDT or XSDT
+	 */
+	rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp));
+	if (!rsdp) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
 
-	ACPI_FUNCTION_TRACE(tb_verify_table_checksum);
+	acpi_tb_print_table_header(rsdp_address,
+				   ACPI_CAST_PTR(struct acpi_table_header,
+						 rsdp));
 
-	/* Compute the checksum on the table */
+	/* Differentiate between RSDT and XSDT root tables */
 
-	checksum = acpi_tb_generate_checksum(table_header);
+	if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
+		/*
+		 * Root table is an XSDT (64-bit physical addresses). We must use the
+		 * XSDT if the revision is > 1 and the XSDT pointer is present, as per
+		 * the ACPI specification.
+		 */
+		address = (acpi_physical_address) rsdp->xsdt_physical_address;
+		table_entry_size = sizeof(u64);
+	} else {
+		/* Root table is an RSDT (32-bit physical addresses) */
 
-	/* Checksum ok? */
+		address = (acpi_physical_address) rsdp->rsdt_physical_address;
+		table_entry_size = sizeof(u32);
+	}
 
-	if (checksum == table_header->checksum) {
-		return_ACPI_STATUS(AE_OK);
+	/*
+	 * It is not possible to map more than one entry in some environments,
+	 * so unmap the RSDP here before mapping other tables
+	 */
+	acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
+
+	/* Map the RSDT/XSDT table header to get the full table length */
+
+	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+	if (!table) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	ACPI_WARNING((AE_INFO,
-		      "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X",
-		      table_header->signature, table_header->checksum,
-		      checksum));
+	acpi_tb_print_table_header(address, table);
 
-	return_ACPI_STATUS(AE_BAD_CHECKSUM);
-}
+	/* Get the length of the full table, verify length and map entire table */
 
-#ifdef ACPI_OBSOLETE_FUNCTIONS
-/*******************************************************************************
- *
- * 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.
- *
- ******************************************************************************/
+	length = table->length;
+	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
 
-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;
+	if (length < sizeof(struct acpi_table_header)) {
+		ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT",
+			    length));
+		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+	}
 
-	ACPI_FUNCTION_NAME(tb_handle_to_object);
+	table = acpi_os_map_memory(address, length);
+	if (!table) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	/* Validate the root table checksum */
+
+	status = acpi_tb_verify_checksum(table, length);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_unmap_memory(table, length);
+		return_ACPI_STATUS(status);
+	}
 
-	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);
+	/* Calculate the number of tables described in the root table */
+
+	table_count =
+	    (u32) ((table->length -
+		    sizeof(struct acpi_table_header)) / table_entry_size);
+
+	/*
+	 * First two entries in the table array are reserved for the DSDT and FACS,
+	 * which are not actually present in the RSDT/XSDT - they come from the FADT
+	 */
+	table_entry =
+	    ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
+	acpi_gbl_root_table_list.count = 2;
+
+	/*
+	 * Initialize the root table array from the RSDT/XSDT
+	 */
+	for (i = 0; i < table_count; i++) {
+		if (acpi_gbl_root_table_list.count >=
+		    acpi_gbl_root_table_list.size) {
+
+			/* There is no more room in the root table array, attempt resize */
+
+			status = acpi_tb_resize_root_table_list();
+			if (ACPI_FAILURE(status)) {
+				ACPI_WARNING((AE_INFO,
+					      "Truncating %u table entries!",
+					      (unsigned)
+					      (acpi_gbl_root_table_list.size -
+					       acpi_gbl_root_table_list.
+					       count)));
+				break;
 			}
+		}
+
+		/* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
 
-			table_desc = table_desc->next;
+		acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
+		    address =
+		    acpi_tb_get_root_table_entry(table_entry, table_entry_size);
+
+		table_entry += table_entry_size;
+		acpi_gbl_root_table_list.count++;
+	}
+
+	/*
+	 * It is not possible to map more than one entry in some environments,
+	 * so unmap the root table here before mapping other tables
+	 */
+	acpi_os_unmap_memory(table, length);
+
+	/*
+	 * Complete the initialization of the root table array by examining
+	 * the header of each table
+	 */
+	for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
+		acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
+				      address, flags, NULL, i);
+
+		/* Special case for FADT - get the DSDT and FACS */
+
+		if (ACPI_COMPARE_NAME
+		    (&acpi_gbl_root_table_list.tables[i].signature,
+		     ACPI_SIG_FADT)) {
+			acpi_tb_parse_fadt(i, flags);
 		}
 	}
 
-	ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id));
-	return (AE_BAD_PARAMETER);
+	return_ACPI_STATUS(AE_OK);
 }
-#endif
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 5ba9303293ad..807978d5381a 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,80 +49,158 @@
 #define _COMPONENT          ACPI_TABLES
 ACPI_MODULE_NAME("tbxface")
 
+/* Local prototypes */
+static acpi_status acpi_tb_load_namespace(void);
+
 /*******************************************************************************
  *
- * FUNCTION:    acpi_load_tables
+ * FUNCTION:    acpi_allocate_root_table
  *
- * PARAMETERS:  None
+ * PARAMETERS:  initial_table_count - Size of initial_table_array, in number of
+ *                                    struct acpi_table_desc structures
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to load the ACPI tables from the
- *              provided RSDT
+ * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and
+ *              acpi_initialize_tables.
  *
  ******************************************************************************/
-acpi_status acpi_load_tables(void)
+
+acpi_status acpi_allocate_root_table(u32 initial_table_count)
 {
-	struct acpi_pointer rsdp_address;
-	acpi_status status;
 
-	ACPI_FUNCTION_TRACE(acpi_load_tables);
+	acpi_gbl_root_table_list.size = initial_table_count;
+	acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE;
 
-	/* Get the RSDP */
+	return (acpi_tb_resize_root_table_list());
+}
 
-	status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING,
-					  &rsdp_address);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP"));
-		goto error_exit;
-	}
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_tables
+ *
+ * PARAMETERS:  initial_table_array - Pointer to an array of pre-allocated
+ *                                    struct acpi_table_desc structures. If NULL, the
+ *                                    array is dynamically allocated.
+ *              initial_table_count - Size of initial_table_array, in number of
+ *                                    struct acpi_table_desc structures
+ *              allow_realloc       - Flag to tell Table Manager if resize of
+ *                                    pre-allocated array is allowed. Ignored
+ *                                    if initial_table_array is NULL.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
+ *
+ * NOTE:        Allows static allocation of the initial table array in order
+ *              to avoid the use of dynamic memory in confined environments
+ *              such as the kernel boot sequence where it may not be available.
+ *
+ *              If the host OS memory managers are initialized, use NULL for
+ *              initial_table_array, and the table will be dynamically allocated.
+ *
+ ******************************************************************************/
 
-	/* Map and validate the RSDP */
+acpi_status __init
+acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
+		       u32 initial_table_count, u8 allow_resize)
+{
+	acpi_physical_address rsdp_address;
+	acpi_status status;
 
-	acpi_gbl_table_flags = rsdp_address.pointer_type;
+	ACPI_FUNCTION_TRACE(acpi_initialize_tables);
 
-	status = acpi_tb_verify_rsdp(&rsdp_address);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation"));
-		goto error_exit;
+	/*
+	 * Set up the Root Table Array
+	 * Allocate the table array if requested
+	 */
+	if (!initial_table_array) {
+		status = acpi_allocate_root_table(initial_table_count);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	} else {
+		/* Root Table Array has been statically allocated by the host */
+
+		ACPI_MEMSET(initial_table_array, 0,
+			    initial_table_count *
+			    sizeof(struct acpi_table_desc));
+
+		acpi_gbl_root_table_list.tables = initial_table_array;
+		acpi_gbl_root_table_list.size = initial_table_count;
+		acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN;
+		if (allow_resize) {
+			acpi_gbl_root_table_list.flags |=
+			    ACPI_ROOT_ALLOW_RESIZE;
+		}
 	}
 
-	/* Get the RSDT via the RSDP */
+	/* Get the address of the RSDP */
 
-	status = acpi_tb_get_table_rsdt();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT"));
-		goto error_exit;
+	rsdp_address = acpi_os_get_root_pointer();
+	if (!rsdp_address) {
+		return_ACPI_STATUS(AE_NOT_FOUND);
 	}
 
-	/* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */
+	/*
+	 * Get the root table (RSDT or XSDT) and extract all entries to the local
+	 * Root Table Array. This array contains the information of the RSDT/XSDT
+	 * in a common, more useable format.
+	 */
+	status =
+	    acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
+	return_ACPI_STATUS(status);
+}
 
-	status = acpi_tb_get_required_tables();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Could not get all required tables (DSDT/FADT/FACS)"));
-		goto error_exit;
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_reallocate_root_table
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
+ *              root list from the previously provided scratch area. Should
+ *              be called once dynamic memory allocation is available in the
+ *              kernel
+ *
+ ******************************************************************************/
+acpi_status acpi_reallocate_root_table(void)
+{
+	struct acpi_table_desc *tables;
+	acpi_size new_size;
+
+	ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
+
+	/*
+	 * Only reallocate the root table if the host provided a static buffer
+	 * for the table array in the call to acpi_initialize_tables.
+	 */
+	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
+		return_ACPI_STATUS(AE_SUPPORT);
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
+	new_size =
+	    (acpi_gbl_root_table_list.count +
+	     ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
 
-	/* Load the namespace from the tables */
+	/* Create new array and copy the old array */
 
-	status = acpi_ns_load_namespace();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace"));
-		goto error_exit;
+	tables = ACPI_ALLOCATE_ZEROED(new_size);
+	if (!tables) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size);
 
-      error_exit:
-	ACPI_EXCEPTION((AE_INFO, status, "Could not load tables"));
-	return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_load_tables)
+	acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count;
+	acpi_gbl_root_table_list.tables = tables;
+	acpi_gbl_root_table_list.flags =
+	    ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
 
+	return_ACPI_STATUS(AE_OK);
+}
 /*******************************************************************************
  *
  * FUNCTION:    acpi_load_table
@@ -141,342 +219,405 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables)
 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 */
+	acpi_native_uint table_index;
+	struct acpi_table_desc table_desc;
 
-	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);
-	}
-
-	/* Check signature for a valid table type */
-
-	status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	if (!table_ptr)
+		return AE_BAD_PARAMETER;
 
-	/* Install the new table into the local data structures */
+	ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
+	table_desc.pointer = table_ptr;
+	table_desc.length = table_ptr->length;
+	table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN;
 
-	status = acpi_tb_install_table(&table_info);
+	/*
+	 * Install the new table into the local data structures
+	 */
+	status = acpi_tb_add_table(&table_desc, &table_index);
 	if (ACPI_FAILURE(status)) {
-		if (status == AE_ALREADY_EXISTS) {
-
-			/* Table already exists, no error */
-
-			status = AE_OK;
-		}
-
-		/* Free table allocated by acpi_tb_get_table_body */
-
-		acpi_tb_delete_single_table(&table_info);
-		return_ACPI_STATUS(status);
+		return status;
 	}
+	status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
+	return status;
+}
 
-	/* Convert the table to common format if necessary */
-
-	switch (table_info.type) {
-	case ACPI_TABLE_ID_FADT:
-
-		status = acpi_tb_convert_table_fadt();
-		break;
-
-	case ACPI_TABLE_ID_FACS:
+ACPI_EXPORT_SYMBOL(acpi_load_table)
 
-		status = acpi_tb_build_common_facs(&table_info);
-		break;
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_get_table_header
+ *
+ * PARAMETERS:  Signature           - ACPI signature of needed table
+ *              Instance            - Which instance (for SSDTs)
+ *              out_table_header    - The pointer to the table header to fill
+ *
+ * RETURN:      Status and pointer to mapped table header
+ *
+ * DESCRIPTION: Finds an ACPI table header.
+ *
+ * NOTE:        Caller is responsible in unmapping the header with
+ *              acpi_os_unmap_memory
+ *
+ *****************************************************************************/
+acpi_status
+acpi_get_table_header(char *signature,
+		      acpi_native_uint instance,
+		      struct acpi_table_header *out_table_header)
+{
+	acpi_native_uint i;
+	acpi_native_uint j;
+	struct acpi_table_header *header;
 
-	default:
-		/* Load table into namespace if it contains executable AML */
+	/* Parameter validation */
 
-		status =
-		    acpi_ns_load_table(table_info.installed_desc,
-				       acpi_gbl_root_node);
-		break;
+	if (!signature || !out_table_header) {
+		return (AE_BAD_PARAMETER);
 	}
 
-	if (ACPI_FAILURE(status)) {
+	/*
+	 * Walk the root table list
+	 */
+	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
+		if (!ACPI_COMPARE_NAME
+		    (&(acpi_gbl_root_table_list.tables[i].signature),
+		     signature)) {
+			continue;
+		}
 
-		/* Uninstall table and free the buffer */
+		if (++j < instance) {
+			continue;
+		}
 
-		(void)acpi_tb_uninstall_table(table_info.installed_desc);
+		if (!acpi_gbl_root_table_list.tables[i].pointer) {
+			if ((acpi_gbl_root_table_list.tables[i].
+			     flags & ACPI_TABLE_ORIGIN_MASK) ==
+			    ACPI_TABLE_ORIGIN_MAPPED) {
+				header =
+				    acpi_os_map_memory(acpi_gbl_root_table_list.
+						       tables[i].address,
+						       sizeof(struct
+							      acpi_table_header));
+				if (!header) {
+					return AE_NO_MEMORY;
+				}
+				ACPI_MEMCPY(out_table_header, header,
+					    sizeof(struct acpi_table_header));
+				acpi_os_unmap_memory(header,
+						     sizeof(struct
+							    acpi_table_header));
+			} else {
+				return AE_NOT_FOUND;
+			}
+		} else {
+			ACPI_MEMCPY(out_table_header,
+				    acpi_gbl_root_table_list.tables[i].pointer,
+				    sizeof(struct acpi_table_header));
+		}
+		return (AE_OK);
 	}
 
-	return_ACPI_STATUS(status);
+	return (AE_NOT_FOUND);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_load_table)
+ACPI_EXPORT_SYMBOL(acpi_get_table_header)
 
-/*******************************************************************************
+
+/******************************************************************************
  *
  * FUNCTION:    acpi_unload_table_id
  *
- * PARAMETERS:  table_type    - Type of table to be unloaded
- *              id            - Owner ID of the table to be removed.
+ * PARAMETERS:  id            - Owner ID of the table to be removed.
  *
  * RETURN:      Status
  *
  * DESCRIPTION: This routine is used to force the unload of a table (by id)
  *
  ******************************************************************************/
-acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id)
+acpi_status acpi_unload_table_id(acpi_owner_id id)
 {
-	struct acpi_table_desc *table_desc;
-	acpi_status status;
+	int i;
+	acpi_status status = AE_NOT_EXIST;
 
 	ACPI_FUNCTION_TRACE(acpi_unload_table);
 
-	/* Parameter validation */
-	if (table_type > ACPI_TABLE_ID_MAX)
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
-
 	/* Find table from the requested type list */
-	table_desc = acpi_gbl_table_lists[table_type].next;
-	while (table_desc && table_desc->owner_id != id)
-		table_desc = table_desc->next;
-
-	if (!table_desc)
-		return_ACPI_STATUS(AE_NOT_EXIST);
-
-	/*
-	 * Delete all namespace objects owned by this table. Note that these
-	 * objects 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->owner_id);
-
-	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
-	if (ACPI_FAILURE(status))
-		return_ACPI_STATUS(status);
-
-	(void)acpi_tb_uninstall_table(table_desc);
-
-	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-
-	return_ACPI_STATUS(AE_OK);
+	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
+		if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
+			continue;
+		}
+		/*
+		* Delete all namespace objects owned by this table. Note that these
+		* objects 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_tb_delete_namespace_by_owner(i);
+		acpi_tb_release_owner_id(i);
+		acpi_tb_set_table_loaded_flag(i, FALSE);
+	}
+	return_ACPI_STATUS(status);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
- * FUNCTION:    acpi_unload_table
+ * FUNCTION:    acpi_get_table
  *
- * PARAMETERS:  table_type    - Type of table to be unloaded
+ * PARAMETERS:  Signature           - ACPI signature of needed table
+ *              Instance            - Which instance (for SSDTs)
+ *              out_table           - Where the pointer to the table is returned
  *
- * RETURN:      Status
+ * RETURN:      Status and pointer to table
  *
- * DESCRIPTION: This routine is used to force the unload of a table
+ * DESCRIPTION: Finds and verifies an ACPI table.
  *
- ******************************************************************************/
-acpi_status acpi_unload_table(acpi_table_type table_type)
+ *****************************************************************************/
+acpi_status
+acpi_get_table(char *signature,
+	       acpi_native_uint instance, struct acpi_table_header ** out_table)
 {
-	struct acpi_table_desc *table_desc;
-
-	ACPI_FUNCTION_TRACE(acpi_unload_table);
+	acpi_native_uint i;
+	acpi_native_uint j;
+	acpi_status status;
 
 	/* Parameter validation */
 
-	if (table_type > ACPI_TABLE_ID_MAX) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	if (!signature || !out_table) {
+		return (AE_BAD_PARAMETER);
 	}
 
-	/* Find all tables of the requested type */
+	/*
+	 * Walk the root table list
+	 */
+	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
+		if (!ACPI_COMPARE_NAME
+		    (&(acpi_gbl_root_table_list.tables[i].signature),
+		     signature)) {
+			continue;
+		}
 
-	table_desc = acpi_gbl_table_lists[table_type].next;
-	if (!table_desc) {
-		return_ACPI_STATUS(AE_NOT_EXIST);
-	}
+		if (++j < instance) {
+			continue;
+		}
 
-	while (table_desc) {
-		/*
-		 * Delete all namespace objects owned by this table. Note that these
-		 * objects 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->owner_id);
-		table_desc = table_desc->next;
-	}
+		status =
+		    acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
+		if (ACPI_SUCCESS(status)) {
+			*out_table = acpi_gbl_root_table_list.tables[i].pointer;
+		}
 
-	/* Delete (or unmap) all tables of this type */
+		if (!acpi_gbl_permanent_mmap) {
+			acpi_gbl_root_table_list.tables[i].pointer = 0;
+		}
 
-	acpi_tb_delete_tables_by_type(table_type);
-	return_ACPI_STATUS(AE_OK);
+		return (status);
+	}
+
+	return (AE_NOT_FOUND);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_unload_table)
+ACPI_EXPORT_SYMBOL(acpi_get_table)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_table_header
+ * FUNCTION:    acpi_get_table_by_index
  *
- * 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
+ * PARAMETERS:  table_index         - Table index
+ *              Table               - Where the pointer to the table is returned
  *
- * 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.
+ * RETURN:      Status and pointer to the table
  *
- *              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.
+ * DESCRIPTION: Obtain a table by an index into the global table list.
  *
  ******************************************************************************/
 acpi_status
-acpi_get_table_header(acpi_table_type table_type,
-		      u32 instance, struct acpi_table_header *out_table_header)
+acpi_get_table_by_index(acpi_native_uint table_index,
+			struct acpi_table_header ** table)
 {
-	struct acpi_table_header *tbl_ptr;
 	acpi_status status;
 
-	ACPI_FUNCTION_TRACE(acpi_get_table_header);
+	ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
+
+	/* Parameter validation */
 
-	if ((instance == 0) ||
-	    (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) {
+	if (!table) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Check the table type and instance */
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+
+	/* Validate index */
 
-	if ((table_type > ACPI_TABLE_ID_MAX) ||
-	    (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) &&
-	     instance > 1)) {
+	if (table_index >= acpi_gbl_root_table_list.count) {
+		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Get a pointer to the entire table */
+	if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
 
-	status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+		/* Table is not mapped, map it */
 
-	/* The function will return a NULL pointer if the table is not loaded */
-
-	if (tbl_ptr == NULL) {
-		return_ACPI_STATUS(AE_NOT_EXIST);
+		status =
+		    acpi_tb_verify_table(&acpi_gbl_root_table_list.
+					 tables[table_index]);
+		if (ACPI_FAILURE(status)) {
+			(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+			return_ACPI_STATUS(status);
+		}
 	}
 
-	/* Copy the header to the caller's buffer */
-
-	ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header),
-		    ACPI_CAST_PTR(void, tbl_ptr),
-		    sizeof(struct acpi_table_header));
-
-	return_ACPI_STATUS(status);
+	*table = acpi_gbl_root_table_list.tables[table_index].pointer;
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+	return_ACPI_STATUS(AE_OK);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_get_table_header)
-#endif				/*  ACPI_FUTURE_USAGE  */
+ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_table
+ * FUNCTION:    acpi_tb_load_namespace
  *
- * 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
+ * PARAMETERS:  None
  *
  * 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.
+ * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
+ *              the RSDT/XSDT.
  *
  ******************************************************************************/
-acpi_status
-acpi_get_table(acpi_table_type table_type,
-	       u32 instance, struct acpi_buffer *ret_buffer)
+static acpi_status acpi_tb_load_namespace(void)
 {
-	struct acpi_table_header *tbl_ptr;
 	acpi_status status;
-	acpi_size table_length;
+	struct acpi_table_header *table;
+	acpi_native_uint i;
 
-	ACPI_FUNCTION_TRACE(acpi_get_table);
+	ACPI_FUNCTION_TRACE(tb_load_namespace);
 
-	/* Parameter validation */
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-	if (instance == 0) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	/*
+	 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
+	 * are optional.
+	 */
+	if (!acpi_gbl_root_table_list.count ||
+	    !ACPI_COMPARE_NAME(&
+			       (acpi_gbl_root_table_list.
+				tables[ACPI_TABLE_INDEX_DSDT].signature),
+			       ACPI_SIG_DSDT)
+	    ||
+	    ACPI_FAILURE(acpi_tb_verify_table
+			 (&acpi_gbl_root_table_list.
+			  tables[ACPI_TABLE_INDEX_DSDT]))) {
+		status = AE_NO_ACPI_TABLES;
+		goto unlock_and_exit;
 	}
 
-	status = acpi_ut_validate_buffer(ret_buffer);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+	/*
+	 * Find DSDT table
+	 */
+	status =
+	    acpi_os_table_override(acpi_gbl_root_table_list.
+				   tables[ACPI_TABLE_INDEX_DSDT].pointer,
+				   &table);
+	if (ACPI_SUCCESS(status) && table) {
+		/*
+		 * DSDT table has been found
+		 */
+		acpi_tb_delete_table(&acpi_gbl_root_table_list.
+				     tables[ACPI_TABLE_INDEX_DSDT]);
+		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
+		    table;
+		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
+		    table->length;
+		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
+		    ACPI_TABLE_ORIGIN_UNKNOWN;
+
+		ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
+		acpi_tb_print_table_header(0, table);
 	}
 
-	/* Check the table type and instance */
+	status =
+	    acpi_tb_verify_table(&acpi_gbl_root_table_list.
+				 tables[ACPI_TABLE_INDEX_DSDT]);
+	if (ACPI_FAILURE(status)) {
 
-	if ((table_type > ACPI_TABLE_ID_MAX) ||
-	    (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) &&
-	     instance > 1)) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
+		/* A valid DSDT is required */
+
+		status = AE_NO_ACPI_TABLES;
+		goto unlock_and_exit;
 	}
 
-	/* Get a pointer to the entire table */
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 
-	status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr);
+	/*
+	 * Load and parse tables.
+	 */
+	status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
 	/*
-	 * acpi_tb_get_table_ptr will return a NULL pointer if the
-	 * table is not loaded.
+	 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
 	 */
-	if (tbl_ptr == NULL) {
-		return_ACPI_STATUS(AE_NOT_EXIST);
+	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
+		if ((!ACPI_COMPARE_NAME
+		     (&(acpi_gbl_root_table_list.tables[i].signature),
+		      ACPI_SIG_SSDT)
+		     &&
+		     !ACPI_COMPARE_NAME(&
+					(acpi_gbl_root_table_list.tables[i].
+					 signature), ACPI_SIG_PSDT))
+		    ||
+		    ACPI_FAILURE(acpi_tb_verify_table
+				 (&acpi_gbl_root_table_list.tables[i]))) {
+			continue;
+		}
+
+		/* Ignore errors while loading tables, get as many as possible */
+
+		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+		(void)acpi_ns_load_table(i, acpi_gbl_root_node);
+		(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	}
 
-	/* Get the table length */
+	ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
 
-	if (table_type == ACPI_TABLE_ID_RSDP) {
+      unlock_and_exit:
+	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+	return_ACPI_STATUS(status);
+}
 
-		/* RSD PTR is the only "table" without a header */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_load_tables
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
+ *
+ ******************************************************************************/
 
-		table_length = sizeof(struct rsdp_descriptor);
-	} else {
-		table_length = (acpi_size) tbl_ptr->length;
-	}
+acpi_status acpi_load_tables(void)
+{
+	acpi_status status;
 
-	/* Validate/Allocate/Clear caller buffer */
+	ACPI_FUNCTION_TRACE(acpi_load_tables);
 
-	status = acpi_ut_initialize_buffer(ret_buffer, table_length);
+	/*
+	 * Load the namespace from the tables
+	 */
+	status = acpi_tb_load_namespace();
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+		ACPI_EXCEPTION((AE_INFO, status,
+				"While loading namespace from ACPI tables"));
 	}
 
-	/* Copy the table to the buffer */
-
-	ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer),
-		    ACPI_CAST_PTR(void, tbl_ptr), table_length);
-
-	return_ACPI_STATUS(AE_OK);
+	return_ACPI_STATUS(status);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_get_table)
+ACPI_EXPORT_SYMBOL(acpi_load_tables)
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index da2648bbdbc0..cf8fa514189f 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,16 +48,15 @@
 ACPI_MODULE_NAME("tbxfroot")
 
 /* Local prototypes */
-static acpi_status
-acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags);
-
 static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
 
+static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_validate_rsdp
  *
- * PARAMETERS:  Rsdp        - Pointer to unvalidated RSDP
+ * PARAMETERS:  Rsdp                - Pointer to unvalidated RSDP
  *
  * RETURN:      Status
  *
@@ -65,14 +64,18 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
  *
  ******************************************************************************/
 
-acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp)
+static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
 {
 	ACPI_FUNCTION_ENTRY();
 
 	/*
-	 *  The signature and checksum must both be correct
+	 * The signature and checksum must both be correct
+	 *
+	 * Note: Sometimes there exists more than one RSDP in memory; the valid
+	 * RSDP has a valid checksum, all others have an invalid checksum.
 	 */
-	if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) {
+	if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
+	    != 0) {
 
 		/* Nope, BAD Signature */
 
@@ -81,14 +84,14 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp)
 
 	/* Check the standard checksum */
 
-	if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
+	if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
 		return (AE_BAD_CHECKSUM);
 	}
 
 	/* Check extended checksum if table version >= 2 */
 
 	if ((rsdp->revision >= 2) &&
-	    (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
+	    (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
 		return (AE_BAD_CHECKSUM);
 	}
 
@@ -97,314 +100,123 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp)
 
 /*******************************************************************************
  *
- * 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
- *              table_ptr           - Where the table pointer is returned
- *
- * RETURN:      Status
+ * FUNCTION:    acpi_tb_find_rsdp
  *
- * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
- *              Signature, OEM ID and OEM Table ID.
+ * PARAMETERS:  table_address           - Where the table pointer is returned
  *
- ******************************************************************************/
-
-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_COMPARE_NAME(signature, DSDT_SIG)) {
-		/*
-		 * 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
+ * RETURN:      Status, RSDP physical address
  *
- * 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
+ * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
+ *              pointer structure.  If it is found, set *RSDP to point to it.
  *
- * RETURN:      Status
+ * 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.
  *
- * 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.
+ * NOTE2:       This function is always available, regardless of the
+ *              initialization state of the rest of ACPI.
  *
  ******************************************************************************/
 
-acpi_status
-acpi_get_firmware_table(acpi_string signature,
-			u32 instance,
-			u32 flags, struct acpi_table_header **table_pointer)
+acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
 {
-	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 RDSP signature and checksum must both be correct */
-
-		status = acpi_tb_validate_rsdp(acpi_gbl_RSDP);
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-
-	/* 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)));
+	u8 *table_ptr;
+	u8 *mem_rover;
+	u32 physical_address;
 
-	/* Insert processor_mode flags */
+	ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
 
-	address.pointer_type |= flags;
+	/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
 
-	/* Get and validate the RSDT */
+	table_ptr = acpi_os_map_memory((acpi_physical_address)
+				       ACPI_EBDA_PTR_LOCATION,
+				       ACPI_EBDA_PTR_LENGTH);
+	if (!table_ptr) {
+		ACPI_ERROR((AE_INFO,
+			    "Could not map memory at %8.8X for length %X",
+			    ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
 
-	rsdt_info = ACPI_ALLOCATE_ZEROED(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;
-	}
+	ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
 
-	/* Allocate a scratch table header and table descriptor */
+	/* Convert segment part to physical address */
 
-	header = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
-	if (!header) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
+	physical_address <<= 4;
+	acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
 
-	table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc));
-	if (!table_info) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
+	/* EBDA present? */
 
-	/* 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++) {
+	if (physical_address > 0x400) {
 		/*
-		 * Get the next table pointer, handle RSDT vs. XSDT
-		 * RSDT pointers are 32 bits, XSDT pointers are 64 bits
+		 * 1b) Search EBDA paragraphs (EBDA is required to be a
+		 *     minimum of 1_k length)
 		 */
-		if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
-			address.pointer.value =
-			    (ACPI_CAST_PTR
-			     (struct rsdt_descriptor,
-			      rsdt_info->pointer))->table_offset_entry[i];
-		} else {
-			address.pointer.value =
-			    (ACPI_CAST_PTR
-			     (struct xsdt_descriptor,
-			      rsdt_info->pointer))->table_offset_entry[i];
-		}
-
-		/* Get the table header */
+		table_ptr = acpi_os_map_memory((acpi_native_uint)
+					       physical_address,
+					       ACPI_EBDA_WINDOW_SIZE);
+		if (!table_ptr) {
+			ACPI_ERROR((AE_INFO,
+				    "Could not map memory at %8.8X for length %X",
+				    physical_address, ACPI_EBDA_WINDOW_SIZE));
 
-		status = acpi_tb_get_table_header(&address, header);
-		if (ACPI_FAILURE(status)) {
-			goto cleanup;
+			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
-		/* Compare table signatures and table instance */
-
-		if (ACPI_COMPARE_NAME(header->signature, signature)) {
-
-			/* An instance of the table was found */
+		mem_rover =
+		    acpi_tb_scan_memory_for_rsdp(table_ptr,
+						 ACPI_EBDA_WINDOW_SIZE);
+		acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
 
-			j++;
-			if (j >= instance) {
+		if (mem_rover) {
 
-				/* Found the correct instance, get the entire table */
+			/* Return the physical address */
 
-				status =
-				    acpi_tb_get_table_body(&address, header,
-							   table_info);
-				if (ACPI_FAILURE(status)) {
-					goto cleanup;
-				}
+			physical_address +=
+			    (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
 
-				*table_pointer = table_info->pointer;
-				goto cleanup;
-			}
+			*table_address = physical_address;
+			return_ACPI_STATUS(AE_OK);
 		}
 	}
 
-	/* Did not find the table */
+	/*
+	 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
+	 */
+	table_ptr = acpi_os_map_memory((acpi_physical_address)
+				       ACPI_HI_RSDP_WINDOW_BASE,
+				       ACPI_HI_RSDP_WINDOW_SIZE);
 
-	status = AE_NOT_EXIST;
+	if (!table_ptr) {
+		ACPI_ERROR((AE_INFO,
+			    "Could not map memory at %8.8X for length %X",
+			    ACPI_HI_RSDP_WINDOW_BASE,
+			    ACPI_HI_RSDP_WINDOW_SIZE));
 
-      cleanup:
-	if (rsdt_info->pointer) {
-		acpi_os_unmap_memory(rsdt_info->pointer,
-				     (acpi_size) rsdt_info->pointer->length);
+		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
-	ACPI_FREE(rsdt_info);
 
-	if (header) {
-		ACPI_FREE(header);
-	}
-	if (table_info) {
-		ACPI_FREE(table_info);
-	}
-	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);
 
-ACPI_EXPORT_SYMBOL(acpi_get_firmware_table)
+	if (mem_rover) {
 
-/* TBD: Move to a new file */
-#if ACPI_MACHINE_WIDTH != 16
-/*******************************************************************************
- *
- * FUNCTION:    acpi_find_root_pointer
- *
- * PARAMETERS:  Flags                   - Logical/Physical addressing
- *              rsdp_address            - Where to place the RSDP address
- *
- * 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 */
+		/* Return the physical address */
 
-	status = acpi_tb_find_rsdp(&table_info, flags);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"RSDP structure not found - Flags=%X", flags));
+		physical_address = (u32)
+		    (ACPI_HI_RSDP_WINDOW_BASE +
+		     ACPI_PTR_DIFF(mem_rover, table_ptr));
 
-		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
+		*table_address = physical_address;
+		return_ACPI_STATUS(AE_OK);
 	}
 
-	rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER;
-	rsdp_address->pointer.physical = table_info.physical_address;
-	return_ACPI_STATUS(AE_OK);
+	/* A valid RSDP was not found */
+
+	ACPI_ERROR((AE_INFO, "A valid RSDP was not found"));
+	return_ACPI_STATUS(AE_NOT_FOUND);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_find_root_pointer)
@@ -440,7 +252,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
 
 		status =
 		    acpi_tb_validate_rsdp(ACPI_CAST_PTR
-					  (struct rsdp_descriptor, mem_rover));
+					  (struct acpi_table_rsdp, mem_rover));
 		if (ACPI_SUCCESS(status)) {
 
 			/* Sig and checksum valid, we have found a real RSDP */
@@ -461,189 +273,3 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
 			  start_address));
 	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.
- *
- ******************************************************************************/
-
-static 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 logical addressing or physical addressing
-	 */
-	if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
-
-		/* 1a) Get the location of the Extended BIOS Data Area (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_ERROR((AE_INFO,
-				    "Could not map memory at %8.8X for length %X",
-				    ACPI_EBDA_PTR_LOCATION,
-				    ACPI_EBDA_PTR_LENGTH));
-
-			return_ACPI_STATUS(status);
-		}
-
-		ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
-
-		/* Convert segment part to physical address */
-
-		physical_address <<= 4;
-		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_ERROR((AE_INFO,
-					    "Could not map memory at %8.8X for length %X",
-					    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) {
-
-				/* Return the physical address */
-
-				physical_address +=
-				    (u32) 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_ERROR((AE_INFO,
-				    "Could not map memory at %8.8X for length %X",
-				    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) {
-
-			/* Return the physical address */
-
-			physical_address = (u32)
-			    (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) {
-
-				/* 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);
-		}
-	}
-
-	/* A valid RSDP was not found */
-
-	ACPI_ERROR((AE_INFO, "No valid RSDP was found"));
-	return_ACPI_STATUS(AE_NOT_FOUND);
-}
-
-#endif
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index f6cbc0b1bfd0..55a764807499 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@
  */
 
 #include <acpi/acpi.h>
+#include <acpi/acdebug.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utalloc")
@@ -142,6 +143,14 @@ acpi_status acpi_ut_create_caches(void)
 
 acpi_status acpi_ut_delete_caches(void)
 {
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+	char buffer[7];
+
+	if (acpi_gbl_display_final_mem_stats) {
+		ACPI_STRCPY(buffer, "MEMORY");
+		acpi_db_display_statistics(buffer);
+	}
+#endif
 
 	(void)acpi_os_delete_cache(acpi_gbl_namespace_cache);
 	acpi_gbl_namespace_cache = NULL;
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c
index 1a1f8109159c..870f6edeb5f2 100644
--- a/drivers/acpi/utilities/utcache.c
+++ b/drivers/acpi/utilities/utcache.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -289,6 +289,14 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache)
 
 		ACPI_MEM_TRACKING(cache->total_allocated++);
 
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+		if ((cache->total_allocated - cache->total_freed) >
+		    cache->max_occupied) {
+			cache->max_occupied =
+			    cache->total_allocated - cache->total_freed;
+		}
+#endif
+
 		/* Avoid deadlock with ACPI_ALLOCATE_ZEROED */
 
 		status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 5e1a80d1bc36..84d529db0a66 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -719,6 +719,15 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
 		acpi_ut_add_reference(source_desc->reference.object);
 		break;
 
+	case ACPI_TYPE_REGION:
+		/*
+		 * We copied the Region Handler, so we now must add a reference
+		 */
+		if (dest_desc->region.handler) {
+			acpi_ut_add_reference(dest_desc->region.handler);
+		}
+		break;
+
 	default:
 		/* Nothing to do for other simple objects */
 		break;
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 9e9054e155c1..61ad4f2daee2 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -181,8 +181,7 @@ acpi_ut_debug_print(u32 requested_debug_level,
 		if (ACPI_LV_THREADS & acpi_dbg_level) {
 			acpi_os_printf
 			    ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
-			     (unsigned long) acpi_gbl_prev_thread_id,
-			     (unsigned long) thread_id);
+			     (unsigned long)acpi_gbl_prev_thread_id, (unsigned long)thread_id);
 		}
 
 		acpi_gbl_prev_thread_id = thread_id;
@@ -195,7 +194,7 @@ acpi_ut_debug_print(u32 requested_debug_level,
 	acpi_os_printf("%8s-%04ld ", module_name, line_number);
 
 	if (ACPI_LV_THREADS & acpi_dbg_level) {
-		acpi_os_printf("[%04lX] ", thread_id);
+		acpi_os_printf("[%04lX] ", (unsigned long)thread_id);
 	}
 
 	acpi_os_printf("[%02ld] %-22.22s: ",
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 9d3f1149ba21..f777cebdc46d 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -158,16 +158,20 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
 				  "***** Mutex %p, OS Mutex %p\n",
 				  object, object->mutex.os_mutex));
 
-		if (object->mutex.os_mutex != ACPI_GLOBAL_LOCK) {
-			acpi_ex_unlink_mutex(object);
-			acpi_os_delete_mutex(object->mutex.os_mutex);
-		} else {
-			/* Global Lock "mutex" is actually a counting semaphore */
+		if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
+
+			/* Global Lock has extra semaphore */
 
 			(void)
 			    acpi_os_delete_semaphore
 			    (acpi_gbl_global_lock_semaphore);
 			acpi_gbl_global_lock_semaphore = NULL;
+
+			acpi_os_delete_mutex(object->mutex.os_mutex);
+			acpi_gbl_global_lock_mutex = NULL;
+		} else {
+			acpi_ex_unlink_mutex(object);
+			acpi_os_delete_mutex(object->mutex.os_mutex);
 		}
 		break;
 
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index d6d7121583c0..13d5879cd98b 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 014030af8b50..af33358a964b 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,89 +46,9 @@
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 
+ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
 #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. A valid pointer is
- *              always returned.
- *
- * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
- *
- ******************************************************************************/
-const char *acpi_format_exception(acpi_status status)
-{
-	acpi_status sub_status;
-	const char *exception = NULL;
-
-	ACPI_FUNCTION_ENTRY();
-
-	/*
-	 * Status is composed of two parts, a "type" and an actual code
-	 */
-	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;
-
-	case AE_CODE_PROGRAMMER:
-
-		if (sub_status <= AE_CODE_PGM_MAX) {
-			exception =
-			    acpi_gbl_exception_names_pgm[sub_status - 1];
-		}
-		break;
-
-	case AE_CODE_ACPI_TABLES:
-
-		if (sub_status <= AE_CODE_TBL_MAX) {
-			exception =
-			    acpi_gbl_exception_names_tbl[sub_status - 1];
-		}
-		break;
-
-	case AE_CODE_AML:
-
-		if (sub_status <= AE_CODE_AML_MAX) {
-			exception =
-			    acpi_gbl_exception_names_aml[sub_status - 1];
-		}
-		break;
-
-	case AE_CODE_CONTROL:
-
-		if (sub_status <= AE_CODE_CTRL_MAX) {
-			exception =
-			    acpi_gbl_exception_names_ctrl[sub_status - 1];
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	if (!exception) {
-
-		/* Exception code was not recognized */
-
-		ACPI_ERROR((AE_INFO,
-			    "Unknown exception code: 0x%8.8X", status));
-
-		exception = "UNKNOWN_STATUS_CODE";
-	}
-
-	return (ACPI_CAST_PTR(const char, exception));
-}
+    ACPI_MODULE_NAME("utglobal")
 
 /*******************************************************************************
  *
@@ -163,8 +83,6 @@ u32 acpi_gbl_startup_flags = 0;
 
 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_",
@@ -183,10 +101,45 @@ const char *acpi_gbl_highest_dstate_names[4] = {
 
 /*******************************************************************************
  *
- * Namespace globals
+ * FUNCTION:    acpi_format_exception
+ *
+ * PARAMETERS:  Status       - The acpi_status code to be formatted
+ *
+ * RETURN:      A string containing the exception text. A valid pointer is
+ *              always returned.
+ *
+ * DESCRIPTION: This function translates an ACPI exception into an ASCII string
+ *              It is here instead of utxface.c so it is always present.
  *
  ******************************************************************************/
 
+const char *acpi_format_exception(acpi_status status)
+{
+	const char *exception = NULL;
+
+	ACPI_FUNCTION_ENTRY();
+
+	exception = acpi_ut_validate_exception(status);
+	if (!exception) {
+
+		/* Exception code was not recognized */
+
+		ACPI_ERROR((AE_INFO,
+			    "Unknown exception code: 0x%8.8X", status));
+
+		exception = "UNKNOWN_STATUS_CODE";
+	}
+
+	return (ACPI_CAST_PTR(const char, exception));
+}
+
+ACPI_EXPORT_SYMBOL(acpi_format_exception)
+
+/*******************************************************************************
+ *
+ * Namespace globals
+ *
+ ******************************************************************************/
 /*
  * Predefined ACPI Names (Built-in to the Interpreter)
  *
@@ -280,53 +233,6 @@ 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 (No MADT, ECDT, SBST, etc.)
- *
- ******************************************************************************/
-
-struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1];
-
-struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = {
-	/***********    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
@@ -612,7 +518,7 @@ char *acpi_ut_get_node_name(void *object)
 	/* Name must be a valid ACPI name */
 
 	if (!acpi_ut_valid_acpi_name(node->name.integer)) {
-		node->name.integer = acpi_ut_repair_name(node->name.integer);
+		node->name.integer = acpi_ut_repair_name(node->name.ascii);
 	}
 
 	/* Return the name */
@@ -751,13 +657,6 @@ void acpi_ut_init_globals(void)
 		return;
 	}
 
-	/* ACPI table structure */
-
-	for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) {
-		acpi_gbl_table_lists[i].next = NULL;
-		acpi_gbl_table_lists[i].count = 0;
-	}
-
 	/* Mutex locked flags */
 
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
@@ -773,6 +672,7 @@ void acpi_ut_init_globals(void)
 
 	/* GPE support */
 
+	acpi_gpe_count = 0;
 	acpi_gbl_gpe_xrupt_list_head = NULL;
 	acpi_gbl_gpe_fadt_blocks[0] = NULL;
 	acpi_gbl_gpe_fadt_blocks[1] = NULL;
@@ -784,25 +684,15 @@ void acpi_ut_init_globals(void)
 	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_semaphore = NULL;
+	acpi_gbl_global_lock_mutex = NULL;
 	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;
@@ -837,8 +727,13 @@ void acpi_ut_init_globals(void)
 	acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX;
 #endif
 
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+	acpi_gbl_display_final_mem_stats = FALSE;
+#endif
+
 	return_VOID;
 }
 
 ACPI_EXPORT_SYMBOL(acpi_dbg_level)
 ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
+ACPI_EXPORT_SYMBOL(acpi_gpe_count)
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index ff76055eb7d6..ad3c0d0a5cf8 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,119 +44,14 @@
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utinit")
 
 /* Local prototypes */
-static void
-acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset);
-
 static void acpi_ut_terminate(void);
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_fadt_register_error
- *
- * PARAMETERS:  register_name           - Pointer to string identifying register
- *              Value                   - Actual register contents value
- *              Offset                  - Byte offset in the FADT
- *
- * RETURN:      AE_BAD_VALUE
- *
- * DESCRIPTION: Display failure message
- *
- ******************************************************************************/
-
-static void
-acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset)
-{
-
-	ACPI_WARNING((AE_INFO,
-		      "Invalid FADT value %s=%X at offset %X FADT=%p",
-		      register_name, value, 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
@@ -178,7 +73,6 @@ static void acpi_ut_terminate(void)
 
 	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;
@@ -239,6 +133,10 @@ void acpi_ut_subsystem_shutdown(void)
 
 	acpi_ns_terminate();
 
+	/* Delete the ACPI tables */
+
+	acpi_tb_terminate();
+
 	/* Close the globals */
 
 	acpi_ut_terminate();
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
index 19d74bedce27..0c56a0d20b29 100644
--- a/drivers/acpi/utilities/utmath.c
+++ b/drivers/acpi/utilities/utmath.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 6d8a8211be90..50133fffe420 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,78 @@ ACPI_MODULE_NAME("utmisc")
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ut_validate_exception
+ *
+ * PARAMETERS:  Status       - The acpi_status code to be formatted
+ *
+ * RETURN:      A string containing the exception text. NULL if exception is
+ *              not valid.
+ *
+ * DESCRIPTION: This function validates and translates an ACPI exception into
+ *              an ASCII string.
+ *
+ ******************************************************************************/
+const char *acpi_ut_validate_exception(acpi_status status)
+{
+	acpi_status sub_status;
+	const char *exception = NULL;
+
+	ACPI_FUNCTION_ENTRY();
+
+	/*
+	 * Status is composed of two parts, a "type" and an actual code
+	 */
+	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;
+
+	case AE_CODE_PROGRAMMER:
+
+		if (sub_status <= AE_CODE_PGM_MAX) {
+			exception =
+			    acpi_gbl_exception_names_pgm[sub_status - 1];
+		}
+		break;
+
+	case AE_CODE_ACPI_TABLES:
+
+		if (sub_status <= AE_CODE_TBL_MAX) {
+			exception =
+			    acpi_gbl_exception_names_tbl[sub_status - 1];
+		}
+		break;
+
+	case AE_CODE_AML:
+
+		if (sub_status <= AE_CODE_AML_MAX) {
+			exception =
+			    acpi_gbl_exception_names_aml[sub_status - 1];
+		}
+		break;
+
+	case AE_CODE_CONTROL:
+
+		if (sub_status <= AE_CODE_CTRL_MAX) {
+			exception =
+			    acpi_gbl_exception_names_ctrl[sub_status - 1];
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return (ACPI_CAST_PTR(const char, exception));
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ut_is_aml_table
  *
  * PARAMETERS:  Table               - An ACPI table
@@ -62,14 +134,15 @@ ACPI_MODULE_NAME("utmisc")
  *              data tables that do not contain AML code.
  *
  ******************************************************************************/
+
 u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
 {
 
 	/* These are the only tables that contain executable AML */
 
-	if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) ||
-	    ACPI_COMPARE_NAME(table->signature, PSDT_SIG) ||
-	    ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) {
+	if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) ||
+	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) ||
+	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
 		return (TRUE);
 	}
 
@@ -418,7 +491,7 @@ u32 acpi_ut_dword_byte_swap(u32 value)
 void acpi_ut_set_integer_width(u8 revision)
 {
 
-	if (revision <= 1) {
+	if (revision < 2) {
 
 		/* 32-bit case */
 
@@ -582,26 +655,25 @@ u8 acpi_ut_valid_acpi_name(u32 name)
  *
  ******************************************************************************/
 
-acpi_name acpi_ut_repair_name(acpi_name name)
+acpi_name acpi_ut_repair_name(char *name)
 {
-	char *name_ptr = ACPI_CAST_PTR(char, &name);
-	char new_name[ACPI_NAME_SIZE];
 	acpi_native_uint i;
+	char new_name[ACPI_NAME_SIZE];
 
 	for (i = 0; i < ACPI_NAME_SIZE; i++) {
-		new_name[i] = name_ptr[i];
+		new_name[i] = name[i];
 
 		/*
 		 * Replace a bad character with something printable, yet technically
 		 * still invalid. This prevents any collisions with existing "good"
 		 * names in the namespace.
 		 */
-		if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) {
+		if (!acpi_ut_valid_acpi_char(name[i], i)) {
 			new_name[i] = '*';
 		}
 	}
 
-	return (*ACPI_CAST_PTR(u32, new_name));
+	return (*(u32 *) new_name);
 }
 
 /*******************************************************************************
@@ -996,9 +1068,13 @@ acpi_ut_info(char *module_name, u32 line_number, char *format, ...)
 {
 	va_list args;
 
-	acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number);
+	/*
+	 * Removed module_name, line_number, and acpica version, not needed
+	 * for info output
+	 */
+	acpi_os_printf("ACPI: ");
 
 	va_start(args, format);
 	acpi_os_vprintf(format, args);
-	acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+	acpi_os_printf("\n");
 }
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index 180e73ceb6e2..cbad2ef5987d 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index ba7d8ac702df..4696124759e1 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c
index 5a2de92831d3..e8fe1ba6cc24 100644
--- a/drivers/acpi/utilities/utresrc.c
+++ b/drivers/acpi/utilities/utresrc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
index eaa13d05c859..edcaafad0a31 100644
--- a/drivers/acpi/utilities/utstate.c
+++ b/drivers/acpi/utilities/utstate.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index 3538f69c82a1..de3276f4f468 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,6 +67,7 @@ acpi_status acpi_initialize_subsystem(void)
 
 	ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
 
+	acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
 	ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
 
 	/* Initialize the OS-Dependent layer */
@@ -127,20 +128,6 @@ acpi_status acpi_enable_subsystem(u32 flags)
 
 	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)) {
@@ -398,7 +385,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
 {
 	struct acpi_system_info *info_ptr;
 	acpi_status status;
-	u32 i;
 
 	ACPI_FUNCTION_TRACE(acpi_get_system_info);
 
@@ -431,9 +417,7 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
 
 	/* Timer resolution - 24 or 32 bits  */
 
-	if (!acpi_gbl_FADT) {
-		info_ptr->timer_resolution = 0;
-	} else if (acpi_gbl_FADT->tmr_val_ext == 0) {
+	if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) {
 		info_ptr->timer_resolution = 24;
 	} else {
 		info_ptr->timer_resolution = 32;
@@ -449,13 +433,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
 	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 = ACPI_TABLE_ID_MAX + 1;
-	for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) {
-		info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
-	}
-
 	return_ACPI_STATUS(AE_OK);
 }