summary refs log tree commit diff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 15:14:38 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 15:14:38 -0700
commitc80dc60b03d633047c7f96be87fd59cdcdbb929f (patch)
tree1ef931c2287e376f8fef37cea89f7a951d9d3b00
parent90ca9a2ff4d6b89b6939c3ece19f8fed1eecdbab (diff)
parent0466684907ea1695eeef98cb28ca3399882ecc0a (diff)
downloadlinux-c80dc60b03d633047c7f96be87fd59cdcdbb929f.tar.gz
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
  ACPI: ACPI_DOCK: Initialize the atomic notifier list
  ACPI: acpi_os_allocate() fixes
  ACPI: SBS: fix initialization, sem2mutex
  ACPI: add 'const' to several ACPI file_operations
  ACPI: delete some defaults from ACPI Kconfig
  ACPI: "Device `[%s]' is not power manageable" make message debug only
  ACPI: ACPI_DOCK Kconfig
  Revert "Revert "ACPI: dock driver""
  ACPI: acpi_os_get_thread_id() returns current
  ACPI: ACPICA 20060707
-rw-r--r--drivers/acpi/Kconfig7
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c2
-rw-r--r--drivers/acpi/battery.c6
-rw-r--r--drivers/acpi/bus.c4
-rw-r--r--drivers/acpi/button.c4
-rw-r--r--drivers/acpi/cm_sbs.c46
-rw-r--r--drivers/acpi/dispatcher/dsinit.c10
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c23
-rw-r--r--drivers/acpi/dispatcher/dswexec.c4
-rw-r--r--drivers/acpi/dock.c740
-rw-r--r--drivers/acpi/ec.c2
-rw-r--r--drivers/acpi/event.c2
-rw-r--r--drivers/acpi/events/evregion.c44
-rw-r--r--drivers/acpi/events/evxface.c44
-rw-r--r--drivers/acpi/events/evxfregn.c13
-rw-r--r--drivers/acpi/executer/exconfig.c1
-rw-r--r--drivers/acpi/executer/exconvrt.c3
-rw-r--r--drivers/acpi/executer/exmutex.c4
-rw-r--r--drivers/acpi/executer/exsystem.c8
-rw-r--r--drivers/acpi/fan.c2
-rw-r--r--drivers/acpi/hotkey.c10
-rw-r--r--drivers/acpi/namespace/nsalloc.c13
-rw-r--r--drivers/acpi/osl.c30
-rw-r--r--drivers/acpi/parser/psutils.c2
-rw-r--r--drivers/acpi/pci_link.c7
-rw-r--r--drivers/acpi/power.c2
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/acpi/processor_idle.c2
-rw-r--r--drivers/acpi/scan.c23
-rw-r--r--drivers/acpi/sleep/proc.c6
-rw-r--r--drivers/acpi/system.c6
-rw-r--r--drivers/acpi/tables/tbget.c12
-rw-r--r--drivers/acpi/tables/tbinstal.c21
-rw-r--r--drivers/acpi/tables/tbrsdt.c27
-rw-r--r--drivers/acpi/tables/tbxface.c32
-rw-r--r--drivers/acpi/thermal.c10
-rw-r--r--drivers/acpi/utilities/utalloc.c2
-rw-r--r--drivers/acpi/utilities/utdebug.c4
-rw-r--r--drivers/acpi/utilities/utdelete.c13
-rw-r--r--drivers/acpi/utilities/utmisc.c25
-rw-r--r--drivers/acpi/utilities/utmutex.c8
-rw-r--r--drivers/acpi/utilities/utstate.c7
-rw-r--r--drivers/pci/hotplug/Kconfig2
-rw-r--r--include/acpi/acconfig.h2
-rw-r--r--include/acpi/acinterp.h10
-rw-r--r--include/acpi/aclocal.h4
-rw-r--r--include/acpi/acmacros.h8
-rw-r--r--include/acpi/acpi_bus.h2
-rw-r--r--include/acpi/acpi_drivers.h17
-rw-r--r--include/acpi/acresrc.h8
-rw-r--r--include/acpi/platform/aclinux.h27
52 files changed, 1086 insertions, 228 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 89eacd1bfeeb..56c5ba874623 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -132,6 +132,12 @@ config ACPI_FAN
 	  This driver adds support for ACPI fan devices, allowing user-mode 
 	  applications to perform basic fan control (on, off, status).
 
+config ACPI_DOCK
+	tristate "Dock"
+	depends on EXPERIMENTAL
+	help
+	  This driver adds support for ACPI controlled docking stations
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	default y
@@ -206,6 +212,7 @@ config ACPI_IBM
 config ACPI_IBM_DOCK
 	bool "Legacy Docking Station Support"
 	depends on ACPI_IBM
+	depends on ACPI_DOCK=n
 	default n
 	---help---
 	  Allows the ibm_acpi driver to handle docking station events.
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bb5b80a80b18..bce7ca27b429 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_EC)		+= ec.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
+obj-$(CONFIG_ACPI_DOCK)		+= dock.o
 obj-$(CONFIG_ACPI_VIDEO)	+= video.o 
 obj-$(CONFIG_ACPI_HOTKEY)	+= hotkey.o
 obj-y				+= pci_root.o pci_link.o pci_irq.o pci_bind.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 24ccf81d135f..96309b9660da 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -72,7 +72,7 @@ struct acpi_ac {
 	unsigned long state;
 };
 
-static struct file_operations acpi_ac_fops = {
+static const struct file_operations acpi_ac_fops = {
 	.open = acpi_ac_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 24bf4dca88cc..6e5221707d97 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -557,7 +557,7 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
 	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
 }
 
-static struct file_operations acpi_battery_info_ops = {
+static const struct file_operations acpi_battery_info_ops = {
 	.open = acpi_battery_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -565,7 +565,7 @@ static struct file_operations acpi_battery_info_ops = {
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_state_ops = {
+static const struct file_operations acpi_battery_state_ops = {
 	.open = acpi_battery_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -573,7 +573,7 @@ static struct file_operations acpi_battery_state_ops = {
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_alarm_ops = {
+static const struct file_operations acpi_battery_alarm_ops = {
 	.open = acpi_battery_alarm_open_fs,
 	.read = seq_read,
 	.write = acpi_battery_write_alarm,
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index ea5a0496a4fd..b2977695e120 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -192,8 +192,8 @@ int acpi_bus_set_power(acpi_handle handle, int state)
 	/* Make sure this is a valid target state */
 
 	if (!device->flags.power_manageable) {
-		printk(KERN_DEBUG "Device `[%s]' is not power manageable",
-				device->kobj.name);
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable",
+				device->kobj.name));
 		return -ENODEV;
 	}
 	/*
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index fd1ba05eab68..5ef885e82c78 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -87,14 +87,14 @@ struct acpi_button {
 	unsigned long pushed;
 };
 
-static struct file_operations acpi_button_info_fops = {
+static const struct file_operations acpi_button_info_fops = {
 	.open = acpi_button_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
-static struct file_operations acpi_button_state_fops = {
+static const struct file_operations acpi_button_state_fops = {
 	.open = acpi_button_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c
index 574a75a166c5..a01ce6700bfe 100644
--- a/drivers/acpi/cm_sbs.c
+++ b/drivers/acpi/cm_sbs.c
@@ -39,50 +39,43 @@ ACPI_MODULE_NAME("cm_sbs")
 static struct proc_dir_entry *acpi_ac_dir;
 static struct proc_dir_entry *acpi_battery_dir;
 
-static struct semaphore cm_sbs_sem;
+static DEFINE_MUTEX(cm_sbs_mutex);
 
-static int lock_ac_dir_cnt = 0;
-static int lock_battery_dir_cnt = 0;
+static int lock_ac_dir_cnt;
+static int lock_battery_dir_cnt;
 
 struct proc_dir_entry *acpi_lock_ac_dir(void)
 {
-
-	down(&cm_sbs_sem);
-	if (!acpi_ac_dir) {
+	mutex_lock(&cm_sbs_mutex);
+	if (!acpi_ac_dir)
 		acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
-	}
 	if (acpi_ac_dir) {
 		lock_ac_dir_cnt++;
 	} else {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "Cannot create %s\n", ACPI_AC_CLASS));
 	}
-	up(&cm_sbs_sem);
+	mutex_unlock(&cm_sbs_mutex);
 	return acpi_ac_dir;
 }
-
 EXPORT_SYMBOL(acpi_lock_ac_dir);
 
 void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param)
 {
-
-	down(&cm_sbs_sem);
-	if (acpi_ac_dir_param) {
+	mutex_lock(&cm_sbs_mutex);
+	if (acpi_ac_dir_param)
 		lock_ac_dir_cnt--;
-	}
 	if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) {
 		remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
 		acpi_ac_dir = 0;
 	}
-	up(&cm_sbs_sem);
+	mutex_unlock(&cm_sbs_mutex);
 }
-
 EXPORT_SYMBOL(acpi_unlock_ac_dir);
 
 struct proc_dir_entry *acpi_lock_battery_dir(void)
 {
-
-	down(&cm_sbs_sem);
+	mutex_lock(&cm_sbs_mutex);
 	if (!acpi_battery_dir) {
 		acpi_battery_dir =
 		    proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir);
@@ -93,39 +86,28 @@ struct proc_dir_entry *acpi_lock_battery_dir(void)
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "Cannot create %s\n", ACPI_BATTERY_CLASS));
 	}
-	up(&cm_sbs_sem);
+	mutex_unlock(&cm_sbs_mutex);
 	return acpi_battery_dir;
 }
-
 EXPORT_SYMBOL(acpi_lock_battery_dir);
 
 void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param)
 {
-
-	down(&cm_sbs_sem);
-	if (acpi_battery_dir_param) {
+	mutex_lock(&cm_sbs_mutex);
+	if (acpi_battery_dir_param)
 		lock_battery_dir_cnt--;
-	}
 	if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param
 	    && acpi_battery_dir) {
 		remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
 		acpi_battery_dir = 0;
 	}
-	up(&cm_sbs_sem);
+	mutex_unlock(&cm_sbs_mutex);
 	return;
 }
-
 EXPORT_SYMBOL(acpi_unlock_battery_dir);
 
 static int __init acpi_cm_sbs_init(void)
 {
-
-	if (acpi_disabled)
-		return 0;
-
-	init_MUTEX(&cm_sbs_sem);
-
 	return 0;
 }
-
 subsys_initcall(acpi_cm_sbs_init);
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index daf51b5b5875..1888c055d10f 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -116,16 +116,6 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
 
 	case ACPI_TYPE_METHOD:
 
-		/*
-		 * Set the execution data width (32 or 64) based upon the
-		 * revision number of the parent ACPI table.
-		 * TBD: This is really for possible future support of integer width
-		 * on a per-table basis. Currently, we just use a global for the width.
-		 */
-		if (info->table_desc->pointer->revision == 1) {
-			node->flags |= ANOBJ_DATA_WIDTH_32;
-		}
-
 		info->method_count++;
 		break;
 
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index a39a33f4847a..cf888add3191 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -134,7 +134,7 @@ acpi_ds_create_method_mutex(union acpi_operand_object *method_desc)
 	union acpi_operand_object *mutex_desc;
 	acpi_status status;
 
-	ACPI_FUNCTION_NAME(ds_create_method_mutex);
+	ACPI_FUNCTION_TRACE(ds_create_method_mutex);
 
 	/* Create the new mutex object */
 
@@ -493,7 +493,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
 
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 			  "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
-			  (char *)&walk_state->method_node->name,
+			  acpi_ut_get_node_name(walk_state->method_node),
 			  walk_state->method_call_op, return_desc));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
@@ -610,6 +610,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
 
 			acpi_os_release_mutex(method_desc->method.mutex->mutex.
 					      os_mutex);
+			method_desc->method.mutex->mutex.owner_thread = NULL;
 		}
 	}
 
@@ -620,27 +621,11 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
 		 */
 		method_node = walk_state->method_node;
 
-		/* Lock namespace for possible update */
-
-		status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-		if (ACPI_FAILURE(status)) {
-			return_VOID;
-		}
-
-		/*
-		 * Delete any namespace entries created immediately underneath
-		 * the method
-		 */
-		if (method_node && method_node->child) {
-			acpi_ns_delete_namespace_subtree(method_node);
-		}
-
 		/*
-		 * Delete any namespace entries created anywhere else within
+		 * Delete any namespace objects created anywhere within
 		 * the namespace by the execution of this method
 		 */
 		acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id);
-		status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	}
 
 	/* Decrement the thread count on the method */
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index b1ded62d0df1..d7a616c3104e 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -313,10 +313,10 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
 	case AML_CLASS_EXECUTE:
 	case AML_CLASS_CREATE:
 		/*
-		 * Most operators with arguments.
+		 * Most operators with arguments (except create_xxx_field operators)
 		 * Start a new result/operand state
 		 */
-		if (walk_state->opcode != AML_CREATE_FIELD_OP) {
+		if (walk_state->op_info->object_type != ACPI_TYPE_BUFFER_FIELD) {
 			status = acpi_ds_result_stack_push(walk_state);
 		}
 		break;
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
new file mode 100644
index 000000000000..1c0a39d8b04e
--- /dev/null
+++ b/drivers/acpi/dock.c
@@ -0,0 +1,740 @@
+/*
+ *  dock.c - ACPI dock station driver
+ *
+ *  Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/notifier.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver"
+
+ACPI_MODULE_NAME("dock")
+MODULE_AUTHOR("Kristen Carlson Accardi");
+MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static struct atomic_notifier_head dock_notifier_list;
+
+struct dock_station {
+	acpi_handle handle;
+	unsigned long last_dock_time;
+	u32 flags;
+	spinlock_t dd_lock;
+	spinlock_t hp_lock;
+	struct list_head dependent_devices;
+	struct list_head hotplug_devices;
+};
+
+struct dock_dependent_device {
+	struct list_head list;
+	struct list_head hotplug_list;
+	acpi_handle handle;
+	acpi_notify_handler handler;
+	void *context;
+};
+
+#define DOCK_DOCKING	0x00000001
+#define DOCK_EVENT	KOBJ_DOCK
+#define UNDOCK_EVENT	KOBJ_UNDOCK
+
+static struct dock_station *dock_station;
+
+/*****************************************************************************
+ *                         Dock Dependent device functions                   *
+ *****************************************************************************/
+/**
+ *  alloc_dock_dependent_device - allocate and init a dependent device
+ *  @handle: the acpi_handle of the dependent device
+ *
+ *  Allocate memory for a dependent device structure for a device referenced
+ *  by the acpi handle
+ */
+static struct dock_dependent_device *
+alloc_dock_dependent_device(acpi_handle handle)
+{
+	struct dock_dependent_device *dd;
+
+	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
+	if (dd) {
+		dd->handle = handle;
+		INIT_LIST_HEAD(&dd->list);
+		INIT_LIST_HEAD(&dd->hotplug_list);
+	}
+	return dd;
+}
+
+/**
+ * add_dock_dependent_device - associate a device with the dock station
+ * @ds: The dock station
+ * @dd: The dependent device
+ *
+ * Add the dependent device to the dock's dependent device list.
+ */
+static void
+add_dock_dependent_device(struct dock_station *ds,
+			  struct dock_dependent_device *dd)
+{
+	spin_lock(&ds->dd_lock);
+	list_add_tail(&dd->list, &ds->dependent_devices);
+	spin_unlock(&ds->dd_lock);
+}
+
+/**
+ * dock_add_hotplug_device - associate a hotplug handler with the dock station
+ * @ds: The dock station
+ * @dd: The dependent device struct
+ *
+ * Add the dependent device to the dock's hotplug device list
+ */
+static void
+dock_add_hotplug_device(struct dock_station *ds,
+			struct dock_dependent_device *dd)
+{
+	spin_lock(&ds->hp_lock);
+	list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
+	spin_unlock(&ds->hp_lock);
+}
+
+/**
+ * dock_del_hotplug_device - remove a hotplug handler from the dock station
+ * @ds: The dock station
+ * @dd: the dependent device struct
+ *
+ * Delete the dependent device from the dock's hotplug device list
+ */
+static void
+dock_del_hotplug_device(struct dock_station *ds,
+			struct dock_dependent_device *dd)
+{
+	spin_lock(&ds->hp_lock);
+	list_del(&dd->hotplug_list);
+	spin_unlock(&ds->hp_lock);
+}
+
+/**
+ * find_dock_dependent_device - get a device dependent on this dock
+ * @ds: the dock station
+ * @handle: the acpi_handle of the device we want
+ *
+ * iterate over the dependent device list for this dock.  If the
+ * dependent device matches the handle, return.
+ */
+static struct dock_dependent_device *
+find_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
+{
+	struct dock_dependent_device *dd;
+
+	spin_lock(&ds->dd_lock);
+	list_for_each_entry(dd, &ds->dependent_devices, list) {
+		if (handle == dd->handle) {
+			spin_unlock(&ds->dd_lock);
+			return dd;
+		}
+	}
+	spin_unlock(&ds->dd_lock);
+	return NULL;
+}
+
+/*****************************************************************************
+ *                         Dock functions                                    *
+ *****************************************************************************/
+/**
+ * is_dock - see if a device is a dock station
+ * @handle: acpi handle of the device
+ *
+ * If an acpi object has a _DCK method, then it is by definition a dock
+ * station, so return true.
+ */
+static int is_dock(acpi_handle handle)
+{
+	acpi_status status;
+	acpi_handle tmp;
+
+	status = acpi_get_handle(handle, "_DCK", &tmp);
+	if (ACPI_FAILURE(status))
+		return 0;
+	return 1;
+}
+
+/**
+ * is_dock_device - see if a device is on a dock station
+ * @handle: acpi handle of the device
+ *
+ * If this device is either the dock station itself,
+ * or is a device dependent on the dock station, then it
+ * is a dock device
+ */
+int is_dock_device(acpi_handle handle)
+{
+	if (!dock_station)
+		return 0;
+
+	if (is_dock(handle) || find_dock_dependent_device(dock_station, handle))
+		return 1;
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(is_dock_device);
+
+/**
+ * dock_present - see if the dock station is present.
+ * @ds: the dock station
+ *
+ * execute the _STA method.  note that present does not
+ * imply that we are docked.
+ */
+static int dock_present(struct dock_station *ds)
+{
+	unsigned long sta;
+	acpi_status status;
+
+	if (ds) {
+		status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
+		if (ACPI_SUCCESS(status) && sta)
+			return 1;
+	}
+	return 0;
+}
+
+
+
+/**
+ * dock_create_acpi_device - add new devices to acpi
+ * @handle - handle of the device to add
+ *
+ *  This function will create a new acpi_device for the given
+ *  handle if one does not exist already.  This should cause
+ *  acpi to scan for drivers for the given devices, and call
+ *  matching driver's add routine.
+ *
+ *  Returns a pointer to the acpi_device corresponding to the handle.
+ */
+static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
+{
+	struct acpi_device *device = NULL;
+	struct acpi_device *parent_device;
+	acpi_handle parent;
+	int ret;
+
+	if (acpi_bus_get_device(handle, &device)) {
+		/*
+		 * no device created for this object,
+		 * so we should create one.
+		 */
+		acpi_get_parent(handle, &parent);
+		if (acpi_bus_get_device(parent, &parent_device))
+			parent_device = NULL;
+
+		ret = acpi_bus_add(&device, parent_device, handle,
+			ACPI_BUS_TYPE_DEVICE);
+		if (ret) {
+			pr_debug("error adding bus, %x\n",
+				-ret);
+			return NULL;
+		}
+	}
+	return device;
+}
+
+/**
+ * dock_remove_acpi_device - remove the acpi_device struct from acpi
+ * @handle - the handle of the device to remove
+ *
+ *  Tell acpi to remove the acpi_device.  This should cause any loaded
+ *  driver to have it's remove routine called.
+ */
+static void dock_remove_acpi_device(acpi_handle handle)
+{
+	struct acpi_device *device;
+	int ret;
+
+	if (!acpi_bus_get_device(handle, &device)) {
+		ret = acpi_bus_trim(device, 1);
+		if (ret)
+			pr_debug("error removing bus, %x\n", -ret);
+	}
+}
+
+
+/**
+ * hotplug_dock_devices - insert or remove devices on the dock station
+ * @ds: the dock station
+ * @event: either bus check or eject request
+ *
+ * Some devices on the dock station need to have drivers called
+ * to perform hotplug operations after a dock event has occurred.
+ * Traverse the list of dock devices that have registered a
+ * hotplug handler, and call the handler.
+ */
+static void hotplug_dock_devices(struct dock_station *ds, u32 event)
+{
+	struct dock_dependent_device *dd;
+
+	spin_lock(&ds->hp_lock);
+
+	/*
+	 * First call driver specific hotplug functions
+	 */
+	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
+		if (dd->handler)
+			dd->handler(dd->handle, event, dd->context);
+	}
+
+	/*
+	 * Now make sure that an acpi_device is created for each
+	 * dependent device, or removed if this is an eject request.
+	 * This will cause acpi_drivers to be stopped/started if they
+	 * exist
+	 */
+	list_for_each_entry(dd, &ds->dependent_devices, list) {
+		if (event == ACPI_NOTIFY_EJECT_REQUEST)
+			dock_remove_acpi_device(dd->handle);
+		else
+			dock_create_acpi_device(dd->handle);
+	}
+	spin_unlock(&ds->hp_lock);
+}
+
+static void dock_event(struct dock_station *ds, u32 event, int num)
+{
+	struct acpi_device *device;
+
+	device = dock_create_acpi_device(ds->handle);
+	if (device)
+		kobject_uevent(&device->kobj, num);
+}
+
+/**
+ * eject_dock - respond to a dock eject request
+ * @ds: the dock station
+ *
+ * This is called after _DCK is called, to execute the dock station's
+ * _EJ0 method.
+ */
+static void eject_dock(struct dock_station *ds)
+{
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	acpi_status status;
+	acpi_handle tmp;
+
+	/* all dock devices should have _EJ0, but check anyway */
+	status = acpi_get_handle(ds->handle, "_EJ0", &tmp);
+	if (ACPI_FAILURE(status)) {
+		pr_debug("No _EJ0 support for dock device\n");
+		return;
+	}
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = 1;
+
+	if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
+					      &arg_list, NULL)))
+		pr_debug("Failed to evaluate _EJ0!\n");
+}
+
+/**
+ * handle_dock - handle a dock event
+ * @ds: the dock station
+ * @dock: to dock, or undock - that is the question
+ *
+ * Execute the _DCK method in response to an acpi event
+ */
+static void handle_dock(struct dock_station *ds, int dock)
+{
+	acpi_status status;
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+
+	acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
+	obj = name_buffer.pointer;
+
+	printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking");
+
+	/* _DCK method has one argument */
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = dock;
+	status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
+	if (ACPI_FAILURE(status))
+		pr_debug("%s: failed to execute _DCK\n", obj->string.pointer);
+	kfree(buffer.pointer);
+	kfree(name_buffer.pointer);
+}
+
+static inline void dock(struct dock_station *ds)
+{
+	handle_dock(ds, 1);
+}
+
+static inline void undock(struct dock_station *ds)
+{
+	handle_dock(ds, 0);
+}
+
+static inline void begin_dock(struct dock_station *ds)
+{
+	ds->flags |= DOCK_DOCKING;
+}
+
+static inline void complete_dock(struct dock_station *ds)
+{
+	ds->flags &= ~(DOCK_DOCKING);
+	ds->last_dock_time = jiffies;
+}
+
+/**
+ * dock_in_progress - see if we are in the middle of handling a dock event
+ * @ds: the dock station
+ *
+ * Sometimes while docking, false dock events can be sent to the driver
+ * because good connections aren't made or some other reason.  Ignore these
+ * if we are in the middle of doing something.
+ */
+static int dock_in_progress(struct dock_station *ds)
+{
+	if ((ds->flags & DOCK_DOCKING) ||
+	    time_before(jiffies, (ds->last_dock_time + HZ)))
+		return 1;
+	return 0;
+}
+
+/**
+ * register_dock_notifier - add yourself to the dock notifier list
+ * @nb: the callers notifier block
+ *
+ * If a driver wishes to be notified about dock events, they can
+ * use this function to put a notifier block on the dock notifier list.
+ * this notifier call chain will be called after a dock event, but
+ * before hotplugging any new devices.
+ */
+int register_dock_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&dock_notifier_list, nb);
+}
+
+EXPORT_SYMBOL_GPL(register_dock_notifier);
+
+/**
+ * unregister_dock_notifier - remove yourself from the dock notifier list
+ * @nb: the callers notifier block
+ */
+void unregister_dock_notifier(struct notifier_block *nb)
+{
+	atomic_notifier_chain_unregister(&dock_notifier_list, nb);
+}
+
+EXPORT_SYMBOL_GPL(unregister_dock_notifier);
+
+/**
+ * register_hotplug_dock_device - register a hotplug function
+ * @handle: the handle of the device
+ * @handler: the acpi_notifier_handler to call after docking
+ * @context: device specific data
+ *
+ * If a driver would like to perform a hotplug operation after a dock
+ * event, they can register an acpi_notifiy_handler to be called by
+ * the dock driver after _DCK is executed.
+ */
+int
+register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
+			     void *context)
+{
+	struct dock_dependent_device *dd;
+
+	if (!dock_station)
+		return -ENODEV;
+
+	/*
+	 * make sure this handle is for a device dependent on the dock,
+	 * this would include the dock station itself
+	 */
+	dd = find_dock_dependent_device(dock_station, handle);
+	if (dd) {
+		dd->handler = handler;
+		dd->context = context;
+		dock_add_hotplug_device(dock_station, dd);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
+
+/**
+ * unregister_hotplug_dock_device - remove yourself from the hotplug list
+ * @handle: the acpi handle of the device
+ */
+void unregister_hotplug_dock_device(acpi_handle handle)
+{
+	struct dock_dependent_device *dd;
+
+	if (!dock_station)
+		return;
+
+	dd = find_dock_dependent_device(dock_station, handle);
+	if (dd)
+		dock_del_hotplug_device(dock_station, dd);
+}
+
+EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
+
+/**
+ * dock_notify - act upon an acpi dock notification
+ * @handle: the dock station handle
+ * @event: the acpi event
+ * @data: our driver data struct
+ *
+ * If we are notified to dock, then check to see if the dock is
+ * present and then dock.  Notify all drivers of the dock event,
+ * and then hotplug and devices that may need hotplugging.  For undock
+ * check to make sure the dock device is still present, then undock
+ * and hotremove all the devices that may need removing.
+ */
+static void dock_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct dock_station *ds = (struct dock_station *)data;
+
+	switch (event) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		if (!dock_in_progress(ds) && dock_present(ds)) {
+			begin_dock(ds);
+			dock(ds);
+			if (!dock_present(ds)) {
+				printk(KERN_ERR PREFIX "Unable to dock!\n");
+				break;
+			}
+			atomic_notifier_call_chain(&dock_notifier_list,
+						   event, NULL);
+			hotplug_dock_devices(ds, event);
+			complete_dock(ds);
+			dock_event(ds, event, DOCK_EVENT);
+		}
+		break;
+	case ACPI_NOTIFY_DEVICE_CHECK:
+	/*
+         * According to acpi spec 3.0a, if a DEVICE_CHECK notification
+         * is sent and _DCK is present, it is assumed to mean an
+         * undock request.  This notify routine will only be called
+         * for objects defining _DCK, so we will fall through to eject
+         * request here.  However, we will pass an eject request through
+	 * to the driver who wish to hotplug.
+         */
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		if (!dock_in_progress(ds) && dock_present(ds)) {
+			/*
+			 * here we need to generate the undock
+			 * event prior to actually doing the undock
+			 * so that the device struct still exists.
+			 */
+			dock_event(ds, event, UNDOCK_EVENT);
+			hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
+			undock(ds);
+			eject_dock(ds);
+			if (dock_present(ds))
+				printk(KERN_ERR PREFIX "Unable to undock!\n");
+		}
+		break;
+	default:
+		printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
+	}
+}
+
+/**
+ * find_dock_devices - find devices on the dock station
+ * @handle: the handle of the device we are examining
+ * @lvl: unused
+ * @context: the dock station private data
+ * @rv: unused
+ *
+ * This function is called by acpi_walk_namespace.  It will
+ * check to see if an object has an _EJD method.  If it does, then it
+ * will see if it is dependent on the dock station.
+ */
+static acpi_status
+find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	acpi_handle tmp;
+	struct dock_station *ds = (struct dock_station *)context;
+	struct dock_dependent_device *dd;
+
+	status = acpi_bus_get_ejd(handle, &tmp);
+	if (ACPI_FAILURE(status))
+		return AE_OK;
+
+	if (tmp == ds->handle) {
+		dd = alloc_dock_dependent_device(handle);
+		if (dd)
+			add_dock_dependent_device(ds, dd);
+	}
+
+	return AE_OK;
+}
+
+/**
+ * dock_add - add a new dock station
+ * @handle: the dock station handle
+ *
+ * allocated and initialize a new dock station device.  Find all devices
+ * that are on the dock station, and register for dock event notifications.
+ */
+static int dock_add(acpi_handle handle)
+{
+	int ret;
+	acpi_status status;
+	struct dock_dependent_device *dd;
+
+	/* allocate & initialize the dock_station private data */
+	dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
+	if (!dock_station)
+		return -ENOMEM;
+	dock_station->handle = handle;
+	dock_station->last_dock_time = jiffies - HZ;
+	INIT_LIST_HEAD(&dock_station->dependent_devices);
+	INIT_LIST_HEAD(&dock_station->hotplug_devices);
+	spin_lock_init(&dock_station->dd_lock);
+	spin_lock_init(&dock_station->hp_lock);
+	ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
+
+	/* Find dependent devices */
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX, find_dock_devices, dock_station,
+			    NULL);
+
+	/* add the dock station as a device dependent on itself */
+	dd = alloc_dock_dependent_device(handle);
+	if (!dd) {
+		kfree(dock_station);
+		return -ENOMEM;
+	}
+	add_dock_dependent_device(dock_station, dd);
+
+	/* register for dock events */
+	status = acpi_install_notify_handler(dock_station->handle,
+					     ACPI_SYSTEM_NOTIFY,
+					     dock_notify, dock_station);
+
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Error installing notify handler\n");
+		ret = -ENODEV;
+		goto dock_add_err;
+	}
+
+	printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME);
+
+	return 0;
+
+dock_add_err:
+	kfree(dock_station);
+	kfree(dd);
+	return ret;
+}
+
+/**
+ * dock_remove - free up resources related to the dock station
+ */
+static int dock_remove(void)
+{
+	struct dock_dependent_device *dd, *tmp;
+	acpi_status status;
+
+	if (!dock_station)
+		return 0;
+
+	/* remove dependent devices */
+	list_for_each_entry_safe(dd, tmp, &dock_station->dependent_devices,
+				 list)
+	    kfree(dd);
+
+	/* remove dock notify handler */
+	status = acpi_remove_notify_handler(dock_station->handle,
+					    ACPI_SYSTEM_NOTIFY,
+					    dock_notify);
+	if (ACPI_FAILURE(status))
+		printk(KERN_ERR "Error removing notify handler\n");
+
+	/* free dock station memory */
+	kfree(dock_station);
+	return 0;
+}
+
+/**
+ * find_dock - look for a dock station
+ * @handle: acpi handle of a device
+ * @lvl: unused
+ * @context: counter of dock stations found
+ * @rv: unused
+ *
+ * This is called by acpi_walk_namespace to look for dock stations.
+ */
+static acpi_status
+find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	int *count = (int *)context;
+	acpi_status status = AE_OK;
+
+	if (is_dock(handle)) {
+		if (dock_add(handle) >= 0) {
+			(*count)++;
+			status = AE_CTRL_TERMINATE;
+		}
+	}
+	return status;
+}
+
+static int __init dock_init(void)
+{
+	int num = 0;
+
+	dock_station = NULL;
+
+	/* look for a dock station */
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX, find_dock, &num, NULL);
+
+	if (!num)
+		return -ENODEV;
+
+	return 0;
+}
+
+static void __exit dock_exit(void)
+{
+	dock_remove();
+}
+
+postcore_initcall(dock_init);
+module_exit(dock_exit);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 8c5d7df7d343..e5d796362854 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -929,7 +929,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
 	return single_open(file, acpi_ec_read_info, PDE(inode)->data);
 }
 
-static struct file_operations acpi_ec_info_ops = {
+static const struct file_operations acpi_ec_info_ops = {
 	.open = acpi_ec_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index a901b23e95e7..959a893c8d1f 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -99,7 +99,7 @@ static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait)
 	return 0;
 }
 
-static struct file_operations acpi_system_event_ops = {
+static const struct file_operations acpi_system_event_ops = {
 	.open = acpi_system_open_event,
 	.read = acpi_system_read_event,
 	.release = acpi_system_close_event,
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 094a17e4c86d..21caae04fe85 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -528,34 +528,40 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
 				}
 			}
 
-			/* Call the setup handler with the deactivate notification */
+			/*
+			 * If the region has been activated, call the setup handler
+			 * with the deactivate notification
+			 */
+			if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
+				region_setup = handler_obj->address_space.setup;
+				status =
+				    region_setup(region_obj,
+						 ACPI_REGION_DEACTIVATE,
+						 handler_obj->address_space.
+						 context, region_context);
 
-			region_setup = handler_obj->address_space.setup;
-			status =
-			    region_setup(region_obj, ACPI_REGION_DEACTIVATE,
-					 handler_obj->address_space.context,
-					 region_context);
+				/* Init routine may fail, Just ignore errors */
 
-			/* Init routine may fail, Just ignore errors */
+				if (ACPI_FAILURE(status)) {
+					ACPI_EXCEPTION((AE_INFO, status,
+							"from region handler - deactivate, [%s]",
+							acpi_ut_get_region_name
+							(region_obj->region.
+							 space_id)));
+				}
 
-			if (ACPI_FAILURE(status)) {
-				ACPI_EXCEPTION((AE_INFO, status,
-						"from region init, [%s]",
-						acpi_ut_get_region_name
-						(region_obj->region.space_id)));
+				region_obj->region.flags &=
+				    ~(AOPOBJ_SETUP_COMPLETE);
 			}
 
-			region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
-
 			/*
 			 * Remove handler reference in the region
 			 *
-			 * NOTE: this doesn't mean that the region goes away
-			 * The region is just inaccessible as indicated to
-			 * the _REG method
+			 * NOTE: this doesn't mean that the region goes away, the region
+			 * is just inaccessible as indicated to the _REG method
 			 *
-			 * If the region is on the handler's list
-			 * this better be the region's handler
+			 * If the region is on the handler's list, this must be the
+			 * region's handler
 			 */
 			region_obj->region.handler = NULL;
 			acpi_ut_remove_reference(handler_obj);
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 4f948df17ab9..923fd2b46955 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -428,7 +428,7 @@ acpi_remove_notify_handler(acpi_handle device,
 	node = acpi_ns_map_handle_to_node(device);
 	if (!node) {
 		status = AE_BAD_PARAMETER;
-		goto unlock;
+		goto unlock_and_exit;
 	}
 
 	/* Root Object */
@@ -442,7 +442,7 @@ acpi_remove_notify_handler(acpi_handle device,
 		    ((handler_type & ACPI_DEVICE_NOTIFY) &&
 		     !acpi_gbl_device_notify.handler)) {
 			status = AE_NOT_EXIST;
-			goto unlock;
+			goto unlock_and_exit;
 		}
 
 		/* Make sure all deferred tasks are completed */
@@ -474,7 +474,7 @@ acpi_remove_notify_handler(acpi_handle device,
 
 		if (!acpi_ev_is_notify_object(node)) {
 			status = AE_TYPE;
-			goto unlock;
+			goto unlock_and_exit;
 		}
 
 		/* Check for an existing internal object */
@@ -482,17 +482,21 @@ acpi_remove_notify_handler(acpi_handle device,
 		obj_desc = acpi_ns_get_attached_object(node);
 		if (!obj_desc) {
 			status = AE_NOT_EXIST;
-			goto unlock;
+			goto unlock_and_exit;
 		}
 
 		/* Object exists - make sure there's an existing handler */
 
 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
 			notify_obj = obj_desc->common_notify.system_notify;
-			if ((!notify_obj) ||
-			    (notify_obj->notify.handler != handler)) {
+			if (!notify_obj) {
+				status = AE_NOT_EXIST;
+				goto unlock_and_exit;
+			}
+
+			if (notify_obj->notify.handler != handler) {
 				status = AE_BAD_PARAMETER;
-				goto unlock;
+				goto unlock_and_exit;
 			}
 			/* Make sure all deferred tasks are completed */
 
@@ -510,10 +514,14 @@ acpi_remove_notify_handler(acpi_handle device,
 
 		if (handler_type & ACPI_DEVICE_NOTIFY) {
 			notify_obj = obj_desc->common_notify.device_notify;
-			if ((!notify_obj) ||
-			    (notify_obj->notify.handler != handler)) {
+			if (!notify_obj) {
+				status = AE_NOT_EXIST;
+				goto unlock_and_exit;
+			}
+
+			if (notify_obj->notify.handler != handler) {
 				status = AE_BAD_PARAMETER;
-				goto unlock;
+				goto unlock_and_exit;
 			}
 			/* Make sure all deferred tasks are completed */
 
@@ -530,9 +538,9 @@ acpi_remove_notify_handler(acpi_handle device,
 		}
 	}
 
-unlock:
+      unlock_and_exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-exit:
+      exit:
 	if (ACPI_FAILURE(status))
 		ACPI_EXCEPTION((AE_INFO, status, "Removing notify handler"));
 	return_ACPI_STATUS(status);
@@ -586,7 +594,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 	if (!gpe_event_info) {
 		status = AE_BAD_PARAMETER;
-		goto unlock;
+		goto unlock_and_exit;
 	}
 
 	/* Make sure that there isn't a handler there already */
@@ -594,7 +602,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
 	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
 	    ACPI_GPE_DISPATCH_HANDLER) {
 		status = AE_ALREADY_EXISTS;
-		goto unlock;
+		goto unlock_and_exit;
 	}
 
 	/* Allocate and init handler object */
@@ -602,7 +610,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
 	handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
 	if (!handler) {
 		status = AE_NO_MEMORY;
-		goto unlock;
+		goto unlock_and_exit;
 	}
 
 	handler->address = address;
@@ -613,7 +621,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
 
 	status = acpi_ev_disable_gpe(gpe_event_info);
 	if (ACPI_FAILURE(status)) {
-		goto unlock;
+		goto unlock_and_exit;
 	}
 
 	/* Install the handler */
@@ -628,9 +636,9 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
 
 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 
-unlock:
+      unlock_and_exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-exit:
+      exit:
 	if (ACPI_FAILURE(status))
 		ACPI_EXCEPTION((AE_INFO, status,
 				"Installing notify handler failed"));
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index e8b86a0baad0..83b12a9afa32 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -155,7 +155,11 @@ acpi_remove_address_space_handler(acpi_handle device,
 	/* Convert and validate the device handle */
 
 	node = acpi_ns_map_handle_to_node(device);
-	if (!node) {
+	if (!node ||
+	    ((node->type != ACPI_TYPE_DEVICE) &&
+	     (node->type != ACPI_TYPE_PROCESSOR) &&
+	     (node->type != ACPI_TYPE_THERMAL) &&
+	     (node != acpi_gbl_root_node))) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
 	}
@@ -178,6 +182,13 @@ acpi_remove_address_space_handler(acpi_handle device,
 
 		if (handler_obj->address_space.space_id == space_id) {
 
+			/* Handler must be the same as the installed handler */
+
+			if (handler_obj->address_space.handler != handler) {
+				status = AE_BAD_PARAMETER;
+				goto unlock_and_exit;
+			}
+
 			/* Matched space_id, first dereference this in the Regions */
 
 			ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 83fed079a276..c8341fa5fe01 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -502,7 +502,6 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 	 * (Offset contains the table_id)
 	 */
 	acpi_ns_delete_namespace_by_owner(table_info->owner_id);
-	acpi_ut_release_owner_id(&table_info->owner_id);
 
 	/* Delete the table itself */
 
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index b732e399b1ef..544e81a6a438 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -170,6 +170,9 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+			  ACPI_FORMAT_UINT64(result)));
+
 	/* Save the Result */
 
 	return_desc->integer.value = result;
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index d8ac2877cf05..3a39c2e8e104 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -267,9 +267,9 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
 	    && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) {
 		ACPI_ERROR((AE_INFO,
 			    "Thread %X cannot release Mutex [%4.4s] acquired by thread %X",
-			    walk_state->thread->thread_id,
+			    (u32) walk_state->thread->thread_id,
 			    acpi_ut_get_node_name(obj_desc->mutex.node),
-			    obj_desc->mutex.owner_thread->thread_id));
+			    (u32) obj_desc->mutex.owner_thread->thread_id));
 		return_ACPI_STATUS(AE_AML_NOT_OWNER);
 	}
 
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 6b5d1e6ce94b..28aef3e69ecc 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -60,7 +60,7 @@ ACPI_MODULE_NAME("exsystem")
  *
  * DESCRIPTION: Implements a semaphore wait with a check to see if the
  *              semaphore is available immediately.  If it is not, the
- *              interpreter is released.
+ *              interpreter is released before waiting.
  *
  ******************************************************************************/
 acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
@@ -110,9 +110,9 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Implements a semaphore wait with a check to see if the
- *              semaphore is available immediately.  If it is not, the
- *              interpreter is released.
+ * DESCRIPTION: Implements a mutex wait with a check to see if the
+ *              mutex is available immediately.  If it is not, the
+ *              interpreter is released before waiting.
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index daed2460924d..045c89477e59 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -120,7 +120,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
 	return count;
 }
 
-static struct file_operations acpi_fan_state_ops = {
+static const struct file_operations acpi_fan_state_ops = {
 	.open = acpi_fan_state_open_fs,
 	.read = seq_read,
 	.write = acpi_fan_write_state,
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
index fd81a0f5222f..32c9d88fd196 100644
--- a/drivers/acpi/hotkey.c
+++ b/drivers/acpi/hotkey.c
@@ -184,7 +184,7 @@ static union acpi_hotkey *get_hotkey_by_event(struct
 					      *hotkey_list, int event);
 
 /* event based config */
-static struct file_operations hotkey_config_fops = {
+static const struct file_operations hotkey_config_fops = {
 	.open = hotkey_open_config,
 	.read = seq_read,
 	.write = hotkey_write_config,
@@ -193,7 +193,7 @@ static struct file_operations hotkey_config_fops = {
 };
 
 /* polling based config */
-static struct file_operations hotkey_poll_config_fops = {
+static const struct file_operations hotkey_poll_config_fops = {
 	.open = hotkey_poll_open_config,
 	.read = seq_read,
 	.write = hotkey_write_config,
@@ -202,7 +202,7 @@ static struct file_operations hotkey_poll_config_fops = {
 };
 
 /* hotkey driver info */
-static struct file_operations hotkey_info_fops = {
+static const struct file_operations hotkey_info_fops = {
 	.open = hotkey_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -210,7 +210,7 @@ static struct file_operations hotkey_info_fops = {
 };
 
 /* action */
-static struct file_operations hotkey_action_fops = {
+static const struct file_operations hotkey_action_fops = {
 	.open = hotkey_action_open_fs,
 	.read = seq_read,
 	.write = hotkey_execute_aml_method,
@@ -219,7 +219,7 @@ static struct file_operations hotkey_action_fops = {
 };
 
 /* polling results */
-static struct file_operations hotkey_polling_fops = {
+static const struct file_operations hotkey_polling_fops = {
 	.open = hotkey_polling_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index dc3f0739a46b..55b407aae266 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -386,14 +386,17 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
  *              specific ID.  Used to delete entire ACPI tables.  All
  *              reference counts are updated.
  *
+ * MUTEX:       Locks namespace during deletion walk.
+ *
  ******************************************************************************/
 
 void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
 {
 	struct acpi_namespace_node *child_node;
 	struct acpi_namespace_node *deletion_node;
-	u32 level;
 	struct acpi_namespace_node *parent_node;
+	u32 level;
+	acpi_status status;
 
 	ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id);
 
@@ -401,6 +404,13 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
 		return_VOID;
 	}
 
+	/* Lock namespace for possible update */
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return_VOID;
+	}
+
 	deletion_node = NULL;
 	parent_node = acpi_gbl_root_node;
 	child_node = NULL;
@@ -469,5 +479,6 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
 		}
 	}
 
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	return_VOID;
 }
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index eedb05c6dc7b..47dfde95b8f8 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -136,16 +136,6 @@ void acpi_os_vprintf(const char *fmt, va_list args)
 #endif
 }
 
-
-extern int acpi_in_resume;
-void *acpi_os_allocate(acpi_size size)
-{
-	if (acpi_in_resume)
-		return kmalloc(size, GFP_ATOMIC);
-	else
-		return kmalloc(size, GFP_KERNEL);
-}
-
 acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
 {
 	if (efi_enabled) {
@@ -1115,26 +1105,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
 	return (AE_OK);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_os_acquire_object
- *
- * PARAMETERS:  Cache           - Handle to cache object
- *              ReturnObject    - Where the object is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Return a zero-filled object.
- *
- ******************************************************************************/
-
-void *acpi_os_acquire_object(acpi_cache_t * cache)
-{
-	void *object = kmem_cache_zalloc(cache, GFP_KERNEL);
-	WARN_ON(!object);
-	return object;
-}
-
 /******************************************************************************
  *
  * FUNCTION:    acpi_os_validate_interface
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index 182474ae8ce9..d405387b7414 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -139,12 +139,10 @@ union acpi_parse_object *acpi_ps_alloc_op(u16 opcode)
 		/* The generic op (default) is by far the most common (16 to 1) */
 
 		op = acpi_os_acquire_object(acpi_gbl_ps_node_cache);
-		memset(op, 0, sizeof(struct acpi_parse_obj_common));
 	} else {
 		/* Extended parseop */
 
 		op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache);
-		memset(op, 0, sizeof(struct acpi_parse_obj_named));
 	}
 
 	/* Initialize the Op */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 8197c0e40769..7f3e7e77e794 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -780,11 +780,6 @@ static int acpi_pci_link_resume(struct acpi_pci_link *link)
 		return 0;
 }
 
-/*
- * FIXME: this is a workaround to avoid nasty warning.  It will be removed
- * after every device calls pci_disable_device in .resume.
- */
-int acpi_in_resume;
 static int irqrouter_resume(struct sys_device *dev)
 {
 	struct list_head *node = NULL;
@@ -794,7 +789,6 @@ 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_in_resume = 1;
 	list_for_each(node, &acpi_link.entries) {
 		link = list_entry(node, struct acpi_pci_link, node);
 		if (!link) {
@@ -803,7 +797,6 @@ static int irqrouter_resume(struct sys_device *dev)
 		}
 		acpi_pci_link_resume(link);
 	}
-	acpi_in_resume = 0;
 	return 0;
 }
 
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 5d3447f4582c..fec225d1b6b7 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -80,7 +80,7 @@ struct acpi_power_resource {
 
 static struct list_head acpi_power_resource_list;
 
-static struct file_operations acpi_power_fops = {
+static const struct file_operations acpi_power_fops = {
 	.open = acpi_power_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 52674323b14d..b13d64415b7a 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -102,7 +102,7 @@ static struct acpi_driver acpi_processor_driver = {
 #define INSTALL_NOTIFY_HANDLER		1
 #define UNINSTALL_NOTIFY_HANDLER	2
 
-static struct file_operations acpi_processor_info_fops = {
+static const struct file_operations acpi_processor_info_fops = {
 	.open = acpi_processor_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 8e9c26aae8fe..71066066d626 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1070,7 +1070,7 @@ static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
 			   PDE(inode)->data);
 }
 
-static struct file_operations acpi_processor_power_fops = {
+static const struct file_operations acpi_processor_power_fops = {
 	.open = acpi_processor_power_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index cac4fcdcfc8d..5fcb50c7b778 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -663,6 +663,29 @@ static int acpi_bus_find_driver(struct acpi_device *device)
                                  Device Enumeration
    -------------------------------------------------------------------------- */
 
+acpi_status
+acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
+{
+	acpi_status status;
+	acpi_handle tmp;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *obj;
+
+	status = acpi_get_handle(handle, "_EJD", &tmp);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
+	if (ACPI_SUCCESS(status)) {
+		obj = buffer.pointer;
+		status = acpi_get_handle(NULL, obj->string.pointer, ejd);
+		kfree(buffer.pointer);
+	}
+	return status;
+}
+EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
+
+
 static int acpi_bus_get_flags(struct acpi_device *device)
 {
 	acpi_status status = AE_OK;
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 4696a85a98b9..34962578039d 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -434,7 +434,7 @@ acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file)
 			   PDE(inode)->data);
 }
 
-static struct file_operations acpi_system_wakeup_device_fops = {
+static const struct file_operations acpi_system_wakeup_device_fops = {
 	.open = acpi_system_wakeup_device_open_fs,
 	.read = seq_read,
 	.write = acpi_system_write_wakeup_device,
@@ -443,7 +443,7 @@ static struct file_operations acpi_system_wakeup_device_fops = {
 };
 
 #ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
-static struct file_operations acpi_system_sleep_fops = {
+static const struct file_operations acpi_system_sleep_fops = {
 	.open = acpi_system_sleep_open_fs,
 	.read = seq_read,
 	.write = acpi_system_write_sleep,
@@ -452,7 +452,7 @@ static struct file_operations acpi_system_sleep_fops = {
 };
 #endif				/* CONFIG_ACPI_SLEEP_PROC_SLEEP */
 
-static struct file_operations acpi_system_alarm_fops = {
+static const struct file_operations acpi_system_alarm_fops = {
 	.open = acpi_system_alarm_open_fs,
 	.read = seq_read,
 	.write = acpi_system_write_alarm,
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index c3bb7faad75e..d86dcb3c2366 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -57,7 +57,7 @@ static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
 	return single_open(file, acpi_system_read_info, PDE(inode)->data);
 }
 
-static struct file_operations acpi_system_info_ops = {
+static const struct file_operations acpi_system_info_ops = {
 	.open = acpi_system_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -67,7 +67,7 @@ static struct file_operations acpi_system_info_ops = {
 static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
 				     loff_t *);
 
-static struct file_operations acpi_system_dsdt_ops = {
+static const struct file_operations acpi_system_dsdt_ops = {
 	.read = acpi_system_read_dsdt,
 };
 
@@ -94,7 +94,7 @@ acpi_system_read_dsdt(struct file *file,
 static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
 				     loff_t *);
 
-static struct file_operations acpi_system_fadt_ops = {
+static const struct file_operations acpi_system_fadt_ops = {
 	.read = acpi_system_read_fadt,
 };
 
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 99eacceff563..7856db759af0 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -320,6 +320,16 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
 
 	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 (%X)",
+			    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
@@ -356,7 +366,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
 		 */
 		status = acpi_os_map_memory(address->pointer.physical,
 					    (acpi_size) header->length,
-					    (void *)&full_table);
+					    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",
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 7ca2df75bb11..1668a232fb67 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -256,7 +256,7 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type,
 
 	status = acpi_ut_allocate_owner_id(&table_desc->owner_id);
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+		goto error_exit1;
 	}
 
 	/* Install the table into the global data structure */
@@ -274,8 +274,8 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type,
 		 * at this location, so return an error.
 		 */
 		if (list_head->next) {
-			ACPI_FREE(table_desc);
-			return_ACPI_STATUS(AE_ALREADY_EXISTS);
+			status = AE_ALREADY_EXISTS;
+			goto error_exit2;
 		}
 
 		table_desc->next = list_head->next;
@@ -335,6 +335,17 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type,
 	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);
+
+      error_exit1:
+
+	ACPI_FREE(table_desc);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -525,6 +536,10 @@ struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc
 
 	acpi_tb_delete_single_table(table_desc);
 
+	/* Free the owner ID associated with this table */
+
+	acpi_ut_release_owner_id(&table_desc->owner_id);
+
 	/* Free the table descriptor */
 
 	next_desc = table_desc->next;
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index abcb08c2592a..0ad3dbb9ebca 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -183,6 +183,17 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
 
 	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 (%X)",
+			    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) {
@@ -210,7 +221,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
 			ACPI_ERROR((AE_INFO, "Looking for XSDT"));
 		}
 
-		ACPI_DUMP_BUFFER((char *)table_ptr, 48);
+		ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48);
 		return (AE_BAD_SIGNATURE);
 	}
 
@@ -258,7 +269,7 @@ acpi_status acpi_tb_get_table_rsdt(void)
 
 	status = acpi_tb_validate_rsdt(table_info.pointer);
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+		goto error_cleanup;
 	}
 
 	/* Get the number of tables defined in the RSDT or XSDT */
@@ -270,14 +281,14 @@ acpi_status acpi_tb_get_table_rsdt(void)
 
 	status = acpi_tb_convert_to_xsdt(&table_info);
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(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)) {
-		return_ACPI_STATUS(status);
+		goto error_cleanup;
 	}
 
 	acpi_gbl_XSDT =
@@ -285,4 +296,12 @@ acpi_status acpi_tb_get_table_rsdt(void)
 
 	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/tbxface.c b/drivers/acpi/tables/tbxface.c
index 4e91f2984815..7767987be15a 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -134,8 +134,8 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables)
  * RETURN:      Status
  *
  * DESCRIPTION: This function is called to load a table from the caller's
- *              buffer.  The buffer must contain an entire ACPI Table including
- *              a valid header.  The header fields will be verified, and if it
+ *              buffer. The buffer must contain an entire ACPI Table including
+ *              a valid header. The header fields will be verified, and if it
  *              is determined that the table is invalid, the call will fail.
  *
  ******************************************************************************/
@@ -245,15 +245,18 @@ acpi_status acpi_unload_table(acpi_table_type table_type)
 	/* Find all tables of the requested type */
 
 	table_desc = acpi_gbl_table_lists[table_type].next;
+	if (!table_desc) {
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+
 	while (table_desc) {
 		/*
-		 * Delete all namespace entries owned by this table.  Note that these
-		 * entries can appear anywhere in the namespace by virtue of the AML
-		 * "Scope" operator.  Thus, we need to track ownership by an ID, not
+		 * 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);
-		acpi_ut_release_owner_id(&table_desc->owner_id);
 		table_desc = table_desc->next;
 	}
 
@@ -275,12 +278,12 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table)
  *                                see acpi_gbl_acpi_table_flag
  *              out_table_header - pointer to the struct acpi_table_header if successful
  *
- * DESCRIPTION: This function is called to get an ACPI table header.  The caller
+ * DESCRIPTION: This function is called to get an ACPI table header. The caller
  *              supplies an pointer to a data area sufficient to contain an ACPI
  *              struct acpi_table_header structure.
  *
  *              The header contains a length field that can be used to determine
- *              the size of the buffer needed to contain the entire table.  This
+ *              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.
  *
@@ -322,7 +325,8 @@ acpi_get_table_header(acpi_table_type table_type,
 
 	/* Copy the header to the caller's buffer */
 
-	ACPI_MEMCPY((void *)out_table_header, (void *)tbl_ptr,
+	ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header),
+		    ACPI_CAST_PTR(void, tbl_ptr),
 		    sizeof(struct acpi_table_header));
 
 	return_ACPI_STATUS(status);
@@ -344,10 +348,10 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_header)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to get an ACPI table.  The caller
+ * 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
+ *              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.
@@ -417,7 +421,9 @@ acpi_get_table(acpi_table_type table_type,
 
 	/* Copy the table to the buffer */
 
-	ACPI_MEMCPY((void *)ret_buffer->pointer, (void *)tbl_ptr, table_length);
+	ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer),
+		    ACPI_CAST_PTR(void, tbl_ptr), table_length);
+
 	return_ACPI_STATUS(AE_OK);
 }
 
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index fdba4879603f..5753d06b7860 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -176,21 +176,21 @@ struct acpi_thermal {
 	struct timer_list timer;
 };
 
-static struct file_operations acpi_thermal_state_fops = {
+static const struct file_operations acpi_thermal_state_fops = {
 	.open = acpi_thermal_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
-static struct file_operations acpi_thermal_temp_fops = {
+static const struct file_operations acpi_thermal_temp_fops = {
 	.open = acpi_thermal_temp_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
-static struct file_operations acpi_thermal_trip_fops = {
+static const struct file_operations acpi_thermal_trip_fops = {
 	.open = acpi_thermal_trip_open_fs,
 	.read = seq_read,
 	.write = acpi_thermal_write_trip_points,
@@ -198,7 +198,7 @@ static struct file_operations acpi_thermal_trip_fops = {
 	.release = single_release,
 };
 
-static struct file_operations acpi_thermal_cooling_fops = {
+static const struct file_operations acpi_thermal_cooling_fops = {
 	.open = acpi_thermal_cooling_open_fs,
 	.read = seq_read,
 	.write = acpi_thermal_write_cooling_mode,
@@ -206,7 +206,7 @@ static struct file_operations acpi_thermal_cooling_fops = {
 	.release = single_release,
 };
 
-static struct file_operations acpi_thermal_polling_fops = {
+static const struct file_operations acpi_thermal_polling_fops = {
 	.open = acpi_thermal_polling_open_fs,
 	.read = seq_read,
 	.write = acpi_thermal_write_polling,
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 5cff17dc78b3..f6cbc0b1bfd0 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -285,6 +285,7 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
 	return (status);
 }
 
+#ifdef NOT_USED_BY_LINUX
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_allocate
@@ -360,3 +361,4 @@ void *acpi_ut_allocate_zeroed(acpi_size size,
 
 	return (allocation);
 }
+#endif
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 5ec1cfcc611d..bb1eaf9aa653 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -47,7 +47,7 @@
 ACPI_MODULE_NAME("utdebug")
 
 #ifdef ACPI_DEBUG_OUTPUT
-static u32 acpi_gbl_prev_thread_id = 0xFFFFFFFF;
+static acpi_thread_id acpi_gbl_prev_thread_id;
 static char *acpi_gbl_fn_entry_str = "----Entry";
 static char *acpi_gbl_fn_exit_str = "----Exit-";
 
@@ -181,7 +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 %X to TID %X ****\n\n",
-			     acpi_gbl_prev_thread_id, thread_id);
+			     (u32) acpi_gbl_prev_thread_id, (u32) thread_id);
 		}
 
 		acpi_gbl_prev_thread_id = thread_id;
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 38ebe1c54330..9d3f1149ba21 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -447,11 +447,16 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
 		 */
 		switch (ACPI_GET_OBJECT_TYPE(object)) {
 		case ACPI_TYPE_DEVICE:
+		case ACPI_TYPE_PROCESSOR:
+		case ACPI_TYPE_POWER:
+		case ACPI_TYPE_THERMAL:
 
-			acpi_ut_update_ref_count(object->device.system_notify,
-						 action);
-			acpi_ut_update_ref_count(object->device.device_notify,
-						 action);
+			/* Update the notify objects for these types (if present) */
+
+			acpi_ut_update_ref_count(object->common_notify.
+						 system_notify, action);
+			acpi_ut_update_ref_count(object->common_notify.
+						 device_notify, action);
 			break;
 
 		case ACPI_TYPE_PACKAGE:
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 33268310c738..6d8a8211be90 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -65,7 +65,7 @@ ACPI_MODULE_NAME("utmisc")
 u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
 {
 
-	/* Ignore tables that contain AML */
+	/* These are the only tables that contain executable AML */
 
 	if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) ||
 	    ACPI_COMPARE_NAME(table->signature, PSDT_SIG) ||
@@ -419,10 +419,15 @@ void acpi_ut_set_integer_width(u8 revision)
 {
 
 	if (revision <= 1) {
+
+		/* 32-bit case */
+
 		acpi_gbl_integer_bit_width = 32;
 		acpi_gbl_integer_nybble_width = 8;
 		acpi_gbl_integer_byte_width = 4;
 	} else {
+		/* 64-bit case (ACPI 2.0+) */
+
 		acpi_gbl_integer_bit_width = 64;
 		acpi_gbl_integer_nybble_width = 16;
 		acpi_gbl_integer_byte_width = 8;
@@ -502,6 +507,7 @@ acpi_ut_display_init_pathname(u8 type,
  * FUNCTION:    acpi_ut_valid_acpi_char
  *
  * PARAMETERS:  Char            - The character to be examined
+ *              Position        - Byte position (0-3)
  *
  * RETURN:      TRUE if the character is valid, FALSE otherwise
  *
@@ -609,7 +615,9 @@ acpi_name acpi_ut_repair_name(acpi_name name)
  *
  * RETURN:      Status and Converted value
  *
- * DESCRIPTION: Convert a string into an unsigned value.
+ * DESCRIPTION: Convert a string into an unsigned value. Performs either a
+ *              32-bit or 64-bit conversion, depending on the current mode
+ *              of the interpreter.
  *              NOTE: Does not support Octal strings, not needed.
  *
  ******************************************************************************/
@@ -627,7 +635,7 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
 	u8 sign_of0x = 0;
 	u8 term = 0;
 
-	ACPI_FUNCTION_TRACE(ut_stroul64);
+	ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
 
 	switch (base) {
 	case ACPI_ANY_BASE:
@@ -675,11 +683,13 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
 		}
 	}
 
+	/*
+	 * Perform a 32-bit or 64-bit conversion, depending upon the current
+	 * execution mode of the interpreter
+	 */
 	dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
 
-	/* At least one character in the string here */
-
-	/* Main loop: convert the string to a 64-bit integer */
+	/* Main loop: convert the string to a 32- or 64-bit integer */
 
 	while (*string) {
 		if (ACPI_IS_DIGIT(*string)) {
@@ -754,6 +764,9 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
 
       all_done:
 
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+			  ACPI_FORMAT_UINT64(return_value)));
+
 	*ret_integer = return_value;
 	return_ACPI_STATUS(AE_OK);
 
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index dfc8f30ca892..c39062a047cd 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -244,14 +244,14 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
 
 	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
 			  "Thread %X attempting to acquire Mutex [%s]\n",
-			  this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
+			  (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
 
 	status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
 				       ACPI_WAIT_FOREVER);
 	if (ACPI_SUCCESS(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
 				  "Thread %X acquired Mutex [%s]\n",
-				  this_thread_id,
+				  (u32) this_thread_id,
 				  acpi_ut_get_mutex_name(mutex_id)));
 
 		acpi_gbl_mutex_info[mutex_id].use_count++;
@@ -259,7 +259,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
 	} else {
 		ACPI_EXCEPTION((AE_INFO, status,
 				"Thread %X could not acquire Mutex [%X]",
-				this_thread_id, mutex_id));
+				(u32) this_thread_id, mutex_id));
 	}
 
 	return (status);
@@ -285,7 +285,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
 
 	this_thread_id = acpi_os_get_thread_id();
 	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-			  "Thread %X releasing Mutex [%s]\n", this_thread_id,
+			  "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id,
 			  acpi_ut_get_mutex_name(mutex_id)));
 
 	if (mutex_id > ACPI_MAX_MUTEX) {
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
index 0f5c5bb5deff..eaa13d05c859 100644
--- a/drivers/acpi/utilities/utstate.c
+++ b/drivers/acpi/utilities/utstate.c
@@ -199,6 +199,13 @@ struct acpi_thread_state *acpi_ut_create_thread_state(void)
 	state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD;
 	state->thread.thread_id = acpi_os_get_thread_id();
 
+	/* Check for invalid thread ID - zero is very bad, it will break things */
+
+	if (!state->thread.thread_id) {
+		ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
+		state->thread.thread_id = (acpi_thread_id) 1;
+	}
+
 	return_PTR((struct acpi_thread_state *)state);
 }
 
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index e94099c3e82e..3fae77ffb2fa 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -76,7 +76,7 @@ config HOTPLUG_PCI_IBM
 
 config HOTPLUG_PCI_ACPI
 	tristate "ACPI PCI Hotplug driver"
-	depends on ACPI && HOTPLUG_PCI
+	depends on ACPI_DOCK && HOTPLUG_PCI
 	help
 	  Say Y here if you have a system that supports PCI Hotplug using
 	  ACPI.
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index b492857fe721..9e6c23c360b2 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -63,7 +63,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20060623
+#define ACPI_CA_VERSION                 0x20060707
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index 216339a8f1f6..91586d0d5bb5 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -53,10 +53,14 @@
 #define ACPI_EXD_TABLE_SIZE(name)   (sizeof(name) / sizeof (struct acpi_exdump_info))
 
 /*
- * If possible, pack the following structure to byte alignment, since we
- * don't care about performance for debug output
+ * If possible, pack the following structures to byte alignment, since we
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
  */
-#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
 #pragma pack(1)
 #endif
 
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index 56b802486161..a4d0e73d5aca 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -127,7 +127,7 @@ typedef u8 acpi_owner_id;
 
 /* This Thread ID means that the mutex is not in use (unlocked) */
 
-#define ACPI_MUTEX_NOT_ACQUIRED         (u32) -1
+#define ACPI_MUTEX_NOT_ACQUIRED         (acpi_thread_id) 0
 
 /* Table for the global mutexes */
 
@@ -204,7 +204,7 @@ struct acpi_namespace_node {
 /* Namespace Node flags */
 
 #define ANOBJ_END_OF_PEER_LIST          0x01	/* End-of-list, Peer field points to parent */
-#define ANOBJ_DATA_WIDTH_32             0x02	/* Parent table uses 32-bit math */
+#define ANOBJ_RESERVED                  0x02	/* Available for future use */
 #define ANOBJ_METHOD_ARG                0x04	/* Node is a method argument */
 #define ANOBJ_METHOD_LOCAL              0x08	/* Node is a method local */
 #define ANOBJ_SUBTREE_HAS_INI           0x10	/* Used to optimize device initialization */
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index f1ac6109556e..192fa095a515 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -724,9 +724,15 @@
 
 /* Memory allocation */
 
+#ifndef ACPI_ALLOCATE
 #define ACPI_ALLOCATE(a)            acpi_ut_allocate((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__)
+#endif
+#ifndef ACPI_ALLOCATE_ZEROED
 #define ACPI_ALLOCATE_ZEROED(a)     acpi_ut_allocate_zeroed((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__)
-#define ACPI_FREE(a)                kfree(a)
+#endif
+#ifndef ACPI_FREE
+#define ACPI_FREE(a)                acpio_os_free(a)
+#endif
 #define ACPI_MEM_TRACKING(a)
 
 #else
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a2b3e390a503..f338e40bd544 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -334,7 +334,7 @@ int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
 		 acpi_handle handle, int type);
 int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 int acpi_bus_start(struct acpi_device *device);
-
+acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd);
 int acpi_match_ids(struct acpi_device *device, char *ids);
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index b425f9bb6d43..6a5bdcefec64 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -110,4 +110,21 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
 
 extern int acpi_specific_hotkey_enabled;
 
+/*--------------------------------------------------------------------------
+                                  Dock Station
+  -------------------------------------------------------------------------- */
+#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
+extern int is_dock_device(acpi_handle handle);
+extern int register_dock_notifier(struct notifier_block *nb);
+extern void unregister_dock_notifier(struct notifier_block *nb);
+extern int register_hotplug_dock_device(acpi_handle handle,
+	acpi_notify_handler handler, void *context);
+extern void unregister_hotplug_dock_device(acpi_handle handle);
+#else
+#define is_dock_device(h)			(0)
+#define register_dock_notifier(nb) 		(-ENODEV)
+#define unregister_dock_notifier(nb)           	do { } while(0)
+#define register_hotplug_dock_device(h1, h2, c)	(-ENODEV)
+#define unregister_hotplug_dock_device(h)       do { } while(0)
+#endif
 #endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h
index ad11fc13fbef..80a3b33571b4 100644
--- a/include/acpi/acresrc.h
+++ b/include/acpi/acresrc.h
@@ -50,9 +50,13 @@
 
 /*
  * If possible, pack the following structures to byte alignment, since we
- * don't care about performance for debug output
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
  */
-#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
 #pragma pack(1)
 #endif
 
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 3f853cabbd41..47faf27913a5 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -59,6 +59,7 @@
 #include <asm/acpi.h>
 #include <linux/slab.h>
 #include <linux/spinlock_types.h>
+#include <asm/current.h>
 
 /* Host-dependent types and defines */
 
@@ -100,8 +101,30 @@
 
 #define acpi_cpu_flags unsigned long
 
-#define acpi_thread_id u32
+#define acpi_thread_id struct task_struct *
 
-static inline acpi_thread_id acpi_os_get_thread_id(void) { return 0; }
+static inline acpi_thread_id acpi_os_get_thread_id(void) { return current; }
+
+/*
+ * The irqs_disabled() check is for resume from RAM.
+ * Interrupts are off during resume, just like they are for boot.
+ * However, boot has  (system_state != SYSTEM_RUNNING)
+ * to quiet __might_sleep() in kmalloc() and resume does not.
+ */
+#include <acpi/actypes.h>
+static inline void *acpi_os_allocate(acpi_size size) {
+	return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+}
+static inline void *acpi_os_allocate_zeroed(acpi_size size) {
+	return kzalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+}
+
+static inline void *acpi_os_acquire_object(acpi_cache_t * cache) {
+        return kmem_cache_zalloc(cache, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
+}
+
+#define ACPI_ALLOCATE(a)	acpi_os_allocate(a)
+#define ACPI_ALLOCATE_ZEROED(a)	acpi_os_allocate_zeroed(a)
+#define ACPI_FREE(a)		kfree(a)
 
 #endif				/* __ACLINUX_H__ */