Merge branches 'acpi-osl', 'acpi-pad', 'acpi-video' and 'acpi-assorted'

* acpi-osl:
  ACPI / PM: Fix incorrect wakeup IRQ setting during suspend-to-idle
  ACPI: Using correct irq when waiting for events
  ACPI: Use correct IRQ when uninstalling ACPI interrupt handler

* acpi-pad:
  ACPI / PAD: power_saving_thread() is not freezable

* acpi-video:
  ACPI / video: Add a quirk to force native backlight on Lenovo IdeaPad S405

* acpi-assorted:
  ACPI / Documentation: add copy_dsdt to ACPI format options
  ACPI / sysfs: correctly check failing memory allocation
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 22a4b68..bbf4ee6c 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -167,7 +167,8 @@
 
 	acpi=		[HW,ACPI,X86,ARM64]
 			Advanced Configuration and Power Interface
-			Format: { force | off | strict | noirq | rsdt }
+			Format: { force | off | strict | noirq | rsdt |
+				  copy_dsdt }
 			force -- enable ACPI if default was off
 			off -- disable ACPI if default was on
 			noirq -- do not use ACPI for IRQ routing
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index a66e37e..97b22fa 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -120,6 +120,6 @@
 #ifdef CONFIG_COMMON_CLK
 		of_clk_init(NULL);
 #endif
-		clocksource_of_init();
+		clocksource_probe();
 	}
 }
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index a556551..bef4183 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -647,7 +647,7 @@
 void __init omap4_local_timer_init(void)
 {
 	omap4_sync32k_timer_init();
-	clocksource_of_init();
+	clocksource_probe();
 }
 #else
 void __init omap4_local_timer_init(void)
@@ -663,7 +663,7 @@
 	omap4_sync32k_timer_init();
 	realtime_counter_init();
 
-	clocksource_of_init();
+	clocksource_probe();
 }
 #endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
 
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index b6cf3b4..251c7b9 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -67,7 +67,7 @@
 	}
 
 	of_clk_init(NULL);
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 static void __init rockchip_dt_init(void)
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 6bfa640..1e572a9 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -97,7 +97,7 @@
 static void __init r8a7779_init_time(void)
 {
 	r8a7779_clocks_init(r8a7779_read_mode_pins());
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 static const char *const r8a7779_compat_dt[] __initconst = {
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index aa33392..9eccde3 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -128,7 +128,7 @@
 #endif /* CONFIG_ARM_ARCH_TIMER */
 
 	rcar_gen2_clocks_init(mode);
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 struct memory_reserve_config {
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index b7afce6..ca2f6a8 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -124,5 +124,5 @@
 	clk_put(pclk);
 
 	spear_setup_of_timer();
-	clocksource_of_init();
+	clocksource_probe();
 }
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 65bab28..223c9e9 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -46,7 +46,7 @@
 	of_clk_init(NULL);
 	if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
 		sun6i_reset_init();
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 35670b1..546338b 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -408,7 +408,7 @@
 DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
 	.map_io		= u300_map_io,
 	.init_irq	= u300_init_irq_dt,
-	.init_time	= clocksource_of_init,
+	.init_time	= clocksource_probe,
 	.init_machine	= u300_init_machine_dt,
 	.restart	= u300_restart,
 	.dt_compat      = u300_board_compat,
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index ff28d8a..8d2d233 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -44,5 +44,5 @@
 
 dt_fail:
 	clksrc_dbx500_prcmu_init(prcmu_timer_base);
-	clocksource_of_init();
+	clocksource_probe();
 }
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 5a6e4e2..6f39d03 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -154,7 +154,7 @@
 
 	zynq_clock_init();
 	of_clk_init(NULL);
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 static struct map_desc zynq_cortex_a9_scu_map __initdata = {
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 208cec0..6894205 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -12,7 +12,6 @@
 #ifndef _ASM_ACPI_H
 #define _ASM_ACPI_H
 
-#include <linux/irqchip/arm-gic-acpi.h>
 #include <linux/mm.h>
 #include <linux/psci.h>
 
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index bbb251b..94c5367 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -1,8 +1,6 @@
 #ifndef __ASM_IRQ_H
 #define __ASM_IRQ_H
 
-#include <linux/irqchip/arm-gic-acpi.h>
-
 #include <asm-generic/irq.h>
 
 struct pt_regs;
@@ -10,15 +8,4 @@
 extern void migrate_irqs(void);
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
-static inline void acpi_irq_init(void)
-{
-	/*
-	 * Hardcode ACPI IRQ chip initialization to GICv2 for now.
-	 * Proper irqchip infrastructure will be implemented along with
-	 * incoming  GICv2m|GICv3|ITS bits.
-	 */
-	acpi_gic_init();
-}
-#define acpi_irq_init acpi_irq_init
-
 #endif
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 19de753..d6463bb 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -205,28 +205,3 @@
 			disable_acpi();
 	}
 }
-
-void __init acpi_gic_init(void)
-{
-	struct acpi_table_header *table;
-	acpi_status status;
-	acpi_size tbl_size;
-	int err;
-
-	if (acpi_disabled)
-		return;
-
-	status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
-	if (ACPI_FAILURE(status)) {
-		const char *msg = acpi_format_exception(status);
-
-		pr_err("Failed to get MADT table, %s\n", msg);
-		return;
-	}
-
-	err = gic_v2_acpi_init(table);
-	if (err)
-		pr_err("Failed to initialize GIC IRQ controller");
-
-	early_acpi_os_unmap_memory((char *)table, tbl_size);
-}
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 149151f..13339b6 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -67,16 +67,10 @@
 	u32 arch_timer_rate;
 
 	of_clk_init(NULL);
-	clocksource_of_init();
+	clocksource_probe();
 
 	tick_setup_hrtimer_broadcast();
 
-	/*
-	 * Since ACPI or FDT will only one be available in the system,
-	 * we can use acpi_generic_timer_init() here safely
-	 */
-	acpi_generic_timer_init();
-
 	arch_timer_rate = arch_timer_get_rate();
 	if (!arch_timer_rate)
 		panic("Unable to initialise architected timer.\n");
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 36d2c1e3..07039d1 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -64,11 +64,6 @@
 #define pci_legacy_read platform_pci_legacy_read
 #define pci_legacy_write platform_pci_legacy_write
 
-struct iospace_resource {
-	struct list_head list;
-	struct resource res;
-};
-
 struct pci_controller {
 	struct acpi_device *companion;
 	void *iommu;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 7cc3be9..8f6ac2f 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -115,33 +115,13 @@
 	.write = pci_write,
 };
 
-/* Called by ACPI when it finds a new root bus.  */
-
-static struct pci_controller *alloc_pci_controller(int seg)
-{
-	struct pci_controller *controller;
-
-	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
-	if (!controller)
-		return NULL;
-
-	controller->segment = seg;
-	return controller;
-}
-
 struct pci_root_info {
-	struct acpi_device *bridge;
-	struct pci_controller *controller;
-	struct list_head resources;
-	struct resource *res;
-	resource_size_t *res_offset;
-	unsigned int res_num;
+	struct acpi_pci_root_info common;
+	struct pci_controller controller;
 	struct list_head io_resources;
-	char *name;
 };
 
-static unsigned int
-new_space (u64 phys_base, int sparse)
+static unsigned int new_space(u64 phys_base, int sparse)
 {
 	u64 mmio_base;
 	int i;
@@ -168,39 +148,36 @@
 	return i;
 }
 
-static u64 add_io_space(struct pci_root_info *info,
-			struct acpi_resource_address64 *addr)
+static int add_io_space(struct device *dev, struct pci_root_info *info,
+			struct resource_entry *entry)
 {
-	struct iospace_resource *iospace;
-	struct resource *resource;
+	struct resource_entry *iospace;
+	struct resource *resource, *res = entry->res;
 	char *name;
 	unsigned long base, min, max, base_port;
 	unsigned int sparse = 0, space_nr, len;
 
-	len = strlen(info->name) + 32;
-	iospace = kzalloc(sizeof(*iospace) + len, GFP_KERNEL);
+	len = strlen(info->common.name) + 32;
+	iospace = resource_list_create_entry(NULL, len);
 	if (!iospace) {
-		dev_err(&info->bridge->dev,
-				"PCI: No memory for %s I/O port space\n",
-				info->name);
-		goto out;
+		dev_err(dev, "PCI: No memory for %s I/O port space\n",
+			info->common.name);
+		return -ENOMEM;
 	}
 
-	name = (char *)(iospace + 1);
-
-	min = addr->address.minimum;
-	max = min + addr->address.address_length - 1;
-	if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION)
+	if (res->flags & IORESOURCE_IO_SPARSE)
 		sparse = 1;
-
-	space_nr = new_space(addr->address.translation_offset, sparse);
+	space_nr = new_space(entry->offset, sparse);
 	if (space_nr == ~0)
 		goto free_resource;
 
+	name = (char *)(iospace + 1);
+	min = res->start - entry->offset;
+	max = res->end - entry->offset;
 	base = __pa(io_space[space_nr].mmio_base);
 	base_port = IO_SPACE_BASE(space_nr);
-	snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
-		base_port + min, base_port + max);
+	snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->common.name,
+		 base_port + min, base_port + max);
 
 	/*
 	 * The SDM guarantees the legacy 0-64K space is sparse, but if the
@@ -210,270 +187,125 @@
 	if (space_nr == 0)
 		sparse = 1;
 
-	resource = &iospace->res;
+	resource = iospace->res;
 	resource->name  = name;
 	resource->flags = IORESOURCE_MEM;
 	resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
 	resource->end   = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
 	if (insert_resource(&iomem_resource, resource)) {
-		dev_err(&info->bridge->dev,
-				"can't allocate host bridge io space resource  %pR\n",
-				resource);
+		dev_err(dev,
+			"can't allocate host bridge io space resource  %pR\n",
+			resource);
 		goto free_resource;
 	}
 
-	list_add_tail(&iospace->list, &info->io_resources);
-	return base_port;
+	entry->offset = base_port;
+	res->start = min + base_port;
+	res->end = max + base_port;
+	resource_list_add_tail(iospace, &info->io_resources);
+
+	return 0;
 
 free_resource:
-	kfree(iospace);
-out:
-	return ~0;
+	resource_list_free_entry(iospace);
+	return -ENOSPC;
 }
 
-static acpi_status resource_to_window(struct acpi_resource *resource,
-				      struct acpi_resource_address64 *addr)
+/*
+ * An IO port or MMIO resource assigned to a PCI host bridge may be
+ * consumed by the host bridge itself or available to its child
+ * bus/devices. The ACPI specification defines a bit (Producer/Consumer)
+ * to tell whether the resource is consumed by the host bridge itself,
+ * but firmware hasn't used that bit consistently, so we can't rely on it.
+ *
+ * On x86 and IA64 platforms, all IO port and MMIO resources are assumed
+ * to be available to child bus/devices except one special case:
+ *     IO port [0xCF8-0xCFF] is consumed by the host bridge itself
+ *     to access PCI configuration space.
+ *
+ * So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF].
+ */
+static bool resource_is_pcicfg_ioport(struct resource *res)
 {
-	acpi_status status;
-
-	/*
-	 * We're only interested in _CRS descriptors that are
-	 *	- address space descriptors for memory or I/O space
-	 *	- non-zero size
-	 */
-	status = acpi_resource_to_address64(resource, addr);
-	if (ACPI_SUCCESS(status) &&
-	    (addr->resource_type == ACPI_MEMORY_RANGE ||
-	     addr->resource_type == ACPI_IO_RANGE) &&
-	    addr->address.address_length)
-		return AE_OK;
-
-	return AE_ERROR;
+	return (res->flags & IORESOURCE_IO) &&
+		res->start == 0xCF8 && res->end == 0xCFF;
 }
 
-static acpi_status count_window(struct acpi_resource *resource, void *data)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
 {
-	unsigned int *windows = (unsigned int *) data;
-	struct acpi_resource_address64 addr;
-	acpi_status status;
-
-	status = resource_to_window(resource, &addr);
-	if (ACPI_SUCCESS(status))
-		(*windows)++;
-
-	return AE_OK;
-}
-
-static acpi_status add_window(struct acpi_resource *res, void *data)
-{
-	struct pci_root_info *info = data;
-	struct resource *resource;
-	struct acpi_resource_address64 addr;
-	acpi_status status;
-	unsigned long flags, offset = 0;
-	struct resource *root;
-
-	/* Return AE_OK for non-window resources to keep scanning for more */
-	status = resource_to_window(res, &addr);
-	if (!ACPI_SUCCESS(status))
-		return AE_OK;
-
-	if (addr.resource_type == ACPI_MEMORY_RANGE) {
-		flags = IORESOURCE_MEM;
-		root = &iomem_resource;
-		offset = addr.address.translation_offset;
-	} else if (addr.resource_type == ACPI_IO_RANGE) {
-		flags = IORESOURCE_IO;
-		root = &ioport_resource;
-		offset = add_io_space(info, &addr);
-		if (offset == ~0)
-			return AE_OK;
-	} else
-		return AE_OK;
-
-	resource = &info->res[info->res_num];
-	resource->name = info->name;
-	resource->flags = flags;
-	resource->start = addr.address.minimum + offset;
-	resource->end = resource->start + addr.address.address_length - 1;
-	info->res_offset[info->res_num] = offset;
-
-	if (insert_resource(root, resource)) {
-		dev_err(&info->bridge->dev,
-			"can't allocate host bridge window %pR\n",
-			resource);
-	} else {
-		if (offset)
-			dev_info(&info->bridge->dev, "host bridge window %pR "
-				 "(PCI address [%#llx-%#llx])\n",
-				 resource,
-				 resource->start - offset,
-				 resource->end - offset);
-		else
-			dev_info(&info->bridge->dev,
-				 "host bridge window %pR\n", resource);
-	}
-	/* HP's firmware has a hack to work around a Windows bug.
-	 * Ignore these tiny memory ranges */
-	if (!((resource->flags & IORESOURCE_MEM) &&
-	      (resource->end - resource->start < 16)))
-		pci_add_resource_offset(&info->resources, resource,
-					info->res_offset[info->res_num]);
-
-	info->res_num++;
-	return AE_OK;
-}
-
-static void free_pci_root_info_res(struct pci_root_info *info)
-{
-	struct iospace_resource *iospace, *tmp;
-
-	list_for_each_entry_safe(iospace, tmp, &info->io_resources, list)
-		kfree(iospace);
-
-	kfree(info->name);
-	kfree(info->res);
-	info->res = NULL;
-	kfree(info->res_offset);
-	info->res_offset = NULL;
-	info->res_num = 0;
-	kfree(info->controller);
-	info->controller = NULL;
-}
-
-static void __release_pci_root_info(struct pci_root_info *info)
-{
-	int i;
+	struct device *dev = &ci->bridge->dev;
+	struct pci_root_info *info;
 	struct resource *res;
-	struct iospace_resource *iospace;
+	struct resource_entry *entry, *tmp;
+	int status;
 
-	list_for_each_entry(iospace, &info->io_resources, list)
-		release_resource(&iospace->res);
-
-	for (i = 0; i < info->res_num; i++) {
-		res = &info->res[i];
-
-		if (!res->parent)
-			continue;
-
-		if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
-			continue;
-
-		release_resource(res);
+	status = acpi_pci_probe_root_resources(ci);
+	if (status > 0) {
+		info = container_of(ci, struct pci_root_info, common);
+		resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+			res = entry->res;
+			if (res->flags & IORESOURCE_MEM) {
+				/*
+				 * HP's firmware has a hack to work around a
+				 * Windows bug. Ignore these tiny memory ranges.
+				 */
+				if (resource_size(res) <= 16) {
+					resource_list_del(entry);
+					insert_resource(&iomem_resource,
+							entry->res);
+					resource_list_add_tail(entry,
+							&info->io_resources);
+				}
+			} else if (res->flags & IORESOURCE_IO) {
+				if (resource_is_pcicfg_ioport(entry->res))
+					resource_list_destroy_entry(entry);
+				else if (add_io_space(dev, info, entry))
+					resource_list_destroy_entry(entry);
+			}
+		}
 	}
 
-	free_pci_root_info_res(info);
+	return status;
+}
+
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
+{
+	struct pci_root_info *info;
+	struct resource_entry *entry, *tmp;
+
+	info = container_of(ci, struct pci_root_info, common);
+	resource_list_for_each_entry_safe(entry, tmp, &info->io_resources) {
+		release_resource(entry->res);
+		resource_list_destroy_entry(entry);
+	}
 	kfree(info);
 }
 
-static void release_pci_root_info(struct pci_host_bridge *bridge)
-{
-	struct pci_root_info *info = bridge->release_data;
-
-	__release_pci_root_info(info);
-}
-
-static int
-probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
-		int busnum, int domain)
-{
-	char *name;
-
-	name = kmalloc(16, GFP_KERNEL);
-	if (!name)
-		return -ENOMEM;
-
-	sprintf(name, "PCI Bus %04x:%02x", domain, busnum);
-	info->bridge = device;
-	info->name = name;
-
-	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
-			&info->res_num);
-	if (info->res_num) {
-		info->res =
-			kzalloc_node(sizeof(*info->res) * info->res_num,
-				     GFP_KERNEL, info->controller->node);
-		if (!info->res) {
-			kfree(name);
-			return -ENOMEM;
-		}
-
-		info->res_offset =
-			kzalloc_node(sizeof(*info->res_offset) * info->res_num,
-					GFP_KERNEL, info->controller->node);
-		if (!info->res_offset) {
-			kfree(name);
-			kfree(info->res);
-			info->res = NULL;
-			return -ENOMEM;
-		}
-
-		info->res_num = 0;
-		acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-			add_window, info);
-	} else
-		kfree(name);
-
-	return 0;
-}
+static struct acpi_pci_root_ops pci_acpi_root_ops = {
+	.pci_ops = &pci_root_ops,
+	.release_info = pci_acpi_root_release_info,
+	.prepare_resources = pci_acpi_root_prepare_resources,
+};
 
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 {
 	struct acpi_device *device = root->device;
-	int domain = root->segment;
-	int bus = root->secondary.start;
-	struct pci_controller *controller;
-	struct pci_root_info *info = NULL;
-	int busnum = root->secondary.start;
-	struct pci_bus *pbus;
-	int ret;
-
-	controller = alloc_pci_controller(domain);
-	if (!controller)
-		return NULL;
-
-	controller->companion = device;
-	controller->node = acpi_get_node(device->handle);
+	struct pci_root_info *info;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info) {
 		dev_err(&device->dev,
-				"pci_bus %04x:%02x: ignored (out of memory)\n",
-				domain, busnum);
-		kfree(controller);
+			"pci_bus %04x:%02x: ignored (out of memory)\n",
+			root->segment, (int)root->secondary.start);
 		return NULL;
 	}
 
-	info->controller = controller;
+	info->controller.segment = root->segment;
+	info->controller.companion = device;
+	info->controller.node = acpi_get_node(device->handle);
 	INIT_LIST_HEAD(&info->io_resources);
-	INIT_LIST_HEAD(&info->resources);
-
-	ret = probe_pci_root_info(info, device, busnum, domain);
-	if (ret) {
-		kfree(info->controller);
-		kfree(info);
-		return NULL;
-	}
-	/* insert busn resource at first */
-	pci_add_resource(&info->resources, &root->secondary);
-	/*
-	 * See arch/x86/pci/acpi.c.
-	 * The desired pci bus might already be scanned in a quirk. We
-	 * should handle the case here, but it appears that IA64 hasn't
-	 * such quirk. So we just ignore the case now.
-	 */
-	pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
-				   &info->resources);
-	if (!pbus) {
-		pci_free_resource_list(&info->resources);
-		__release_pci_root_info(info);
-		return NULL;
-	}
-
-	pci_set_host_bridge_release(to_pci_host_bridge(pbus->bridge),
-			release_pci_root_info, info);
-	pci_scan_child_bus(pbus);
-	return pbus;
+	return acpi_pci_root_create(root, &pci_acpi_root_ops,
+				    &info->common, &info->controller);
 }
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index ab5b488..89a2a939 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -194,7 +194,7 @@
 {
 	of_clk_init(NULL);
 	setup_cpuinfo_clk();
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c
index 8a37734..1022201 100644
--- a/arch/mips/pistachio/time.c
+++ b/arch/mips/pistachio/time.c
@@ -39,7 +39,7 @@
 	struct clk *clk;
 
 	of_clk_init(NULL);
-	clocksource_of_init();
+	clocksource_probe();
 
 	np = of_get_cpu_node(0, NULL);
 	if (!np) {
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
index feb5a9b..25c4a61 100644
--- a/arch/mips/ralink/clk.c
+++ b/arch/mips/ralink/clk.c
@@ -75,5 +75,5 @@
 	pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
 	mips_hpt_frequency = clk_get_rate(clk) / 2;
 	clk_put(clk);
-	clocksource_of_init();
+	clocksource_probe();
 }
diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
index bbc3f91..e835dda 100644
--- a/arch/nios2/kernel/time.c
+++ b/arch/nios2/kernel/time.c
@@ -324,7 +324,7 @@
 	if (count < 2)
 		panic("%d timer is found, it needs 2 timers in system\n", count);
 
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 CLOCKSOURCE_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index ded848c..e759076 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -976,6 +976,8 @@
 {
 	int count;
 	int x2count = 0;
+	int ret;
+	struct acpi_subtable_proc madt_proc[2];
 
 	if (!cpu_has_apic)
 		return -ENODEV;
@@ -999,10 +1001,22 @@
 				      acpi_parse_sapic, MAX_LOCAL_APIC);
 
 	if (!count) {
-		x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
-					acpi_parse_x2apic, MAX_LOCAL_APIC);
-		count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
-					acpi_parse_lapic, MAX_LOCAL_APIC);
+		memset(madt_proc, 0, sizeof(madt_proc));
+		madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+		madt_proc[0].handler = acpi_parse_lapic;
+		madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+		madt_proc[1].handler = acpi_parse_x2apic;
+		ret = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+				sizeof(struct acpi_table_madt),
+				madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+		if (ret < 0) {
+			printk(KERN_ERR PREFIX
+					"Error parsing LAPIC/X2APIC entries\n");
+			return ret;
+		}
+
+		x2count = madt_proc[0].count;
+		count = madt_proc[1].count;
 	}
 	if (!count && !x2count) {
 		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index ff99117..3cd6983 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -4,16 +4,15 @@
 #include <linux/irq.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/pci-acpi.h>
 #include <asm/numa.h>
 #include <asm/pci_x86.h>
 
 struct pci_root_info {
-	struct acpi_device *bridge;
-	char name[16];
+	struct acpi_pci_root_info common;
 	struct pci_sysdata sd;
 #ifdef	CONFIG_PCI_MMCONFIG
 	bool mcfg_added;
-	u16 segment;
 	u8 start_bus;
 	u8 end_bus;
 #endif
@@ -178,15 +177,18 @@
 	return 0;
 }
 
-static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
-			  u8 end, phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
 {
-	int result;
-	struct device *dev = &info->bridge->dev;
+	int result, seg;
+	struct pci_root_info *info;
+	struct acpi_pci_root *root = ci->root;
+	struct device *dev = &ci->bridge->dev;
 
-	info->start_bus = start;
-	info->end_bus = end;
+	info = container_of(ci, struct pci_root_info, common);
+	info->start_bus = (u8)root->secondary.start;
+	info->end_bus = (u8)root->secondary.end;
 	info->mcfg_added = false;
+	seg = info->sd.domain;
 
 	/* return success if MMCFG is not in use */
 	if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
@@ -195,7 +197,8 @@
 	if (!(pci_probe & PCI_PROBE_MMCONF))
 		return check_segment(seg, dev, "MMCONFIG is disabled,");
 
-	result = pci_mmconfig_insert(dev, seg, start, end, addr);
+	result = pci_mmconfig_insert(dev, seg, info->start_bus, info->end_bus,
+				     root->mcfg_addr);
 	if (result == 0) {
 		/* enable MMCFG if it hasn't been enabled yet */
 		if (raw_pci_ext_ops == NULL)
@@ -208,134 +211,55 @@
 	return 0;
 }
 
-static void teardown_mcfg_map(struct pci_root_info *info)
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
 {
+	struct pci_root_info *info;
+
+	info = container_of(ci, struct pci_root_info, common);
 	if (info->mcfg_added) {
-		pci_mmconfig_delete(info->segment, info->start_bus,
-				    info->end_bus);
+		pci_mmconfig_delete(info->sd.domain,
+				    info->start_bus, info->end_bus);
 		info->mcfg_added = false;
 	}
 }
 #else
-static int setup_mcfg_map(struct pci_root_info *info,
-				    u16 seg, u8 start, u8 end,
-				    phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
 {
 	return 0;
 }
-static void teardown_mcfg_map(struct pci_root_info *info)
+
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
 {
 }
 #endif
 
-static void validate_resources(struct device *dev, struct list_head *crs_res,
-			       unsigned long type)
+static int pci_acpi_root_get_node(struct acpi_pci_root *root)
 {
-	LIST_HEAD(list);
-	struct resource *res1, *res2, *root = NULL;
-	struct resource_entry *tmp, *entry, *entry2;
+	int busnum = root->secondary.start;
+	struct acpi_device *device = root->device;
+	int node = acpi_get_node(device->handle);
 
-	BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
-	root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
-
-	list_splice_init(crs_res, &list);
-	resource_list_for_each_entry_safe(entry, tmp, &list) {
-		bool free = false;
-		resource_size_t end;
-
-		res1 = entry->res;
-		if (!(res1->flags & type))
-			goto next;
-
-		/* Exclude non-addressable range or non-addressable portion */
-		end = min(res1->end, root->end);
-		if (end <= res1->start) {
-			dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
-				 res1);
-			free = true;
-			goto next;
-		} else if (res1->end != end) {
-			dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
-				 res1, (unsigned long long)end + 1,
-				 (unsigned long long)res1->end);
-			res1->end = end;
-		}
-
-		resource_list_for_each_entry(entry2, crs_res) {
-			res2 = entry2->res;
-			if (!(res2->flags & type))
-				continue;
-
-			/*
-			 * I don't like throwing away windows because then
-			 * our resources no longer match the ACPI _CRS, but
-			 * the kernel resource tree doesn't allow overlaps.
-			 */
-			if (resource_overlaps(res1, res2)) {
-				res2->start = min(res1->start, res2->start);
-				res2->end = max(res1->end, res2->end);
-				dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
-					 res2, res1);
-				free = true;
-				goto next;
-			}
-		}
-
-next:
-		resource_list_del(entry);
-		if (free)
-			resource_list_free_entry(entry);
-		else
-			resource_list_add_tail(entry, crs_res);
+	if (node == NUMA_NO_NODE) {
+		node = x86_pci_root_bus_node(busnum);
+		if (node != 0 && node != NUMA_NO_NODE)
+			dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
+				node);
 	}
+	if (node != NUMA_NO_NODE && !node_online(node))
+		node = NUMA_NO_NODE;
+
+	return node;
 }
 
-static void add_resources(struct pci_root_info *info,
-			  struct list_head *resources,
-			  struct list_head *crs_res)
+static int pci_acpi_root_init_info(struct acpi_pci_root_info *ci)
 {
-	struct resource_entry *entry, *tmp;
-	struct resource *res, *conflict, *root = NULL;
-
-	validate_resources(&info->bridge->dev, crs_res, IORESOURCE_MEM);
-	validate_resources(&info->bridge->dev, crs_res, IORESOURCE_IO);
-
-	resource_list_for_each_entry_safe(entry, tmp, crs_res) {
-		res = entry->res;
-		if (res->flags & IORESOURCE_MEM)
-			root = &iomem_resource;
-		else if (res->flags & IORESOURCE_IO)
-			root = &ioport_resource;
-		else
-			BUG_ON(res);
-
-		conflict = insert_resource_conflict(root, res);
-		if (conflict) {
-			dev_info(&info->bridge->dev,
-				 "ignoring host bridge window %pR (conflicts with %s %pR)\n",
-				 res, conflict->name, conflict);
-			resource_list_destroy_entry(entry);
-		}
-	}
-
-	list_splice_tail(crs_res, resources);
+	return setup_mcfg_map(ci);
 }
 
-static void release_pci_root_info(struct pci_host_bridge *bridge)
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
 {
-	struct resource *res;
-	struct resource_entry *entry;
-	struct pci_root_info *info = bridge->release_data;
-
-	resource_list_for_each_entry(entry, &bridge->windows) {
-		res = entry->res;
-		if (res->parent &&
-		    (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
-			release_resource(res);
-	}
-
-	teardown_mcfg_map(info);
-	kfree(info);
+	teardown_mcfg_map(ci);
+	kfree(container_of(ci, struct pci_root_info, common));
 }
 
 /*
@@ -358,50 +282,47 @@
 		res->start == 0xCF8 && res->end == 0xCFF;
 }
 
-static void probe_pci_root_info(struct pci_root_info *info,
-				struct acpi_device *device,
-				int busnum, int domain,
-				struct list_head *list)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
 {
-	int ret;
+	struct acpi_device *device = ci->bridge;
+	int busnum = ci->root->secondary.start;
 	struct resource_entry *entry, *tmp;
+	int status;
 
-	sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
-	info->bridge = device;
-	ret = acpi_dev_get_resources(device, list,
-				     acpi_dev_filter_resource_type_cb,
-				     (void *)(IORESOURCE_IO | IORESOURCE_MEM));
-	if (ret < 0)
-		dev_warn(&device->dev,
-			 "failed to parse _CRS method, error code %d\n", ret);
-	else if (ret == 0)
-		dev_dbg(&device->dev,
-			"no IO and memory resources present in _CRS\n");
-	else
-		resource_list_for_each_entry_safe(entry, tmp, list) {
-			if ((entry->res->flags & IORESOURCE_DISABLED) ||
-			    resource_is_pcicfg_ioport(entry->res))
+	status = acpi_pci_probe_root_resources(ci);
+	if (pci_use_crs) {
+		resource_list_for_each_entry_safe(entry, tmp, &ci->resources)
+			if (resource_is_pcicfg_ioport(entry->res))
 				resource_list_destroy_entry(entry);
-			else
-				entry->res->name = info->name;
-		}
+		return status;
+	}
+
+	resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+		dev_printk(KERN_DEBUG, &device->dev,
+			   "host bridge window %pR (ignored)\n", entry->res);
+		resource_list_destroy_entry(entry);
+	}
+	x86_pci_root_bus_resources(busnum, &ci->resources);
+
+	return 0;
 }
 
+static struct acpi_pci_root_ops acpi_pci_root_ops = {
+	.pci_ops = &pci_root_ops,
+	.init_info = pci_acpi_root_init_info,
+	.release_info = pci_acpi_root_release_info,
+	.prepare_resources = pci_acpi_root_prepare_resources,
+};
+
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 {
-	struct acpi_device *device = root->device;
-	struct pci_root_info *info;
 	int domain = root->segment;
 	int busnum = root->secondary.start;
-	struct resource_entry *res_entry;
-	LIST_HEAD(crs_res);
-	LIST_HEAD(resources);
+	int node = pci_acpi_root_get_node(root);
 	struct pci_bus *bus;
-	struct pci_sysdata *sd;
-	int node;
 
 	if (pci_ignore_seg)
-		domain = 0;
+		root->segment = domain = 0;
 
 	if (domain && !pci_domains_supported) {
 		printk(KERN_WARNING "pci_bus %04x:%02x: "
@@ -410,71 +331,33 @@
 		return NULL;
 	}
 
-	node = acpi_get_node(device->handle);
-	if (node == NUMA_NO_NODE) {
-		node = x86_pci_root_bus_node(busnum);
-		if (node != 0 && node != NUMA_NO_NODE)
-			dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
-				node);
-	}
-
-	if (node != NUMA_NO_NODE && !node_online(node))
-		node = NUMA_NO_NODE;
-
-	info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
-	if (!info) {
-		printk(KERN_WARNING "pci_bus %04x:%02x: "
-		       "ignored (out of memory)\n", domain, busnum);
-		return NULL;
-	}
-
-	sd = &info->sd;
-	sd->domain = domain;
-	sd->node = node;
-	sd->companion = device;
-
 	bus = pci_find_bus(domain, busnum);
 	if (bus) {
 		/*
 		 * If the desired bus has been scanned already, replace
 		 * its bus->sysdata.
 		 */
-		memcpy(bus->sysdata, sd, sizeof(*sd));
-		kfree(info);
+		struct pci_sysdata sd = {
+			.domain = domain,
+			.node = node,
+			.companion = root->device
+		};
+
+		memcpy(bus->sysdata, &sd, sizeof(sd));
 	} else {
-		/* insert busn res at first */
-		pci_add_resource(&resources,  &root->secondary);
+		struct pci_root_info *info;
 
-		/*
-		 * _CRS with no apertures is normal, so only fall back to
-		 * defaults or native bridge info if we're ignoring _CRS.
-		 */
-		probe_pci_root_info(info, device, busnum, domain, &crs_res);
-		if (pci_use_crs) {
-			add_resources(info, &resources, &crs_res);
-		} else {
-			resource_list_for_each_entry(res_entry, &crs_res)
-				dev_printk(KERN_DEBUG, &device->dev,
-					   "host bridge window %pR (ignored)\n",
-					   res_entry->res);
-			resource_list_free(&crs_res);
-			x86_pci_root_bus_resources(busnum, &resources);
-		}
-
-		if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
-				    (u8)root->secondary.end, root->mcfg_addr))
-			bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
-						  sd, &resources);
-
-		if (bus) {
-			pci_scan_child_bus(bus);
-			pci_set_host_bridge_release(
-				to_pci_host_bridge(bus->bridge),
-				release_pci_root_info, info);
-		} else {
-			resource_list_free(&resources);
-			teardown_mcfg_map(info);
-			kfree(info);
+		info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
+		if (!info)
+			dev_err(&root->device->dev,
+				"pci_bus %04x:%02x: ignored (out of memory)\n",
+				domain, busnum);
+		else {
+			info->sd.domain = domain;
+			info->sd.node = node;
+			info->sd.companion = root->device;
+			bus = acpi_pci_root_create(root, &acpi_pci_root_ops,
+						   &info->common, &info->sd);
 		}
 	}
 
@@ -487,9 +370,6 @@
 			pcie_bus_configure_settings(child);
 	}
 
-	if (bus && node != NUMA_NO_NODE)
-		dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
-
 	return bus;
 }
 
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index b97767d..b9ad9fe 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -148,7 +148,7 @@
 	local_timer_setup(0);
 	setup_irq(this_cpu_ptr(&ccount_timer)->evt.irq, &timer_irqaction);
 	sched_clock_register(ccount_sched_clock_read, 32, ccount_freq);
-	clocksource_of_init();
+	clocksource_probe();
 }
 
 /*
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 5d1015c..25dbb76 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -57,6 +57,15 @@
 config ACPI_CCA_REQUIRED
 	bool
 
+config ACPI_DEBUGGER
+	bool "In-kernel debugger (EXPERIMENTAL)"
+	select ACPI_DEBUG
+	help
+	  Enable in-kernel debugging facilities: statistics, internal
+	  object dump, single step control method execution.
+	  This is still under development, currently enabling this only
+	  results in the compilation of the ACPICA debugger files.
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
@@ -197,11 +206,25 @@
 	bool
 	select CPU_IDLE
 
+config ACPI_CPPC_LIB
+	bool
+	depends on ACPI_PROCESSOR
+	depends on !ACPI_CPU_FREQ_PSS
+	select MAILBOX
+	select PCC
+	help
+	  If this option is enabled, this file implements common functionality
+	  to parse CPPC tables as described in the ACPI 5.1+ spec. The
+	  routines implemented are meant to be used by other
+	  drivers to control CPU performance using CPPC semantics.
+	  If your platform does not support CPPC in firmware,
+	  leave this option disabled.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
-	depends on X86 || IA64
-	select ACPI_PROCESSOR_IDLE
-	select ACPI_CPU_FREQ_PSS
+	depends on X86 || IA64 || ARM64
+	select ACPI_PROCESSOR_IDLE if X86 || IA64
+	select ACPI_CPU_FREQ_PSS if X86 || IA64
 	default y
 	help
 	  This driver adds support for the ACPI Processor package. It is required
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index b5e7cd8..675eaf3 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -78,6 +78,7 @@
 obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
+obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index ae307ff..8ea8211 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -148,8 +148,6 @@
 	while (!kthread_should_stop()) {
 		unsigned long expire_time;
 
-		try_to_freeze();
-
 		/* round robin to cpus */
 		expire_time = last_jiffies + round_robin_time * HZ;
 		if (time_before(expire_time, jiffies)) {
diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c
index c58940b..48fc3ad 100644
--- a/drivers/acpi/acpi_pnp.c
+++ b/drivers/acpi/acpi_pnp.c
@@ -316,7 +316,7 @@
 	{""},
 };
 
-static bool matching_id(char *idstr, char *list_id)
+static bool matching_id(const char *idstr, const char *list_id)
 {
 	int i;
 
@@ -333,7 +333,7 @@
 	return true;
 }
 
-static bool acpi_pnp_match(char *idstr, const struct acpi_device_id **matchid)
+static bool acpi_pnp_match(const char *idstr, const struct acpi_device_id **matchid)
 {
 	const struct acpi_device_id *devid;
 
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
index 985b8a8..6979186 100644
--- a/drivers/acpi/acpi_processor.c
+++ b/drivers/acpi/acpi_processor.c
@@ -164,6 +164,24 @@
    -------------------------------------------------------------------------- */
 
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
+int __weak acpi_map_cpu(acpi_handle handle,
+		phys_cpuid_t physid, int *pcpu)
+{
+	return -ENODEV;
+}
+
+int __weak acpi_unmap_cpu(int cpu)
+{
+	return -ENODEV;
+}
+
+int __weak arch_register_cpu(int cpu)
+{
+	return -ENODEV;
+}
+
+void __weak arch_unregister_cpu(int cpu) {}
+
 static int acpi_processor_hotadd_init(struct acpi_processor *pr)
 {
 	unsigned long long sta;
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index fedcc16..885936f 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -123,7 +123,6 @@
 	rsaddr.o	\
 	rscalc.o	\
 	rscreate.o	\
-	rsdump.o	\
 	rsdumpinfo.o	\
 	rsinfo.o	\
 	rsio.o		\
@@ -178,7 +177,24 @@
 	utxferror.o	\
 	utxfmutex.o
 
+acpi-$(CONFIG_ACPI_DEBUGGER) +=	\
+	dbcmds.o		\
+	dbconvert.o		\
+	dbdisply.o		\
+	dbexec.o		\
+	dbhistry.o		\
+	dbinput.o		\
+	dbmethod.o		\
+	dbnames.o		\
+	dbobject.o		\
+	dbstats.o		\
+	dbutils.o		\
+	dbxface.o		\
+	rsdump.o		\
+
 acpi-$(ACPI_FUTURE_USAGE) +=	\
+	dbfileio.o		\
+	dbtest.o		\
 	utcache.o		\
 	utfileio.o		\
 	utprint.o		\
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h
index e9f0833..e4cc48f 100644
--- a/drivers/acpi/acpica/acapps.h
+++ b/drivers/acpi/acpica/acapps.h
@@ -88,7 +88,7 @@
 	acpi_os_printf (" %-18s%s\n", name, description);
 
 #define FILE_SUFFIX_DISASSEMBLY     "dsl"
-#define ACPI_TABLE_FILE_SUFFIX      ".dat"
+#define FILE_SUFFIX_BINARY_TABLE    ".dat"	/* Needs the dot */
 
 /*
  * getopt
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h
index eb2e926..c928ba4 100644
--- a/drivers/acpi/acpica/acdebug.h
+++ b/drivers/acpi/acpica/acdebug.h
@@ -44,6 +44,12 @@
 #ifndef __ACDEBUG_H__
 #define __ACDEBUG_H__
 
+/* The debugger is used in conjunction with the disassembler most of time */
+
+#ifdef ACPI_DISASSEMBLER
+#include "acdisasm.h"
+#endif
+
 #define ACPI_DEBUG_BUFFER_SIZE  0x4000	/* 16K buffer for return objects */
 
 struct acpi_db_command_info {
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 4dde37c..faa9760 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -325,9 +325,9 @@
 
 #ifdef ACPI_DEBUGGER
 
-ACPI_INIT_GLOBAL(u8, acpi_gbl_db_terminate_threads, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_region_support);
@@ -337,6 +337,8 @@
 ACPI_GLOBAL(u32, acpi_gbl_db_debug_level);
 ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level);
 ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node);
+ACPI_GLOBAL(u8, acpi_gbl_db_terminate_loop);
+ACPI_GLOBAL(u8, acpi_gbl_db_threads_terminated);
 
 ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]);
 ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
@@ -358,6 +360,9 @@
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
+
 #endif				/* ACPI_DEBUGGER */
 
 /*****************************************************************************
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h
index e820ed8..e9e936e 100644
--- a/drivers/acpi/acpica/acinterp.h
+++ b/drivers/acpi/acpica/acinterp.h
@@ -397,12 +397,10 @@
 acpi_ex_dump_operands(union acpi_operand_object **operands,
 		      const char *opcode_name, u32 num_opcodes);
 
-#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags);
 
 void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * exnames - AML namestring support
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 6f70826..e1dd784 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -83,10 +83,8 @@
 #define ACPI_MTX_EVENTS                 3	/* Data for ACPI events */
 #define ACPI_MTX_CACHES                 4	/* Internal caches, general purposes */
 #define ACPI_MTX_MEMORY                 5	/* Debug memory tracking lists */
-#define ACPI_MTX_DEBUG_CMD_COMPLETE     6	/* AML debugger */
-#define ACPI_MTX_DEBUG_CMD_READY        7	/* AML debugger */
 
-#define ACPI_MAX_MUTEX                  7
+#define ACPI_MAX_MUTEX                  5
 #define ACPI_NUM_MUTEX                  ACPI_MAX_MUTEX+1
 
 /* Lock structure for reader/writer interfaces */
@@ -111,6 +109,14 @@
 
 #define ACPI_MUTEX_NOT_ACQUIRED         (acpi_thread_id) 0
 
+/* This Thread ID means an invalid thread ID */
+
+#ifdef ACPI_OS_INVALID_THREAD_ID
+#define ACPI_INVALID_THREAD_ID          ACPI_OS_INVALID_THREAD_ID
+#else
+#define ACPI_INVALID_THREAD_ID          ((acpi_thread_id) 0xFFFFFFFF)
+#endif
+
 /* Table for the global mutexes */
 
 struct acpi_mutex_info {
@@ -287,13 +293,17 @@
 #define ACPI_BTYPE_BUFFER_FIELD         0x00002000
 #define ACPI_BTYPE_DDB_HANDLE           0x00004000
 #define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
-#define ACPI_BTYPE_REFERENCE            0x00010000
+#define ACPI_BTYPE_REFERENCE_OBJECT     0x00010000	/* From Index(), ref_of(), etc (type6_opcodes) */
 #define ACPI_BTYPE_RESOURCE             0x00020000
+#define ACPI_BTYPE_NAMED_REFERENCE      0x00040000	/* Generic unresolved Name or Namepath */
 
 #define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
 
 #define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+
+	/* Used by Copy, de_ref_of, Store, Printf, Fprintf */
+
+#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE_OBJECT | ACPI_BTYPE_DDB_HANDLE)
 #define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
 #define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF	/* ARG or LOCAL */
 #define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
@@ -848,7 +858,7 @@
 #define ACPI_PARSEOP_PARAMLIST          0x02
 #define ACPI_PARSEOP_EMPTY_TERMLIST     0x04
 #define ACPI_PARSEOP_PREDEF_CHECKED     0x08
-#define ACPI_PARSEOP_SPECIAL            0x10
+#define ACPI_PARSEOP_CLOSING_PAREN      0x10
 #define ACPI_PARSEOP_COMPOUND           0x20
 #define ACPI_PARSEOP_ASSIGNMENT         0x40
 
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index ea0d907..5d261c9 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -193,9 +193,7 @@
 /*
  * nsdump - Namespace dump/print utilities
  */
-#ifdef	ACPI_FUTURE_USAGE
 void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth);
-#endif				/* ACPI_FUTURE_USAGE */
 
 void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level);
 
@@ -208,7 +206,6 @@
 acpi_ns_dump_one_object(acpi_handle obj_handle,
 			u32 level, void *context, void **return_value);
 
-#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ns_dump_objects(acpi_object_type type,
 		     u8 display_type,
@@ -220,7 +217,6 @@
 			  u8 display_type,
 			  u32 max_depth,
 			  acpi_owner_id owner_id, acpi_handle start_handle);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * nseval - Namespace evaluation functions
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h
index fd85ad0..f9acf92 100644
--- a/drivers/acpi/acpica/acopcode.h
+++ b/drivers/acpi/acpica/acopcode.h
@@ -211,7 +211,7 @@
 #define ARGI_ARG4                       ARG_NONE
 #define ARGI_ARG5                       ARG_NONE
 #define ARGI_ARG6                       ARG_NONE
-#define ARGI_BANK_FIELD_OP              ARGI_INVALID_OPCODE
+#define ARGI_BANK_FIELD_OP              ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_BIT_AND_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_BIT_NAND_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_BIT_NOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
@@ -307,7 +307,7 @@
 #define ARGI_SLEEP_OP                   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STALL_OP                   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STATICSTRING_OP            ARGI_INVALID_OPCODE
-#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
+#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_STORE_TARGET)
 #define ARGI_STRING_OP                  ARGI_INVALID_OPCODE
 #define ARGI_SUBTRACT_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_THERMAL_ZONE_OP            ARGI_INVALID_OPCODE
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h
index 6021ccf..8fc8c7c 100644
--- a/drivers/acpi/acpica/acparser.h
+++ b/drivers/acpi/acpica/acparser.h
@@ -194,10 +194,8 @@
 
 union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn);
 
-#ifdef	ACPI_FUTURE_USAGE
 union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
 						union acpi_parse_object *op);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * pswalk - parse tree walk routines
@@ -235,9 +233,7 @@
 
 u8 acpi_ps_is_leading_char(u32 c);
 
-#ifdef	ACPI_FUTURE_USAGE
 u32 acpi_ps_get_name(union acpi_parse_object *op);
-#endif				/* ACPI_FUTURE_USAGE */
 
 void acpi_ps_set_name(union acpi_parse_object *op, u32 name);
 
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index fb2aa50..8b8fef6 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -635,9 +635,7 @@
 acpi_ut_free_and_track(void *address,
 		       u32 component, const char *module, u32 line);
 
-#ifdef	ACPI_FUTURE_USAGE
 void acpi_ut_dump_allocation_info(void);
-#endif				/* ACPI_FUTURE_USAGE */
 
 void acpi_ut_dump_allocations(u32 component, const char *module);
 
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h
index be9fd00..883f20c 100644
--- a/drivers/acpi/acpica/amlcode.h
+++ b/drivers/acpi/acpica/amlcode.h
@@ -277,14 +277,15 @@
 #define ARGI_TARGETREF              0x0F	/* Target, subject to implicit conversion */
 #define ARGI_FIXED_TARGET           0x10	/* Target, no implicit conversion */
 #define ARGI_SIMPLE_TARGET          0x11	/* Name, Local, Arg -- no implicit conversion */
+#define ARGI_STORE_TARGET           0x12	/* Target for store is TARGETREF + package objects */
 
 /* Multiple/complex types */
 
-#define ARGI_DATAOBJECT             0x12	/* Buffer, String, package or reference to a node - Used only by size_of operator */
-#define ARGI_COMPLEXOBJ             0x13	/* Buffer, String, or package (Used by INDEX op only) */
-#define ARGI_REF_OR_STRING          0x14	/* Reference or String (Used by DEREFOF op only) */
-#define ARGI_REGION_OR_BUFFER       0x15	/* Used by LOAD op only */
-#define ARGI_DATAREFOBJ             0x16
+#define ARGI_DATAOBJECT             0x13	/* Buffer, String, package or reference to a node - Used only by size_of operator */
+#define ARGI_COMPLEXOBJ             0x14	/* Buffer, String, or package (Used by INDEX op only) */
+#define ARGI_REF_OR_STRING          0x15	/* Reference or String (Used by DEREFOF op only) */
+#define ARGI_REGION_OR_BUFFER       0x16	/* Used by LOAD op only */
+#define ARGI_DATAREFOBJ             0x17
 
 /* Note: types above can expand to 0x1F maximum */
 
diff --git a/drivers/acpi/acpica/dbcmds.c b/drivers/acpi/acpica/dbcmds.c
new file mode 100644
index 0000000..30414b3
--- /dev/null
+++ b/drivers/acpi/acpica/dbcmds.c
@@ -0,0 +1,1187 @@
+/*******************************************************************************
+ *
+ * Module Name: dbcmds - Miscellaneous debug commands and output routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+#include "acresrc.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbcmds")
+
+/* Local prototypes */
+static void
+acpi_dm_compare_aml_resources(u8 *aml1_buffer,
+			      acpi_rsdesc_size aml1_buffer_length,
+			      u8 *aml2_buffer,
+			      acpi_rsdesc_size aml2_buffer_length);
+
+static acpi_status
+acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
+
+static acpi_status
+acpi_db_resource_callback(struct acpi_resource *resource, void *context);
+
+static acpi_status
+acpi_db_device_resources(acpi_handle obj_handle,
+			 u32 nesting_level, void *context, void **return_value);
+
+static void acpi_db_do_one_sleep_state(u8 sleep_state);
+
+static char *acpi_db_trace_method_name = NULL;
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_node
+ *
+ * PARAMETERS:  in_string           - String to convert
+ *
+ * RETURN:      Pointer to a NS node
+ *
+ * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
+ *              alphanumeric strings.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
+{
+	struct acpi_namespace_node *node;
+	acpi_size address;
+
+	if ((*in_string >= 0x30) && (*in_string <= 0x39)) {
+
+		/* Numeric argument, convert */
+
+		address = strtoul(in_string, NULL, 16);
+		node = ACPI_TO_POINTER(address);
+		if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
+			acpi_os_printf("Address %p is invalid", node);
+			return (NULL);
+		}
+
+		/* Make sure pointer is valid NS node */
+
+		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
+			acpi_os_printf
+			    ("Address %p is not a valid namespace node [%s]\n",
+			     node, acpi_ut_get_descriptor_name(node));
+			return (NULL);
+		}
+	} else {
+		/*
+		 * Alpha argument: The parameter is a name string that must be
+		 * resolved to a Namespace object.
+		 */
+		node = acpi_db_local_ns_lookup(in_string);
+		if (!node) {
+			acpi_os_printf
+			    ("Could not find [%s] in namespace, defaulting to root node\n",
+			     in_string);
+			node = acpi_gbl_root_node;
+		}
+	}
+
+	return (node);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_sleep
+ *
+ * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means
+ *                                    invoke all possible sleep states.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Simulate sleep/wake sequences
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_sleep(char *object_arg)
+{
+	u8 sleep_state;
+	u32 i;
+
+	ACPI_FUNCTION_TRACE(acpi_db_sleep);
+
+	/* Null input (no arguments) means to invoke all sleep states */
+
+	if (!object_arg) {
+		acpi_os_printf("Invoking all possible sleep states, 0-%d\n",
+			       ACPI_S_STATES_MAX);
+
+		for (i = 0; i <= ACPI_S_STATES_MAX; i++) {
+			acpi_db_do_one_sleep_state((u8)i);
+		}
+
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/* Convert argument to binary and invoke the sleep state */
+
+	sleep_state = (u8)strtoul(object_arg, NULL, 0);
+	acpi_db_do_one_sleep_state(sleep_state);
+	return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_do_one_sleep_state
+ *
+ * PARAMETERS:  sleep_state         - Desired sleep state (0-5)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate a sleep/wake sequence
+ *
+ ******************************************************************************/
+
+static void acpi_db_do_one_sleep_state(u8 sleep_state)
+{
+	acpi_status status;
+	u8 sleep_type_a;
+	u8 sleep_type_b;
+
+	/* Validate parameter */
+
+	if (sleep_state > ACPI_S_STATES_MAX) {
+		acpi_os_printf("Sleep state %d out of range (%d max)\n",
+			       sleep_state, ACPI_S_STATES_MAX);
+		return;
+	}
+
+	acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
+		       sleep_state, acpi_gbl_sleep_state_names[sleep_state]);
+
+	/* Get the values for the sleep type registers (for display only) */
+
+	status =
+	    acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not evaluate [%s] method, %s\n",
+			       acpi_gbl_sleep_state_names[sleep_state],
+			       acpi_format_exception(status));
+		return;
+	}
+
+	acpi_os_printf
+	    ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
+	     sleep_state, sleep_type_a, sleep_type_b);
+
+	/* Invoke the various sleep/wake interfaces */
+
+	acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
+		       sleep_state);
+	status = acpi_enter_sleep_state_prep(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
+	status = acpi_enter_sleep_state(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
+		       sleep_state);
+	status = acpi_leave_sleep_state_prep(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
+		       sleep_state);
+	status = acpi_leave_sleep_state(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	return;
+
+error_exit:
+	ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
+			sleep_state));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_locks
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about internal mutexes.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_locks(void)
+{
+	u32 i;
+
+	for (i = 0; i < ACPI_MAX_MUTEX; i++) {
+		acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),
+			       acpi_gbl_mutex_info[i].thread_id ==
+			       ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_table_info
+ *
+ * PARAMETERS:  table_arg           - Name of table to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about loaded tables. Current
+ *              implementation displays all loaded tables.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_table_info(char *table_arg)
+{
+	u32 i;
+	struct acpi_table_desc *table_desc;
+	acpi_status status;
+
+	/* Header */
+
+	acpi_os_printf("Idx ID  Status Type                    "
+		       "TableHeader (Sig, Address, Length, Misc)\n");
+
+	/* Walk the entire root table list */
+
+	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
+		table_desc = &acpi_gbl_root_table_list.tables[i];
+
+		/* Index and Table ID */
+
+		acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);
+
+		/* Decode the table flags */
+
+		if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {
+			acpi_os_printf("NotLoaded ");
+		} else {
+			acpi_os_printf(" Loaded ");
+		}
+
+		switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
+		case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+
+			acpi_os_printf("External/virtual ");
+			break;
+
+		case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+			acpi_os_printf("Internal/physical ");
+			break;
+
+		case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+
+			acpi_os_printf("Internal/virtual ");
+			break;
+
+		default:
+
+			acpi_os_printf("INVALID TYPE    ");
+			break;
+		}
+
+		/* Make sure that the table is mapped */
+
+		status = acpi_tb_validate_table(table_desc);
+		if (ACPI_FAILURE(status)) {
+			return;
+		}
+
+		/* Dump the table header */
+
+		if (table_desc->pointer) {
+			acpi_tb_print_table_header(table_desc->address,
+						   table_desc->pointer);
+		} else {
+			/* If the pointer is null, the table has been unloaded */
+
+			ACPI_INFO((AE_INFO, "%4.4s - Table has been unloaded",
+				   table_desc->signature.ascii));
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_unload_acpi_table
+ *
+ * PARAMETERS:  object_name         - Namespace pathname for an object that
+ *                                    is owned by the table to be unloaded
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
+ *              by the table.
+ *
+ ******************************************************************************/
+
+void acpi_db_unload_acpi_table(char *object_name)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+
+	/* Translate name to an Named object */
+
+	node = acpi_db_convert_to_node(object_name);
+	if (!node) {
+		return;
+	}
+
+	status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));
+	if (ACPI_SUCCESS(status)) {
+		acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",
+			       object_name, node);
+	} else {
+		acpi_os_printf("%s, while unloading parent table of [%s]\n",
+			       acpi_format_exception(status), object_name);
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_send_notify
+ *
+ * PARAMETERS:  name                - Name of ACPI object where to send notify
+ *              value               - Value of the notify to send.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
+ *              named object as an ACPI notify.
+ *
+ ******************************************************************************/
+
+void acpi_db_send_notify(char *name, u32 value)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+
+	/* Translate name to an Named object */
+
+	node = acpi_db_convert_to_node(name);
+	if (!node) {
+		return;
+	}
+
+	/* Dispatch the notify if legal */
+
+	if (acpi_ev_is_notify_object(node)) {
+		status = acpi_ev_queue_notify_request(node, value);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not queue notify\n");
+		}
+	} else {
+		acpi_os_printf("Named object [%4.4s] Type %s, "
+			       "must be Device/Thermal/Processor type\n",
+			       acpi_ut_get_node_name(node),
+			       acpi_ut_get_type_name(node->type));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_interfaces
+ *
+ * PARAMETERS:  action_arg          - Null, "install", or "remove"
+ *              interface_name_arg  - Name for install/remove options
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display or modify the global _OSI interface list
+ *
+ ******************************************************************************/
+
+void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)
+{
+	struct acpi_interface_info *next_interface;
+	char *sub_string;
+	acpi_status status;
+
+	/* If no arguments, just display current interface list */
+
+	if (!action_arg) {
+		(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,
+					    ACPI_WAIT_FOREVER);
+
+		next_interface = acpi_gbl_supported_interfaces;
+		while (next_interface) {
+			if (!(next_interface->flags & ACPI_OSI_INVALID)) {
+				acpi_os_printf("%s\n", next_interface->name);
+			}
+
+			next_interface = next_interface->next;
+		}
+
+		acpi_os_release_mutex(acpi_gbl_osi_mutex);
+		return;
+	}
+
+	/* If action_arg exists, so must interface_name_arg */
+
+	if (!interface_name_arg) {
+		acpi_os_printf("Missing Interface Name argument\n");
+		return;
+	}
+
+	/* Uppercase the action for match below */
+
+	acpi_ut_strupr(action_arg);
+
+	/* install - install an interface */
+
+	sub_string = strstr("INSTALL", action_arg);
+	if (sub_string) {
+		status = acpi_install_interface(interface_name_arg);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("%s, while installing \"%s\"\n",
+				       acpi_format_exception(status),
+				       interface_name_arg);
+		}
+		return;
+	}
+
+	/* remove - remove an interface */
+
+	sub_string = strstr("REMOVE", action_arg);
+	if (sub_string) {
+		status = acpi_remove_interface(interface_name_arg);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("%s, while removing \"%s\"\n",
+				       acpi_format_exception(status),
+				       interface_name_arg);
+		}
+		return;
+	}
+
+	/* Invalid action_arg */
+
+	acpi_os_printf("Invalid action argument: %s\n", action_arg);
+	return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_template
+ *
+ * PARAMETERS:  buffer_arg          - Buffer name or address
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump a buffer that contains a resource template
+ *
+ ******************************************************************************/
+
+void acpi_db_display_template(char *buffer_arg)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+	struct acpi_buffer return_buffer;
+
+	/* Translate buffer_arg to an Named object */
+
+	node = acpi_db_convert_to_node(buffer_arg);
+	if (!node || (node == acpi_gbl_root_node)) {
+		acpi_os_printf("Invalid argument: %s\n", buffer_arg);
+		return;
+	}
+
+	/* We must have a buffer object */
+
+	if (node->type != ACPI_TYPE_BUFFER) {
+		acpi_os_printf
+		    ("Not a Buffer object, cannot be a template: %s\n",
+		     buffer_arg);
+		return;
+	}
+
+	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+	return_buffer.pointer = acpi_gbl_db_buffer;
+
+	/* Attempt to convert the raw buffer to a resource list */
+
+	status = acpi_rs_create_resource_list(node->object, &return_buffer);
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	acpi_dbg_level |= ACPI_LV_RESOURCES;
+
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf
+		    ("Could not convert Buffer to a resource list: %s, %s\n",
+		     buffer_arg, acpi_format_exception(status));
+		goto dump_buffer;
+	}
+
+	/* Now we can dump the resource list */
+
+	acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
+						 return_buffer.pointer));
+
+dump_buffer:
+	acpi_os_printf("\nRaw data buffer:\n");
+	acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,
+				  node->object->buffer.length,
+				  DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+	return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_dm_compare_aml_resources
+ *
+ * PARAMETERS:  aml1_buffer         - Contains first resource list
+ *              aml1_buffer_length  - Length of first resource list
+ *              aml2_buffer         - Contains second resource list
+ *              aml2_buffer_length  - Length of second resource list
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
+ *              order to isolate a miscompare to an individual resource)
+ *
+ ******************************************************************************/
+
+static void
+acpi_dm_compare_aml_resources(u8 *aml1_buffer,
+			      acpi_rsdesc_size aml1_buffer_length,
+			      u8 *aml2_buffer,
+			      acpi_rsdesc_size aml2_buffer_length)
+{
+	u8 *aml1;
+	u8 *aml2;
+	u8 *aml1_end;
+	u8 *aml2_end;
+	acpi_rsdesc_size aml1_length;
+	acpi_rsdesc_size aml2_length;
+	acpi_rsdesc_size offset = 0;
+	u8 resource_type;
+	u32 count = 0;
+	u32 i;
+
+	/* Compare overall buffer sizes (may be different due to size rounding) */
+
+	if (aml1_buffer_length != aml2_buffer_length) {
+		acpi_os_printf("**** Buffer length mismatch in converted "
+			       "AML: Original %X, New %X ****\n",
+			       aml1_buffer_length, aml2_buffer_length);
+	}
+
+	aml1 = aml1_buffer;
+	aml2 = aml2_buffer;
+	aml1_end = aml1_buffer + aml1_buffer_length;
+	aml2_end = aml2_buffer + aml2_buffer_length;
+
+	/* Walk the descriptor lists, comparing each descriptor */
+
+	while ((aml1 < aml1_end) && (aml2 < aml2_end)) {
+
+		/* Get the lengths of each descriptor */
+
+		aml1_length = acpi_ut_get_descriptor_length(aml1);
+		aml2_length = acpi_ut_get_descriptor_length(aml2);
+		resource_type = acpi_ut_get_resource_type(aml1);
+
+		/* Check for descriptor length match */
+
+		if (aml1_length != aml2_length) {
+			acpi_os_printf
+			    ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
+			     "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
+			     resource_type, offset, aml1_length, aml2_length);
+		}
+
+		/* Check for descriptor byte match */
+
+		else if (memcmp(aml1, aml2, aml1_length)) {
+			acpi_os_printf
+			    ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
+			     "Offset %8.8X ****\n", count, resource_type,
+			     offset);
+
+			for (i = 0; i < aml1_length; i++) {
+				if (aml1[i] != aml2[i]) {
+					acpi_os_printf
+					    ("Mismatch at byte offset %.2X: is %2.2X, "
+					     "should be %2.2X\n", i, aml2[i],
+					     aml1[i]);
+				}
+			}
+		}
+
+		/* Exit on end_tag descriptor */
+
+		if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
+			return;
+		}
+
+		/* Point to next descriptor in each buffer */
+
+		count++;
+		offset += aml1_length;
+		aml1 += aml1_length;
+		aml2 += aml2_length;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_dm_test_resource_conversion
+ *
+ * PARAMETERS:  node                - Parent device node
+ *              name                - resource method name (_CRS)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Compare the original AML with a conversion of the AML to
+ *              internal resource list, then back to AML.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)
+{
+	acpi_status status;
+	struct acpi_buffer return_buffer;
+	struct acpi_buffer resource_buffer;
+	struct acpi_buffer new_aml;
+	union acpi_object *original_aml;
+
+	acpi_os_printf("Resource Conversion Comparison:\n");
+
+	new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+	/* Get the original _CRS AML resource template */
+
+	status = acpi_evaluate_object(node, name, NULL, &return_buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not obtain %s: %s\n",
+			       name, acpi_format_exception(status));
+		return (status);
+	}
+
+	/* Get the AML resource template, converted to internal resource structs */
+
+	status = acpi_get_current_resources(node, &resource_buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
+			       acpi_format_exception(status));
+		goto exit1;
+	}
+
+	/* Convert internal resource list to external AML resource template */
+
+	status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",
+			       acpi_format_exception(status));
+		goto exit2;
+	}
+
+	/* Compare original AML to the newly created AML resource list */
+
+	original_aml = return_buffer.pointer;
+
+	acpi_dm_compare_aml_resources(original_aml->buffer.pointer,
+				      (acpi_rsdesc_size) original_aml->buffer.
+				      length, new_aml.pointer,
+				      (acpi_rsdesc_size) new_aml.length);
+
+	/* Cleanup and exit */
+
+	ACPI_FREE(new_aml.pointer);
+exit2:
+	ACPI_FREE(resource_buffer.pointer);
+exit1:
+	ACPI_FREE(return_buffer.pointer);
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_resource_callback
+ *
+ * PARAMETERS:  acpi_walk_resource_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
+ *              acpi_walk_resource_buffer.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_resource_callback(struct acpi_resource *resource, void *context)
+{
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_device_resources
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_device_resources(acpi_handle obj_handle,
+			 u32 nesting_level, void *context, void **return_value)
+{
+	struct acpi_namespace_node *node;
+	struct acpi_namespace_node *prt_node = NULL;
+	struct acpi_namespace_node *crs_node = NULL;
+	struct acpi_namespace_node *prs_node = NULL;
+	struct acpi_namespace_node *aei_node = NULL;
+	char *parent_path;
+	struct acpi_buffer return_buffer;
+	acpi_status status;
+
+	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
+	parent_path = acpi_ns_get_external_pathname(node);
+	if (!parent_path) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Get handles to the resource methods for this device */
+
+	(void)acpi_get_handle(node, METHOD_NAME__PRT,
+			      ACPI_CAST_PTR(acpi_handle, &prt_node));
+	(void)acpi_get_handle(node, METHOD_NAME__CRS,
+			      ACPI_CAST_PTR(acpi_handle, &crs_node));
+	(void)acpi_get_handle(node, METHOD_NAME__PRS,
+			      ACPI_CAST_PTR(acpi_handle, &prs_node));
+	(void)acpi_get_handle(node, METHOD_NAME__AEI,
+			      ACPI_CAST_PTR(acpi_handle, &aei_node));
+
+	if (!prt_node && !crs_node && !prs_node && !aei_node) {
+		goto cleanup;	/* Nothing to do */
+	}
+
+	acpi_os_printf("\nDevice: %s\n", parent_path);
+
+	/* Prepare for a return object of arbitrary size */
+
+	return_buffer.pointer = acpi_gbl_db_buffer;
+	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+	/* _PRT */
+
+	if (prt_node) {
+		acpi_os_printf("Evaluating _PRT\n");
+
+		status =
+		    acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _PRT: %s\n",
+				       acpi_format_exception(status));
+			goto get_crs;
+		}
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status = acpi_get_irq_routing_table(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("GetIrqRoutingTable failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_crs;
+		}
+
+		acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));
+	}
+
+	/* _CRS */
+
+get_crs:
+	if (crs_node) {
+		acpi_os_printf("Evaluating _CRS\n");
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status =
+		    acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _CRS: %s\n",
+				       acpi_format_exception(status));
+			goto get_prs;
+		}
+
+		/* This code exercises the acpi_walk_resources interface */
+
+		status = acpi_walk_resources(node, METHOD_NAME__CRS,
+					     acpi_db_resource_callback, NULL);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiWalkResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_prs;
+		}
+
+		/* Get the _CRS resource list (test ALLOCATE buffer) */
+
+		return_buffer.pointer = NULL;
+		return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+		status = acpi_get_current_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_prs;
+		}
+
+		/* This code exercises the acpi_walk_resource_buffer interface */
+
+		status = acpi_walk_resource_buffer(&return_buffer,
+						   acpi_db_resource_callback,
+						   NULL);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",
+				       acpi_format_exception(status));
+			goto end_crs;
+		}
+
+		/* Dump the _CRS resource list */
+
+		acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
+							 return_buffer.
+							 pointer));
+
+		/*
+		 * Perform comparison of original AML to newly created AML. This
+		 * tests both the AML->Resource conversion and the Resource->AML
+		 * conversion.
+		 */
+		(void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);
+
+		/* Execute _SRS with the resource list */
+
+		acpi_os_printf("Evaluating _SRS\n");
+
+		status = acpi_set_current_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiSetCurrentResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto end_crs;
+		}
+
+end_crs:
+		ACPI_FREE(return_buffer.pointer);
+	}
+
+	/* _PRS */
+
+get_prs:
+	if (prs_node) {
+		acpi_os_printf("Evaluating _PRS\n");
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status =
+		    acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _PRS: %s\n",
+				       acpi_format_exception(status));
+			goto get_aei;
+		}
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status = acpi_get_possible_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiGetPossibleResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_aei;
+		}
+
+		acpi_rs_dump_resource_list(ACPI_CAST_PTR
+					   (struct acpi_resource,
+					    acpi_gbl_db_buffer));
+	}
+
+	/* _AEI */
+
+get_aei:
+	if (aei_node) {
+		acpi_os_printf("Evaluating _AEI\n");
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status =
+		    acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _AEI: %s\n",
+				       acpi_format_exception(status));
+			goto cleanup;
+		}
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status = acpi_get_event_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiGetEventResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto cleanup;
+		}
+
+		acpi_rs_dump_resource_list(ACPI_CAST_PTR
+					   (struct acpi_resource,
+					    acpi_gbl_db_buffer));
+	}
+
+cleanup:
+	ACPI_FREE(parent_path);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_resources
+ *
+ * PARAMETERS:  object_arg          - String object name or object pointer.
+ *                                    NULL or "*" means "display resources for
+ *                                    all devices"
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the resource objects associated with a device.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_resources(char *object_arg)
+{
+	struct acpi_namespace_node *node;
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	acpi_dbg_level |= ACPI_LV_RESOURCES;
+
+	/* Asterisk means "display resources for all devices" */
+
+	if (!object_arg || (!strcmp(object_arg, "*"))) {
+		(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+					  ACPI_UINT32_MAX,
+					  acpi_db_device_resources, NULL, NULL,
+					  NULL);
+	} else {
+		/* Convert string to object pointer */
+
+		node = acpi_db_convert_to_node(object_arg);
+		if (node) {
+			if (node->type != ACPI_TYPE_DEVICE) {
+				acpi_os_printf
+				    ("%4.4s: Name is not a device object (%s)\n",
+				     node->name.ascii,
+				     acpi_ut_get_type_name(node->type));
+			} else {
+				(void)acpi_db_device_resources(node, 0, NULL,
+							       NULL);
+			}
+		}
+	}
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_generate_gpe
+ *
+ * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string
+ *              block_arg           - GPE block number, ascii string
+ *                                    0 or 1 for FADT GPE blocks
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate firing of a GPE
+ *
+ ******************************************************************************/
+
+void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
+{
+	u32 block_number = 0;
+	u32 gpe_number;
+	struct acpi_gpe_event_info *gpe_event_info;
+
+	gpe_number = strtoul(gpe_arg, NULL, 0);
+
+	/*
+	 * If no block arg, or block arg == 0 or 1, use the FADT-defined
+	 * GPE blocks.
+	 */
+	if (block_arg) {
+		block_number = strtoul(block_arg, NULL, 0);
+		if (block_number == 1) {
+			block_number = 0;
+		}
+	}
+
+	gpe_event_info =
+	    acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
+				       gpe_number);
+	if (!gpe_event_info) {
+		acpi_os_printf("Invalid GPE\n");
+		return;
+	}
+
+	(void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_generate_sci
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
+ *
+ ******************************************************************************/
+
+void acpi_db_generate_sci(void)
+{
+	acpi_ev_sci_dispatch();
+}
+
+#endif				/* !ACPI_REDUCED_HARDWARE */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_trace
+ *
+ * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer
+ *                                    DISABLE to disable tracer
+ *              method_arg          - Method to trace
+ *              once_arg            - Whether trace once
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Control method tracing facility
+ *
+ ******************************************************************************/
+
+void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
+{
+	u32 debug_level = 0;
+	u32 debug_layer = 0;
+	u32 flags = 0;
+
+	if (enable_arg) {
+		acpi_ut_strupr(enable_arg);
+	}
+
+	if (once_arg) {
+		acpi_ut_strupr(once_arg);
+	}
+
+	if (method_arg) {
+		if (acpi_db_trace_method_name) {
+			ACPI_FREE(acpi_db_trace_method_name);
+			acpi_db_trace_method_name = NULL;
+		}
+
+		acpi_db_trace_method_name =
+		    ACPI_ALLOCATE(strlen(method_arg) + 1);
+		if (!acpi_db_trace_method_name) {
+			acpi_os_printf("Failed to allocate method name (%s)\n",
+				       method_arg);
+			return;
+		}
+
+		strcpy(acpi_db_trace_method_name, method_arg);
+	}
+
+	if (!strcmp(enable_arg, "ENABLE") ||
+	    !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
+		if (!strcmp(enable_arg, "ENABLE")) {
+
+			/* Inherit current console settings */
+
+			debug_level = acpi_gbl_db_console_debug_level;
+			debug_layer = acpi_dbg_layer;
+		} else {
+			/* Restrict console output to trace points only */
+
+			debug_level = ACPI_LV_TRACE_POINT;
+			debug_layer = ACPI_EXECUTER;
+		}
+
+		flags = ACPI_TRACE_ENABLED;
+
+		if (!strcmp(enable_arg, "OPCODE")) {
+			flags |= ACPI_TRACE_OPCODE;
+		}
+
+		if (once_arg && !strcmp(once_arg, "ONCE")) {
+			flags |= ACPI_TRACE_ONESHOT;
+		}
+	}
+
+	(void)acpi_debug_trace(acpi_db_trace_method_name,
+			       debug_level, debug_layer, flags);
+}
diff --git a/drivers/acpi/acpica/dbconvert.c b/drivers/acpi/acpica/dbconvert.c
new file mode 100644
index 0000000..a71632c
--- /dev/null
+++ b/drivers/acpi/acpica/dbconvert.c
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ *
+ * Module Name: dbconvert - debugger miscellaneous conversion routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbconvert")
+
+#define DB_DEFAULT_PKG_ELEMENTS     33
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_hex_char_to_value
+ *
+ * PARAMETERS:  hex_char            - Ascii Hex digit, 0-9|a-f|A-F
+ *              return_value        - Where the converted value is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16).
+ *
+ ******************************************************************************/
+acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value)
+{
+	u8 value;
+
+	/* Digit must be ascii [0-9a-fA-F] */
+
+	if (!isxdigit(hex_char)) {
+		return (AE_BAD_HEX_CONSTANT);
+	}
+
+	if (hex_char <= 0x39) {
+		value = (u8)(hex_char - 0x30);
+	} else {
+		value = (u8)(toupper(hex_char) - 0x37);
+	}
+
+	*return_value = value;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_hex_byte_to_binary
+ *
+ * PARAMETERS:  hex_byte            - Double hex digit (0x00 - 0xFF) in format:
+ *                                    hi_byte then lo_byte.
+ *              return_value        - Where the converted value is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255).
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_db_hex_byte_to_binary(char *hex_byte, u8 *return_value)
+{
+	u8 local0;
+	u8 local1;
+	acpi_status status;
+
+	/* High byte */
+
+	status = acpi_db_hex_char_to_value(hex_byte[0], &local0);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Low byte */
+
+	status = acpi_db_hex_char_to_value(hex_byte[1], &local1);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	*return_value = (u8)((local0 << 4) | local1);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_buffer
+ *
+ * PARAMETERS:  string              - Input string to be converted
+ *              object              - Where the buffer object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a string to a buffer object. String is treated a list
+ *              of buffer elements, each separated by a space or comma.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_convert_to_buffer(char *string, union acpi_object *object)
+{
+	u32 i;
+	u32 j;
+	u32 length;
+	u8 *buffer;
+	acpi_status status;
+
+	/* Generate the final buffer length */
+
+	for (i = 0, length = 0; string[i];) {
+		i += 2;
+		length++;
+
+		while (string[i] && ((string[i] == ',') || (string[i] == ' '))) {
+			i++;
+		}
+	}
+
+	buffer = ACPI_ALLOCATE(length);
+	if (!buffer) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Convert the command line bytes to the buffer */
+
+	for (i = 0, j = 0; string[i];) {
+		status = acpi_db_hex_byte_to_binary(&string[i], &buffer[j]);
+		if (ACPI_FAILURE(status)) {
+			ACPI_FREE(buffer);
+			return (status);
+		}
+
+		j++;
+		i += 2;
+		while (string[i] && ((string[i] == ',') || (string[i] == ' '))) {
+			i++;
+		}
+	}
+
+	object->type = ACPI_TYPE_BUFFER;
+	object->buffer.pointer = buffer;
+	object->buffer.length = length;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_package
+ *
+ * PARAMETERS:  string              - Input string to be converted
+ *              object              - Where the package object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a string to a package object. Handles nested packages
+ *              via recursion with acpi_db_convert_to_object.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_convert_to_package(char *string, union acpi_object * object)
+{
+	char *this;
+	char *next;
+	u32 i;
+	acpi_object_type type;
+	union acpi_object *elements;
+	acpi_status status;
+
+	elements =
+	    ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
+				 sizeof(union acpi_object));
+
+	this = string;
+	for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {
+		this = acpi_db_get_next_token(this, &next, &type);
+		if (!this) {
+			break;
+		}
+
+		/* Recursive call to convert each package element */
+
+		status = acpi_db_convert_to_object(type, this, &elements[i]);
+		if (ACPI_FAILURE(status)) {
+			acpi_db_delete_objects(i + 1, elements);
+			ACPI_FREE(elements);
+			return (status);
+		}
+
+		this = next;
+	}
+
+	object->type = ACPI_TYPE_PACKAGE;
+	object->package.count = i;
+	object->package.elements = elements;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_object
+ *
+ * PARAMETERS:  type                - Object type as determined by parser
+ *              string              - Input string to be converted
+ *              object              - Where the new object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a typed and tokenized string to an union acpi_object. Typing:
+ *              1) String objects were surrounded by quotes.
+ *              2) Buffer objects were surrounded by parentheses.
+ *              3) Package objects were surrounded by brackets "[]".
+ *              4) All standalone tokens are treated as integers.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_convert_to_object(acpi_object_type type,
+			  char *string, union acpi_object * object)
+{
+	acpi_status status = AE_OK;
+
+	switch (type) {
+	case ACPI_TYPE_STRING:
+
+		object->type = ACPI_TYPE_STRING;
+		object->string.pointer = string;
+		object->string.length = (u32)strlen(string);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		status = acpi_db_convert_to_buffer(string, object);
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+
+		status = acpi_db_convert_to_package(string, object);
+		break;
+
+	default:
+
+		object->type = ACPI_TYPE_INTEGER;
+		status = acpi_ut_strtoul64(string, 16, &object->integer.value);
+		break;
+	}
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_encode_pld_buffer
+ *
+ * PARAMETERS:  pld_info            - _PLD buffer struct (Using local struct)
+ *
+ * RETURN:      Encode _PLD buffer suitable for return value from _PLD
+ *
+ * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros
+ *
+ ******************************************************************************/
+
+u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info)
+{
+	u32 *buffer;
+	u32 dword;
+
+	buffer = ACPI_ALLOCATE_ZEROED(ACPI_PLD_BUFFER_SIZE);
+	if (!buffer) {
+		return (NULL);
+	}
+
+	/* First 32 bits */
+
+	dword = 0;
+	ACPI_PLD_SET_REVISION(&dword, pld_info->revision);
+	ACPI_PLD_SET_IGNORE_COLOR(&dword, pld_info->ignore_color);
+	ACPI_PLD_SET_RED(&dword, pld_info->red);
+	ACPI_PLD_SET_GREEN(&dword, pld_info->green);
+	ACPI_PLD_SET_BLUE(&dword, pld_info->blue);
+	ACPI_MOVE_32_TO_32(&buffer[0], &dword);
+
+	/* Second 32 bits */
+
+	dword = 0;
+	ACPI_PLD_SET_WIDTH(&dword, pld_info->width);
+	ACPI_PLD_SET_HEIGHT(&dword, pld_info->height);
+	ACPI_MOVE_32_TO_32(&buffer[1], &dword);
+
+	/* Third 32 bits */
+
+	dword = 0;
+	ACPI_PLD_SET_USER_VISIBLE(&dword, pld_info->user_visible);
+	ACPI_PLD_SET_DOCK(&dword, pld_info->dock);
+	ACPI_PLD_SET_LID(&dword, pld_info->lid);
+	ACPI_PLD_SET_PANEL(&dword, pld_info->panel);
+	ACPI_PLD_SET_VERTICAL(&dword, pld_info->vertical_position);
+	ACPI_PLD_SET_HORIZONTAL(&dword, pld_info->horizontal_position);
+	ACPI_PLD_SET_SHAPE(&dword, pld_info->shape);
+	ACPI_PLD_SET_ORIENTATION(&dword, pld_info->group_orientation);
+	ACPI_PLD_SET_TOKEN(&dword, pld_info->group_token);
+	ACPI_PLD_SET_POSITION(&dword, pld_info->group_position);
+	ACPI_PLD_SET_BAY(&dword, pld_info->bay);
+	ACPI_MOVE_32_TO_32(&buffer[2], &dword);
+
+	/* Fourth 32 bits */
+
+	dword = 0;
+	ACPI_PLD_SET_EJECTABLE(&dword, pld_info->ejectable);
+	ACPI_PLD_SET_OSPM_EJECT(&dword, pld_info->ospm_eject_required);
+	ACPI_PLD_SET_CABINET(&dword, pld_info->cabinet_number);
+	ACPI_PLD_SET_CARD_CAGE(&dword, pld_info->card_cage_number);
+	ACPI_PLD_SET_REFERENCE(&dword, pld_info->reference);
+	ACPI_PLD_SET_ROTATION(&dword, pld_info->rotation);
+	ACPI_PLD_SET_ORDER(&dword, pld_info->order);
+	ACPI_MOVE_32_TO_32(&buffer[3], &dword);
+
+	if (pld_info->revision >= 2) {
+
+		/* Fifth 32 bits */
+
+		dword = 0;
+		ACPI_PLD_SET_VERT_OFFSET(&dword, pld_info->vertical_offset);
+		ACPI_PLD_SET_HORIZ_OFFSET(&dword, pld_info->horizontal_offset);
+		ACPI_MOVE_32_TO_32(&buffer[4], &dword);
+	}
+
+	return (ACPI_CAST_PTR(u8, buffer));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_pld_buffer
+ *
+ * PARAMETERS:  obj_desc            - Object returned from _PLD method
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Dumps formatted contents of a _PLD return buffer.
+ *
+ ******************************************************************************/
+
+#define ACPI_PLD_OUTPUT     "%20s : %-6X\n"
+
+void acpi_db_dump_pld_buffer(union acpi_object *obj_desc)
+{
+	union acpi_object *buffer_desc;
+	struct acpi_pld_info *pld_info;
+	u8 *new_buffer;
+	acpi_status status;
+
+	/* Object must be of type Package with at least one Buffer element */
+
+	if (obj_desc->type != ACPI_TYPE_PACKAGE) {
+		return;
+	}
+
+	buffer_desc = &obj_desc->package.elements[0];
+	if (buffer_desc->type != ACPI_TYPE_BUFFER) {
+		return;
+	}
+
+	/* Convert _PLD buffer to local _PLD struct */
+
+	status = acpi_decode_pld_buffer(buffer_desc->buffer.pointer,
+					buffer_desc->buffer.length, &pld_info);
+	if (ACPI_FAILURE(status)) {
+		return;
+	}
+
+	/* Encode local _PLD struct back to a _PLD buffer */
+
+	new_buffer = acpi_db_encode_pld_buffer(pld_info);
+	if (!new_buffer) {
+		return;
+	}
+
+	/* The two bit-packed buffers should match */
+
+	if (memcmp(new_buffer, buffer_desc->buffer.pointer,
+		   buffer_desc->buffer.length)) {
+		acpi_os_printf
+		    ("Converted _PLD buffer does not compare. New:\n");
+
+		acpi_ut_dump_buffer(new_buffer,
+				    buffer_desc->buffer.length, DB_BYTE_DISPLAY,
+				    0);
+	}
+
+	/* First 32-bit dword */
+
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Revision", pld_info->revision);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_IgnoreColor",
+		       pld_info->ignore_color);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Red", pld_info->red);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Green", pld_info->green);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Blue", pld_info->blue);
+
+	/* Second 32-bit dword */
+
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Width", pld_info->width);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Height", pld_info->height);
+
+	/* Third 32-bit dword */
+
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_UserVisible",
+		       pld_info->user_visible);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Dock", pld_info->dock);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Lid", pld_info->lid);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Panel", pld_info->panel);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalPosition",
+		       pld_info->vertical_position);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalPosition",
+		       pld_info->horizontal_position);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Shape", pld_info->shape);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupOrientation",
+		       pld_info->group_orientation);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupToken",
+		       pld_info->group_token);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupPosition",
+		       pld_info->group_position);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Bay", pld_info->bay);
+
+	/* Fourth 32-bit dword */
+
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Ejectable", pld_info->ejectable);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_EjectRequired",
+		       pld_info->ospm_eject_required);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CabinetNumber",
+		       pld_info->cabinet_number);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CardCageNumber",
+		       pld_info->card_cage_number);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Reference", pld_info->reference);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Rotation", pld_info->rotation);
+	acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Order", pld_info->order);
+
+	/* Fifth 32-bit dword */
+
+	if (buffer_desc->buffer.length > 16) {
+		acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalOffset",
+			       pld_info->vertical_offset);
+		acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalOffset",
+			       pld_info->horizontal_offset);
+	}
+
+	ACPI_FREE(pld_info);
+	ACPI_FREE(new_buffer);
+}
diff --git a/drivers/acpi/acpica/dbdisply.c b/drivers/acpi/acpica/dbdisply.c
new file mode 100644
index 0000000..672977e
--- /dev/null
+++ b/drivers/acpi/acpica/dbdisply.c
@@ -0,0 +1,1108 @@
+/*******************************************************************************
+ *
+ * Module Name: dbdisply - debug display commands
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbdisply")
+
+/* Local prototypes */
+static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op);
+
+static void *acpi_db_get_pointer(void *target);
+
+static acpi_status
+acpi_db_display_non_root_handlers(acpi_handle obj_handle,
+				  u32 nesting_level,
+				  void *context, void **return_value);
+
+/*
+ * System handler information.
+ * Used for Handlers command, in acpi_db_display_handlers.
+ */
+#define ACPI_PREDEFINED_PREFIX          "%25s (%.2X) : "
+#define ACPI_HANDLER_NAME_STRING               "%30s : "
+#define ACPI_HANDLER_PRESENT_STRING                    "%-9s (%p)\n"
+#define ACPI_HANDLER_PRESENT_STRING2                   "%-9s (%p)"
+#define ACPI_HANDLER_NOT_PRESENT_STRING                "%-9s\n"
+
+/* All predefined Address Space IDs */
+
+static acpi_adr_space_type acpi_gbl_space_id_list[] = {
+	ACPI_ADR_SPACE_SYSTEM_MEMORY,
+	ACPI_ADR_SPACE_SYSTEM_IO,
+	ACPI_ADR_SPACE_PCI_CONFIG,
+	ACPI_ADR_SPACE_EC,
+	ACPI_ADR_SPACE_SMBUS,
+	ACPI_ADR_SPACE_CMOS,
+	ACPI_ADR_SPACE_PCI_BAR_TARGET,
+	ACPI_ADR_SPACE_IPMI,
+	ACPI_ADR_SPACE_GPIO,
+	ACPI_ADR_SPACE_GSBUS,
+	ACPI_ADR_SPACE_DATA_TABLE,
+	ACPI_ADR_SPACE_FIXED_HARDWARE
+};
+
+/* Global handler information */
+
+typedef struct acpi_handler_info {
+	void *handler;
+	char *name;
+
+} acpi_handler_info;
+
+static struct acpi_handler_info acpi_gbl_handler_list[] = {
+	{&acpi_gbl_global_notify[0].handler, "System Notifications"},
+	{&acpi_gbl_global_notify[1].handler, "Device Notifications"},
+	{&acpi_gbl_table_handler, "ACPI Table Events"},
+	{&acpi_gbl_exception_handler, "Control Method Exceptions"},
+	{&acpi_gbl_interface_handler, "OSI Invocations"}
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_pointer
+ *
+ * PARAMETERS:  target          - Pointer to string to be converted
+ *
+ * RETURN:      Converted pointer
+ *
+ * DESCRIPTION: Convert an ascii pointer value to a real value
+ *
+ ******************************************************************************/
+
+static void *acpi_db_get_pointer(void *target)
+{
+	void *obj_ptr;
+	acpi_size address;
+
+	address = strtoul(target, NULL, 16);
+	obj_ptr = ACPI_TO_POINTER(address);
+	return (obj_ptr);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_parser_descriptor
+ *
+ * PARAMETERS:  op              - A parser Op descriptor
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display a formatted parser object
+ *
+ ******************************************************************************/
+
+static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op)
+{
+	const struct acpi_opcode_info *info;
+
+	info = acpi_ps_get_opcode_info(op->common.aml_opcode);
+
+	acpi_os_printf("Parser Op Descriptor:\n");
+	acpi_os_printf("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode);
+
+	ACPI_DEBUG_ONLY_MEMBERS(acpi_os_printf("%20.20s : %s\n", "Opcode Name",
+					       info->name));
+
+	acpi_os_printf("%20.20s : %p\n", "Value/ArgList", op->common.value.arg);
+	acpi_os_printf("%20.20s : %p\n", "Parent", op->common.parent);
+	acpi_os_printf("%20.20s : %p\n", "NextOp", op->common.next);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_and_display_object
+ *
+ * PARAMETERS:  target          - String with object to be displayed. Names
+ *                                and hex pointers are supported.
+ *              output_type     - Byte, Word, Dword, or Qword (B|W|D|Q)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display a formatted ACPI object
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_and_display_object(char *target, char *output_type)
+{
+	void *obj_ptr;
+	struct acpi_namespace_node *node;
+	union acpi_operand_object *obj_desc;
+	u32 display = DB_BYTE_DISPLAY;
+	char buffer[80];
+	struct acpi_buffer ret_buf;
+	acpi_status status;
+	u32 size;
+
+	if (!target) {
+		return;
+	}
+
+	/* Decode the output type */
+
+	if (output_type) {
+		acpi_ut_strupr(output_type);
+		if (output_type[0] == 'W') {
+			display = DB_WORD_DISPLAY;
+		} else if (output_type[0] == 'D') {
+			display = DB_DWORD_DISPLAY;
+		} else if (output_type[0] == 'Q') {
+			display = DB_QWORD_DISPLAY;
+		}
+	}
+
+	ret_buf.length = sizeof(buffer);
+	ret_buf.pointer = buffer;
+
+	/* Differentiate between a number and a name */
+
+	if ((target[0] >= 0x30) && (target[0] <= 0x39)) {
+		obj_ptr = acpi_db_get_pointer(target);
+		if (!acpi_os_readable(obj_ptr, 16)) {
+			acpi_os_printf
+			    ("Address %p is invalid in this address space\n",
+			     obj_ptr);
+			return;
+		}
+
+		/* Decode the object type */
+
+		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)) {
+		case ACPI_DESC_TYPE_NAMED:
+
+			/* This is a namespace Node */
+
+			if (!acpi_os_readable
+			    (obj_ptr, sizeof(struct acpi_namespace_node))) {
+				acpi_os_printf
+				    ("Cannot read entire Named object at address %p\n",
+				     obj_ptr);
+				return;
+			}
+
+			node = obj_ptr;
+			goto dump_node;
+
+		case ACPI_DESC_TYPE_OPERAND:
+
+			/* This is a ACPI OPERAND OBJECT */
+
+			if (!acpi_os_readable
+			    (obj_ptr, sizeof(union acpi_operand_object))) {
+				acpi_os_printf
+				    ("Cannot read entire ACPI object at address %p\n",
+				     obj_ptr);
+				return;
+			}
+
+			acpi_ut_debug_dump_buffer(obj_ptr,
+						  sizeof(union
+							 acpi_operand_object),
+						  display, ACPI_UINT32_MAX);
+			acpi_ex_dump_object_descriptor(obj_ptr, 1);
+			break;
+
+		case ACPI_DESC_TYPE_PARSER:
+
+			/* This is a Parser Op object */
+
+			if (!acpi_os_readable
+			    (obj_ptr, sizeof(union acpi_parse_object))) {
+				acpi_os_printf
+				    ("Cannot read entire Parser object at address %p\n",
+				     obj_ptr);
+				return;
+			}
+
+			acpi_ut_debug_dump_buffer(obj_ptr,
+						  sizeof(union
+							 acpi_parse_object),
+						  display, ACPI_UINT32_MAX);
+			acpi_db_dump_parser_descriptor((union acpi_parse_object
+							*)obj_ptr);
+			break;
+
+		default:
+
+			/* Is not a recognizeable object */
+
+			acpi_os_printf
+			    ("Not a known ACPI internal object, descriptor type %2.2X\n",
+			     ACPI_GET_DESCRIPTOR_TYPE(obj_ptr));
+
+			size = 16;
+			if (acpi_os_readable(obj_ptr, 64)) {
+				size = 64;
+			}
+
+			/* Just dump some memory */
+
+			acpi_ut_debug_dump_buffer(obj_ptr, size, display,
+						  ACPI_UINT32_MAX);
+			break;
+		}
+
+		return;
+	}
+
+	/* The parameter is a name string that must be resolved to a Named obj */
+
+	node = acpi_db_local_ns_lookup(target);
+	if (!node) {
+		return;
+	}
+
+dump_node:
+	/* Now dump the NS node */
+
+	status = acpi_get_name(node, ACPI_FULL_PATHNAME_NO_TRAILING, &ret_buf);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not convert name to pathname\n");
+	}
+
+	else {
+		acpi_os_printf("Object (%p) Pathname: %s\n",
+			       node, (char *)ret_buf.pointer);
+	}
+
+	if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
+		acpi_os_printf("Invalid Named object at address %p\n", node);
+		return;
+	}
+
+	acpi_ut_debug_dump_buffer((void *)node,
+				  sizeof(struct acpi_namespace_node), display,
+				  ACPI_UINT32_MAX);
+	acpi_ex_dump_namespace_node(node, 1);
+
+	obj_desc = acpi_ns_get_attached_object(node);
+	if (obj_desc) {
+		acpi_os_printf("\nAttached Object (%p):\n", obj_desc);
+		if (!acpi_os_readable
+		    (obj_desc, sizeof(union acpi_operand_object))) {
+			acpi_os_printf
+			    ("Invalid internal ACPI Object at address %p\n",
+			     obj_desc);
+			return;
+		}
+
+		acpi_ut_debug_dump_buffer((void *)obj_desc,
+					  sizeof(union acpi_operand_object),
+					  display, ACPI_UINT32_MAX);
+		acpi_ex_dump_object_descriptor(obj_desc, 1);
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_method_info
+ *
+ * PARAMETERS:  start_op        - Root of the control method parse tree
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about the current method
+ *
+ ******************************************************************************/
+
+void acpi_db_display_method_info(union acpi_parse_object *start_op)
+{
+	struct acpi_walk_state *walk_state;
+	union acpi_operand_object *obj_desc;
+	struct acpi_namespace_node *node;
+	union acpi_parse_object *root_op;
+	union acpi_parse_object *op;
+	const struct acpi_opcode_info *op_info;
+	u32 num_ops = 0;
+	u32 num_operands = 0;
+	u32 num_operators = 0;
+	u32 num_remaining_ops = 0;
+	u32 num_remaining_operands = 0;
+	u32 num_remaining_operators = 0;
+	u8 count_remaining = FALSE;
+
+	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	obj_desc = walk_state->method_desc;
+	node = walk_state->method_node;
+
+	acpi_os_printf("Currently executing control method is [%4.4s]\n",
+		       acpi_ut_get_node_name(node));
+	acpi_os_printf("%X Arguments, SyncLevel = %X\n",
+		       (u32)obj_desc->method.param_count,
+		       (u32)obj_desc->method.sync_level);
+
+	root_op = start_op;
+	while (root_op->common.parent) {
+		root_op = root_op->common.parent;
+	}
+
+	op = root_op;
+
+	while (op) {
+		if (op == start_op) {
+			count_remaining = TRUE;
+		}
+
+		num_ops++;
+		if (count_remaining) {
+			num_remaining_ops++;
+		}
+
+		/* Decode the opcode */
+
+		op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
+		switch (op_info->class) {
+		case AML_CLASS_ARGUMENT:
+
+			if (count_remaining) {
+				num_remaining_operands++;
+			}
+
+			num_operands++;
+			break;
+
+		case AML_CLASS_UNKNOWN:
+
+			/* Bad opcode or ASCII character */
+
+			continue;
+
+		default:
+
+			if (count_remaining) {
+				num_remaining_operators++;
+			}
+
+			num_operators++;
+			break;
+		}
+
+		op = acpi_ps_get_depth_next(start_op, op);
+	}
+
+	acpi_os_printf
+	    ("Method contains:       %X AML Opcodes - %X Operators, %X Operands\n",
+	     num_ops, num_operators, num_operands);
+
+	acpi_os_printf
+	    ("Remaining to execute:  %X AML Opcodes - %X Operators, %X Operands\n",
+	     num_remaining_ops, num_remaining_operators,
+	     num_remaining_operands);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_locals
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_display_locals(void)
+{
+	struct acpi_walk_state *walk_state;
+
+	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	acpi_db_decode_locals(walk_state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_arguments
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_display_arguments(void)
+{
+	struct acpi_walk_state *walk_state;
+
+	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	acpi_db_decode_arguments(walk_state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_results
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display current contents of a method result stack
+ *
+ ******************************************************************************/
+
+void acpi_db_display_results(void)
+{
+	u32 i;
+	struct acpi_walk_state *walk_state;
+	union acpi_operand_object *obj_desc;
+	u32 result_count = 0;
+	struct acpi_namespace_node *node;
+	union acpi_generic_state *frame;
+	u32 index;		/* Index onto current frame */
+
+	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	obj_desc = walk_state->method_desc;
+	node = walk_state->method_node;
+
+	if (walk_state->results) {
+		result_count = walk_state->result_count;
+	}
+
+	acpi_os_printf("Method [%4.4s] has %X stacked result objects\n",
+		       acpi_ut_get_node_name(node), result_count);
+
+	/* From the top element of result stack */
+
+	frame = walk_state->results;
+	index = (result_count - 1) % ACPI_RESULTS_FRAME_OBJ_NUM;
+
+	for (i = 0; i < result_count; i++) {
+		obj_desc = frame->results.obj_desc[index];
+		acpi_os_printf("Result%u: ", i);
+		acpi_db_display_internal_object(obj_desc, walk_state);
+
+		if (index == 0) {
+			frame = frame->results.next;
+			index = ACPI_RESULTS_FRAME_OBJ_NUM;
+		}
+
+		index--;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_calling_tree
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display current calling tree of nested control methods
+ *
+ ******************************************************************************/
+
+void acpi_db_display_calling_tree(void)
+{
+	struct acpi_walk_state *walk_state;
+	struct acpi_namespace_node *node;
+
+	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	node = walk_state->method_node;
+	acpi_os_printf("Current Control Method Call Tree\n");
+
+	while (walk_state) {
+		node = walk_state->method_node;
+		acpi_os_printf("  [%4.4s]\n", acpi_ut_get_node_name(node));
+
+		walk_state = walk_state->next;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_object_type
+ *
+ * PARAMETERS:  name            - User entered NS node handle or name
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display type of an arbitrary NS node
+ *
+ ******************************************************************************/
+
+void acpi_db_display_object_type(char *name)
+{
+	struct acpi_namespace_node *node;
+	struct acpi_device_info *info;
+	acpi_status status;
+	u32 i;
+
+	node = acpi_db_convert_to_node(name);
+	if (!node) {
+		return;
+	}
+
+	status = acpi_get_object_info(ACPI_CAST_PTR(acpi_handle, node), &info);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not get object info, %s\n",
+			       acpi_format_exception(status));
+		return;
+	}
+
+	if (info->valid & ACPI_VALID_ADR) {
+		acpi_os_printf("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n",
+			       ACPI_FORMAT_UINT64(info->address),
+			       info->current_status, info->flags);
+	}
+	if (info->valid & ACPI_VALID_SXDS) {
+		acpi_os_printf("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n",
+			       info->highest_dstates[0],
+			       info->highest_dstates[1],
+			       info->highest_dstates[2],
+			       info->highest_dstates[3]);
+	}
+	if (info->valid & ACPI_VALID_SXWS) {
+		acpi_os_printf
+		    ("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n",
+		     info->lowest_dstates[0], info->lowest_dstates[1],
+		     info->lowest_dstates[2], info->lowest_dstates[3],
+		     info->lowest_dstates[4]);
+	}
+
+	if (info->valid & ACPI_VALID_HID) {
+		acpi_os_printf("HID: %s\n", info->hardware_id.string);
+	}
+
+	if (info->valid & ACPI_VALID_UID) {
+		acpi_os_printf("UID: %s\n", info->unique_id.string);
+	}
+
+	if (info->valid & ACPI_VALID_SUB) {
+		acpi_os_printf("SUB: %s\n", info->subsystem_id.string);
+	}
+
+	if (info->valid & ACPI_VALID_CID) {
+		for (i = 0; i < info->compatible_id_list.count; i++) {
+			acpi_os_printf("CID %u: %s\n", i,
+				       info->compatible_id_list.ids[i].string);
+		}
+	}
+
+	ACPI_FREE(info);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_result_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *              walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ * Note: Curently only displays the result object if we are single stepping.
+ * However, this output may be useful in other contexts and could be enabled
+ * to do so if needed.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_result_object(union acpi_operand_object *obj_desc,
+			      struct acpi_walk_state *walk_state)
+{
+
+	/* Only display if single stepping */
+
+	if (!acpi_gbl_cm_single_step) {
+		return;
+	}
+
+	acpi_os_printf("ResultObj: ");
+	acpi_db_display_internal_object(obj_desc, walk_state);
+	acpi_os_printf("\n");
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_argument_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *              walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
+				struct acpi_walk_state *walk_state)
+{
+
+	if (!acpi_gbl_cm_single_step) {
+		return;
+	}
+
+	acpi_os_printf("ArgObj:  ");
+	acpi_db_display_internal_object(obj_desc, walk_state);
+}
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_gpes
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the current GPE structures
+ *
+ ******************************************************************************/
+
+void acpi_db_display_gpes(void)
+{
+	struct acpi_gpe_block_info *gpe_block;
+	struct acpi_gpe_xrupt_info *gpe_xrupt_info;
+	struct acpi_gpe_event_info *gpe_event_info;
+	struct acpi_gpe_register_info *gpe_register_info;
+	char *gpe_type;
+	struct acpi_gpe_notify_info *notify;
+	u32 gpe_index;
+	u32 block = 0;
+	u32 i;
+	u32 j;
+	u32 count;
+	char buffer[80];
+	struct acpi_buffer ret_buf;
+	acpi_status status;
+
+	ret_buf.length = sizeof(buffer);
+	ret_buf.pointer = buffer;
+
+	block = 0;
+
+	/* Walk the GPE lists */
+
+	gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
+	while (gpe_xrupt_info) {
+		gpe_block = gpe_xrupt_info->gpe_block_list_head;
+		while (gpe_block) {
+			status = acpi_get_name(gpe_block->node,
+					       ACPI_FULL_PATHNAME_NO_TRAILING,
+					       &ret_buf);
+			if (ACPI_FAILURE(status)) {
+				acpi_os_printf
+				    ("Could not convert name to pathname\n");
+			}
+
+			if (gpe_block->node == acpi_gbl_fadt_gpe_device) {
+				gpe_type = "FADT-defined GPE block";
+			} else {
+				gpe_type = "GPE Block Device";
+			}
+
+			acpi_os_printf
+			    ("\nBlock %u - Info %p  DeviceNode %p [%s] - %s\n",
+			     block, gpe_block, gpe_block->node, buffer,
+			     gpe_type);
+
+			acpi_os_printf("    Registers:    %u (%u GPEs)\n",
+				       gpe_block->register_count,
+				       gpe_block->gpe_count);
+
+			acpi_os_printf
+			    ("    GPE range:    0x%X to 0x%X on interrupt %u\n",
+			     gpe_block->block_base_number,
+			     gpe_block->block_base_number +
+			     (gpe_block->gpe_count - 1),
+			     gpe_xrupt_info->interrupt_number);
+
+			acpi_os_printf
+			    ("    RegisterInfo: %p  Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+			     gpe_block->register_info,
+			     ACPI_FORMAT_UINT64(gpe_block->register_info->
+						status_address.address),
+			     ACPI_FORMAT_UINT64(gpe_block->register_info->
+						enable_address.address));
+
+			acpi_os_printf("  EventInfo:    %p\n",
+				       gpe_block->event_info);
+
+			/* Examine each GPE Register within the block */
+
+			for (i = 0; i < gpe_block->register_count; i++) {
+				gpe_register_info =
+				    &gpe_block->register_info[i];
+
+				acpi_os_printf("    Reg %u: (GPE %.2X-%.2X)  "
+					       "RunEnable %2.2X WakeEnable %2.2X"
+					       " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+					       i,
+					       gpe_register_info->
+					       base_gpe_number,
+					       gpe_register_info->
+					       base_gpe_number +
+					       (ACPI_GPE_REGISTER_WIDTH - 1),
+					       gpe_register_info->
+					       enable_for_run,
+					       gpe_register_info->
+					       enable_for_wake,
+					       ACPI_FORMAT_UINT64
+					       (gpe_register_info->
+						status_address.address),
+					       ACPI_FORMAT_UINT64
+					       (gpe_register_info->
+						enable_address.address));
+
+				/* Now look at the individual GPEs in this byte register */
+
+				for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+					gpe_index =
+					    (i * ACPI_GPE_REGISTER_WIDTH) + j;
+					gpe_event_info =
+					    &gpe_block->event_info[gpe_index];
+
+					if (ACPI_GPE_DISPATCH_TYPE
+					    (gpe_event_info->flags) ==
+					    ACPI_GPE_DISPATCH_NONE) {
+
+						/* This GPE is not used (no method or handler), ignore it */
+
+						continue;
+					}
+
+					acpi_os_printf
+					    ("        GPE %.2X: %p  RunRefs %2.2X Flags %2.2X (",
+					     gpe_block->block_base_number +
+					     gpe_index, gpe_event_info,
+					     gpe_event_info->runtime_count,
+					     gpe_event_info->flags);
+
+					/* Decode the flags byte */
+
+					if (gpe_event_info->
+					    flags & ACPI_GPE_LEVEL_TRIGGERED) {
+						acpi_os_printf("Level, ");
+					} else {
+						acpi_os_printf("Edge, ");
+					}
+
+					if (gpe_event_info->
+					    flags & ACPI_GPE_CAN_WAKE) {
+						acpi_os_printf("CanWake, ");
+					} else {
+						acpi_os_printf("RunOnly, ");
+					}
+
+					switch (ACPI_GPE_DISPATCH_TYPE
+						(gpe_event_info->flags)) {
+					case ACPI_GPE_DISPATCH_NONE:
+
+						acpi_os_printf("NotUsed");
+						break;
+
+					case ACPI_GPE_DISPATCH_METHOD:
+
+						acpi_os_printf("Method");
+						break;
+
+					case ACPI_GPE_DISPATCH_HANDLER:
+
+						acpi_os_printf("Handler");
+						break;
+
+					case ACPI_GPE_DISPATCH_NOTIFY:
+
+						count = 0;
+						notify =
+						    gpe_event_info->dispatch.
+						    notify_list;
+						while (notify) {
+							count++;
+							notify = notify->next;
+						}
+
+						acpi_os_printf
+						    ("Implicit Notify on %u devices",
+						     count);
+						break;
+
+					case ACPI_GPE_DISPATCH_RAW_HANDLER:
+
+						acpi_os_printf("RawHandler");
+						break;
+
+					default:
+
+						acpi_os_printf("UNKNOWN: %X",
+							       ACPI_GPE_DISPATCH_TYPE
+							       (gpe_event_info->
+								flags));
+						break;
+					}
+
+					acpi_os_printf(")\n");
+				}
+			}
+
+			block++;
+			gpe_block = gpe_block->next;
+		}
+
+		gpe_xrupt_info = gpe_xrupt_info->next;
+	}
+}
+#endif				/* !ACPI_REDUCED_HARDWARE */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_handlers
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the currently installed global handlers
+ *
+ ******************************************************************************/
+
+void acpi_db_display_handlers(void)
+{
+	union acpi_operand_object *obj_desc;
+	union acpi_operand_object *handler_obj;
+	acpi_adr_space_type space_id;
+	u32 i;
+
+	/* Operation region handlers */
+
+	acpi_os_printf("\nOperation Region Handlers at the namespace root:\n");
+
+	obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
+	if (obj_desc) {
+		for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_space_id_list); i++) {
+			space_id = acpi_gbl_space_id_list[i];
+			handler_obj = obj_desc->device.handler;
+
+			acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+				       acpi_ut_get_region_name((u8)space_id),
+				       space_id);
+
+			while (handler_obj) {
+				if (acpi_gbl_space_id_list[i] ==
+				    handler_obj->address_space.space_id) {
+					acpi_os_printf
+					    (ACPI_HANDLER_PRESENT_STRING,
+					     (handler_obj->address_space.
+					      handler_flags &
+					      ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
+					     ? "Default" : "User",
+					     handler_obj->address_space.
+					     handler);
+
+					goto found_handler;
+				}
+
+				handler_obj = handler_obj->address_space.next;
+			}
+
+			/* There is no handler for this space_id */
+
+			acpi_os_printf("None\n");
+
+found_handler:		;
+		}
+
+		/* Find all handlers for user-defined space_IDs */
+
+		handler_obj = obj_desc->device.handler;
+		while (handler_obj) {
+			if (handler_obj->address_space.space_id >=
+			    ACPI_USER_REGION_BEGIN) {
+				acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+					       "User-defined ID",
+					       handler_obj->address_space.
+					       space_id);
+				acpi_os_printf(ACPI_HANDLER_PRESENT_STRING,
+					       (handler_obj->address_space.
+						handler_flags &
+						ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
+					       ? "Default" : "User",
+					       handler_obj->address_space.
+					       handler);
+			}
+
+			handler_obj = handler_obj->address_space.next;
+		}
+	}
+#if (!ACPI_REDUCED_HARDWARE)
+
+	/* Fixed event handlers */
+
+	acpi_os_printf("\nFixed Event Handlers:\n");
+
+	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
+		acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+			       acpi_ut_get_event_name(i), i);
+		if (acpi_gbl_fixed_event_handlers[i].handler) {
+			acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
+				       acpi_gbl_fixed_event_handlers[i].
+				       handler);
+		} else {
+			acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+		}
+	}
+
+#endif				/* !ACPI_REDUCED_HARDWARE */
+
+	/* Miscellaneous global handlers */
+
+	acpi_os_printf("\nMiscellaneous Global Handlers:\n");
+
+	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_handler_list); i++) {
+		acpi_os_printf(ACPI_HANDLER_NAME_STRING,
+			       acpi_gbl_handler_list[i].name);
+
+		if (acpi_gbl_handler_list[i].handler) {
+			acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
+				       acpi_gbl_handler_list[i].handler);
+		} else {
+			acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+		}
+	}
+
+	/* Other handlers that are installed throughout the namespace */
+
+	acpi_os_printf("\nOperation Region Handlers for specific devices:\n");
+
+	(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX,
+				  acpi_db_display_non_root_handlers, NULL, NULL,
+				  NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_non_root_handlers
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display information about all handlers installed for a
+ *              device object.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_display_non_root_handlers(acpi_handle obj_handle,
+				  u32 nesting_level,
+				  void *context, void **return_value)
+{
+	struct acpi_namespace_node *node =
+	    ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
+	union acpi_operand_object *obj_desc;
+	union acpi_operand_object *handler_obj;
+	char *pathname;
+
+	obj_desc = acpi_ns_get_attached_object(node);
+	if (!obj_desc) {
+		return (AE_OK);
+	}
+
+	pathname = acpi_ns_get_external_pathname(node);
+	if (!pathname) {
+		return (AE_OK);
+	}
+
+	/* Display all handlers associated with this device */
+
+	handler_obj = obj_desc->device.handler;
+	while (handler_obj) {
+		acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+			       acpi_ut_get_region_name((u8)handler_obj->
+						       address_space.space_id),
+			       handler_obj->address_space.space_id);
+
+		acpi_os_printf(ACPI_HANDLER_PRESENT_STRING2,
+			       (handler_obj->address_space.handler_flags &
+				ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default"
+			       : "User", handler_obj->address_space.handler);
+
+		acpi_os_printf(" Device Name: %s (%p)\n", pathname, node);
+
+		handler_obj = handler_obj->address_space.next;
+	}
+
+	ACPI_FREE(pathname);
+	return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c
new file mode 100644
index 0000000..d713e2d
--- /dev/null
+++ b/drivers/acpi/acpica/dbexec.c
@@ -0,0 +1,764 @@
+/*******************************************************************************
+ *
+ * Module Name: dbexec - debugger control method execution
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbexec")
+
+static struct acpi_db_method_info acpi_gbl_db_method_info;
+
+/* Local prototypes */
+
+static acpi_status
+acpi_db_execute_method(struct acpi_db_method_info *info,
+		       struct acpi_buffer *return_obj);
+
+static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info);
+
+static u32 acpi_db_get_outstanding_allocations(void);
+
+static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context);
+
+static acpi_status
+acpi_db_execution_walk(acpi_handle obj_handle,
+		       u32 nesting_level, void *context, void **return_value);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_delete_objects
+ *
+ * PARAMETERS:  count               - Count of objects in the list
+ *              objects             - Array of ACPI_OBJECTs to be deleted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested
+ *              packages via recursion.
+ *
+ ******************************************************************************/
+
+void acpi_db_delete_objects(u32 count, union acpi_object *objects)
+{
+	u32 i;
+
+	for (i = 0; i < count; i++) {
+		switch (objects[i].type) {
+		case ACPI_TYPE_BUFFER:
+
+			ACPI_FREE(objects[i].buffer.pointer);
+			break;
+
+		case ACPI_TYPE_PACKAGE:
+
+			/* Recursive call to delete package elements */
+
+			acpi_db_delete_objects(objects[i].package.count,
+					       objects[i].package.elements);
+
+			/* Free the elements array */
+
+			ACPI_FREE(objects[i].package.elements);
+			break;
+
+		default:
+
+			break;
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_method
+ *
+ * PARAMETERS:  info            - Valid info segment
+ *              return_obj      - Where to put return object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_execute_method(struct acpi_db_method_info *info,
+		       struct acpi_buffer *return_obj)
+{
+	acpi_status status;
+	struct acpi_object_list param_objects;
+	union acpi_object params[ACPI_DEBUGGER_MAX_ARGS + 1];
+	u32 i;
+
+	ACPI_FUNCTION_TRACE(db_execute_method);
+
+	if (acpi_gbl_db_output_to_file && !acpi_dbg_level) {
+		acpi_os_printf("Warning: debug output is not enabled!\n");
+	}
+
+	param_objects.count = 0;
+	param_objects.pointer = NULL;
+
+	/* Pass through any command-line arguments */
+
+	if (info->args && info->args[0]) {
+
+		/* Get arguments passed on the command line */
+
+		for (i = 0; (info->args[i] && *(info->args[i])); i++) {
+
+			/* Convert input string (token) to an actual union acpi_object */
+
+			status = acpi_db_convert_to_object(info->types[i],
+							   info->args[i],
+							   &params[i]);
+			if (ACPI_FAILURE(status)) {
+				ACPI_EXCEPTION((AE_INFO, status,
+						"While parsing method arguments"));
+				goto cleanup;
+			}
+		}
+
+		param_objects.count = i;
+		param_objects.pointer = params;
+	}
+
+	/* Prepare for a return object of arbitrary size */
+
+	return_obj->pointer = acpi_gbl_db_buffer;
+	return_obj->length = ACPI_DEBUG_BUFFER_SIZE;
+
+	/* Do the actual method execution */
+
+	acpi_gbl_method_executing = TRUE;
+	status = acpi_evaluate_object(NULL, info->pathname,
+				      &param_objects, return_obj);
+
+	acpi_gbl_cm_single_step = FALSE;
+	acpi_gbl_method_executing = FALSE;
+
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status,
+				"while executing %s from debugger",
+				info->pathname));
+
+		if (status == AE_BUFFER_OVERFLOW) {
+			ACPI_ERROR((AE_INFO,
+				    "Possible overflow of internal debugger "
+				    "buffer (size 0x%X needed 0x%X)",
+				    ACPI_DEBUG_BUFFER_SIZE,
+				    (u32)return_obj->length));
+		}
+	}
+
+cleanup:
+	acpi_db_delete_objects(param_objects.count, params);
+	return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_setup
+ *
+ * PARAMETERS:  info            - Valid method info
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Setup info segment prior to method execution
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_NAME(db_execute_setup);
+
+	/* Catenate the current scope to the supplied name */
+
+	info->pathname[0] = 0;
+	if ((info->name[0] != '\\') && (info->name[0] != '/')) {
+		if (acpi_ut_safe_strcat(info->pathname, sizeof(info->pathname),
+					acpi_gbl_db_scope_buf)) {
+			status = AE_BUFFER_OVERFLOW;
+			goto error_exit;
+		}
+	}
+
+	if (acpi_ut_safe_strcat(info->pathname, sizeof(info->pathname),
+				info->name)) {
+		status = AE_BUFFER_OVERFLOW;
+		goto error_exit;
+	}
+
+	acpi_db_prep_namestring(info->pathname);
+
+	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+	acpi_os_printf("Evaluating %s\n", info->pathname);
+
+	if (info->flags & EX_SINGLE_STEP) {
+		acpi_gbl_cm_single_step = TRUE;
+		acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+	}
+
+	else {
+		/* No single step, allow redirection to a file */
+
+		acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	}
+
+	return (AE_OK);
+
+error_exit:
+
+	ACPI_EXCEPTION((AE_INFO, status, "During setup for method execution"));
+	return (status);
+}
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+u32 acpi_db_get_cache_info(struct acpi_memory_list *cache)
+{
+
+	return (cache->total_allocated - cache->total_freed -
+		cache->current_depth);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_outstanding_allocations
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Current global allocation count minus cache entries
+ *
+ * DESCRIPTION: Determine the current number of "outstanding" allocations --
+ *              those allocations that have not been freed and also are not
+ *              in one of the various object caches.
+ *
+ ******************************************************************************/
+
+static u32 acpi_db_get_outstanding_allocations(void)
+{
+	u32 outstanding = 0;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+	outstanding += acpi_db_get_cache_info(acpi_gbl_state_cache);
+	outstanding += acpi_db_get_cache_info(acpi_gbl_ps_node_cache);
+	outstanding += acpi_db_get_cache_info(acpi_gbl_ps_node_ext_cache);
+	outstanding += acpi_db_get_cache_info(acpi_gbl_operand_cache);
+#endif
+
+	return (outstanding);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execution_walk
+ *
+ * PARAMETERS:  WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ *              scope.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_execution_walk(acpi_handle obj_handle,
+		       u32 nesting_level, void *context, void **return_value)
+{
+	union acpi_operand_object *obj_desc;
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+	struct acpi_buffer return_obj;
+	acpi_status status;
+
+	obj_desc = acpi_ns_get_attached_object(node);
+	if (obj_desc->method.param_count) {
+		return (AE_OK);
+	}
+
+	return_obj.pointer = NULL;
+	return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+	acpi_ns_print_node_pathname(node, "Evaluating");
+
+	/* Do the actual method execution */
+
+	acpi_os_printf("\n");
+	acpi_gbl_method_executing = TRUE;
+
+	status = acpi_evaluate_object(node, NULL, NULL, &return_obj);
+
+	acpi_os_printf("Evaluation of [%4.4s] returned %s\n",
+		       acpi_ut_get_node_name(node),
+		       acpi_format_exception(status));
+
+	acpi_gbl_method_executing = FALSE;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute
+ *
+ * PARAMETERS:  name                - Name of method to execute
+ *              args                - Parameters to the method
+ *              Types               -
+ *              flags               - single step/no single step
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ *              scope.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_execute(char *name, char **args, acpi_object_type * types, u32 flags)
+{
+	acpi_status status;
+	struct acpi_buffer return_obj;
+	char *name_string;
+
+#ifdef ACPI_DEBUG_OUTPUT
+	u32 previous_allocations;
+	u32 allocations;
+#endif
+
+	/*
+	 * Allow one execution to be performed by debugger or single step
+	 * execution will be dead locked by the interpreter mutexes.
+	 */
+	if (acpi_gbl_method_executing) {
+		acpi_os_printf("Only one debugger execution is allowed.\n");
+		return;
+	}
+#ifdef ACPI_DEBUG_OUTPUT
+	/* Memory allocation tracking */
+
+	previous_allocations = acpi_db_get_outstanding_allocations();
+#endif
+
+	if (*name == '*') {
+		(void)acpi_walk_namespace(ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
+					  ACPI_UINT32_MAX,
+					  acpi_db_execution_walk, NULL, NULL,
+					  NULL);
+		return;
+	} else {
+		name_string = ACPI_ALLOCATE(strlen(name) + 1);
+		if (!name_string) {
+			return;
+		}
+
+		memset(&acpi_gbl_db_method_info, 0,
+		       sizeof(struct acpi_db_method_info));
+
+		strcpy(name_string, name);
+		acpi_ut_strupr(name_string);
+		acpi_gbl_db_method_info.name = name_string;
+		acpi_gbl_db_method_info.args = args;
+		acpi_gbl_db_method_info.types = types;
+		acpi_gbl_db_method_info.flags = flags;
+
+		return_obj.pointer = NULL;
+		return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+		status = acpi_db_execute_setup(&acpi_gbl_db_method_info);
+		if (ACPI_FAILURE(status)) {
+			ACPI_FREE(name_string);
+			return;
+		}
+
+		/* Get the NS node, determines existence also */
+
+		status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname,
+					 &acpi_gbl_db_method_info.method);
+		if (ACPI_SUCCESS(status)) {
+			status =
+			    acpi_db_execute_method(&acpi_gbl_db_method_info,
+						   &return_obj);
+		}
+		ACPI_FREE(name_string);
+	}
+
+	/*
+	 * Allow any handlers in separate threads to complete.
+	 * (Such as Notify handlers invoked from AML executed above).
+	 */
+	acpi_os_sleep((u64)10);
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+	/* Memory allocation tracking */
+
+	allocations =
+	    acpi_db_get_outstanding_allocations() - previous_allocations;
+
+	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+
+	if (allocations > 0) {
+		acpi_os_printf
+		    ("0x%X Outstanding allocations after evaluation of %s\n",
+		     allocations, acpi_gbl_db_method_info.pathname);
+	}
+#endif
+
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Evaluation of %s failed with status %s\n",
+			       acpi_gbl_db_method_info.pathname,
+			       acpi_format_exception(status));
+	} else {
+		/* Display a return object, if any */
+
+		if (return_obj.length) {
+			acpi_os_printf("Evaluation of %s returned object %p, "
+				       "external buffer length %X\n",
+				       acpi_gbl_db_method_info.pathname,
+				       return_obj.pointer,
+				       (u32)return_obj.length);
+
+			acpi_db_dump_external_object(return_obj.pointer, 1);
+
+			/* Dump a _PLD buffer if present */
+
+			if (ACPI_COMPARE_NAME
+			    ((ACPI_CAST_PTR
+			      (struct acpi_namespace_node,
+			       acpi_gbl_db_method_info.method)->name.ascii),
+			     METHOD_NAME__PLD)) {
+				acpi_db_dump_pld_buffer(return_obj.pointer);
+			}
+		} else {
+			acpi_os_printf
+			    ("No object was returned from evaluation of %s\n",
+			     acpi_gbl_db_method_info.pathname);
+		}
+	}
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_method_thread
+ *
+ * PARAMETERS:  context             - Execution info segment
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context)
+{
+	acpi_status status;
+	struct acpi_db_method_info *info = context;
+	struct acpi_db_method_info local_info;
+	u32 i;
+	u8 allow;
+	struct acpi_buffer return_obj;
+
+	/*
+	 * acpi_gbl_db_method_info.Arguments will be passed as method arguments.
+	 * Prevent acpi_gbl_db_method_info from being modified by multiple threads
+	 * concurrently.
+	 *
+	 * Note: The arguments we are passing are used by the ASL test suite
+	 * (aslts). Do not change them without updating the tests.
+	 */
+	(void)acpi_os_wait_semaphore(info->info_gate, 1, ACPI_WAIT_FOREVER);
+
+	if (info->init_args) {
+		acpi_db_uint32_to_hex_string(info->num_created,
+					     info->index_of_thread_str);
+		acpi_db_uint32_to_hex_string((u32)acpi_os_get_thread_id(),
+					     info->id_of_thread_str);
+	}
+
+	if (info->threads && (info->num_created < info->num_threads)) {
+		info->threads[info->num_created++] = acpi_os_get_thread_id();
+	}
+
+	local_info = *info;
+	local_info.args = local_info.arguments;
+	local_info.arguments[0] = local_info.num_threads_str;
+	local_info.arguments[1] = local_info.id_of_thread_str;
+	local_info.arguments[2] = local_info.index_of_thread_str;
+	local_info.arguments[3] = NULL;
+
+	local_info.types = local_info.arg_types;
+
+	(void)acpi_os_signal_semaphore(info->info_gate, 1);
+
+	for (i = 0; i < info->num_loops; i++) {
+		status = acpi_db_execute_method(&local_info, &return_obj);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf
+			    ("%s During evaluation of %s at iteration %X\n",
+			     acpi_format_exception(status), info->pathname, i);
+			if (status == AE_ABORT_METHOD) {
+				break;
+			}
+		}
+#if 0
+		if ((i % 100) == 0) {
+			acpi_os_printf("%u loops, Thread 0x%x\n",
+				       i, acpi_os_get_thread_id());
+		}
+
+		if (return_obj.length) {
+			acpi_os_printf
+			    ("Evaluation of %s returned object %p Buflen %X\n",
+			     info->pathname, return_obj.pointer,
+			     (u32)return_obj.length);
+			acpi_db_dump_external_object(return_obj.pointer, 1);
+		}
+#endif
+	}
+
+	/* Signal our completion */
+
+	allow = 0;
+	(void)acpi_os_wait_semaphore(info->thread_complete_gate,
+				     1, ACPI_WAIT_FOREVER);
+	info->num_completed++;
+
+	if (info->num_completed == info->num_threads) {
+
+		/* Do signal for main thread once only */
+		allow = 1;
+	}
+
+	(void)acpi_os_signal_semaphore(info->thread_complete_gate, 1);
+
+	if (allow) {
+		status = acpi_os_signal_semaphore(info->main_thread_gate, 1);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf
+			    ("Could not signal debugger thread sync semaphore, %s\n",
+			     acpi_format_exception(status));
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_create_execution_threads
+ *
+ * PARAMETERS:  num_threads_arg         - Number of threads to create
+ *              num_loops_arg           - Loop count for the thread(s)
+ *              method_name_arg         - Control method to execute
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create threads to execute method(s)
+ *
+ ******************************************************************************/
+
+void
+acpi_db_create_execution_threads(char *num_threads_arg,
+				 char *num_loops_arg, char *method_name_arg)
+{
+	acpi_status status;
+	u32 num_threads;
+	u32 num_loops;
+	u32 i;
+	u32 size;
+	acpi_mutex main_thread_gate;
+	acpi_mutex thread_complete_gate;
+	acpi_mutex info_gate;
+
+	/* Get the arguments */
+
+	num_threads = strtoul(num_threads_arg, NULL, 0);
+	num_loops = strtoul(num_loops_arg, NULL, 0);
+
+	if (!num_threads || !num_loops) {
+		acpi_os_printf("Bad argument: Threads %X, Loops %X\n",
+			       num_threads, num_loops);
+		return;
+	}
+
+	/*
+	 * Create the semaphore for synchronization of
+	 * the created threads with the main thread.
+	 */
+	status = acpi_os_create_semaphore(1, 0, &main_thread_gate);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not create semaphore for "
+			       "synchronization with the main thread, %s\n",
+			       acpi_format_exception(status));
+		return;
+	}
+
+	/*
+	 * Create the semaphore for synchronization
+	 * between the created threads.
+	 */
+	status = acpi_os_create_semaphore(1, 1, &thread_complete_gate);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not create semaphore for "
+			       "synchronization between the created threads, %s\n",
+			       acpi_format_exception(status));
+
+		(void)acpi_os_delete_semaphore(main_thread_gate);
+		return;
+	}
+
+	status = acpi_os_create_semaphore(1, 1, &info_gate);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not create semaphore for "
+			       "synchronization of AcpiGbl_DbMethodInfo, %s\n",
+			       acpi_format_exception(status));
+
+		(void)acpi_os_delete_semaphore(thread_complete_gate);
+		(void)acpi_os_delete_semaphore(main_thread_gate);
+		return;
+	}
+
+	memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info));
+
+	/* Array to store IDs of threads */
+
+	acpi_gbl_db_method_info.num_threads = num_threads;
+	size = sizeof(acpi_thread_id) * acpi_gbl_db_method_info.num_threads;
+
+	acpi_gbl_db_method_info.threads = acpi_os_allocate(size);
+	if (acpi_gbl_db_method_info.threads == NULL) {
+		acpi_os_printf("No memory for thread IDs array\n");
+		(void)acpi_os_delete_semaphore(main_thread_gate);
+		(void)acpi_os_delete_semaphore(thread_complete_gate);
+		(void)acpi_os_delete_semaphore(info_gate);
+		return;
+	}
+	memset(acpi_gbl_db_method_info.threads, 0, size);
+
+	/* Setup the context to be passed to each thread */
+
+	acpi_gbl_db_method_info.name = method_name_arg;
+	acpi_gbl_db_method_info.flags = 0;
+	acpi_gbl_db_method_info.num_loops = num_loops;
+	acpi_gbl_db_method_info.main_thread_gate = main_thread_gate;
+	acpi_gbl_db_method_info.thread_complete_gate = thread_complete_gate;
+	acpi_gbl_db_method_info.info_gate = info_gate;
+
+	/* Init arguments to be passed to method */
+
+	acpi_gbl_db_method_info.init_args = 1;
+	acpi_gbl_db_method_info.args = acpi_gbl_db_method_info.arguments;
+	acpi_gbl_db_method_info.arguments[0] =
+	    acpi_gbl_db_method_info.num_threads_str;
+	acpi_gbl_db_method_info.arguments[1] =
+	    acpi_gbl_db_method_info.id_of_thread_str;
+	acpi_gbl_db_method_info.arguments[2] =
+	    acpi_gbl_db_method_info.index_of_thread_str;
+	acpi_gbl_db_method_info.arguments[3] = NULL;
+
+	acpi_gbl_db_method_info.types = acpi_gbl_db_method_info.arg_types;
+	acpi_gbl_db_method_info.arg_types[0] = ACPI_TYPE_INTEGER;
+	acpi_gbl_db_method_info.arg_types[1] = ACPI_TYPE_INTEGER;
+	acpi_gbl_db_method_info.arg_types[2] = ACPI_TYPE_INTEGER;
+
+	acpi_db_uint32_to_hex_string(num_threads,
+				     acpi_gbl_db_method_info.num_threads_str);
+
+	status = acpi_db_execute_setup(&acpi_gbl_db_method_info);
+	if (ACPI_FAILURE(status)) {
+		goto cleanup_and_exit;
+	}
+
+	/* Get the NS node, determines existence also */
+
+	status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname,
+				 &acpi_gbl_db_method_info.method);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("%s Could not get handle for %s\n",
+			       acpi_format_exception(status),
+			       acpi_gbl_db_method_info.pathname);
+		goto cleanup_and_exit;
+	}
+
+	/* Create the threads */
+
+	acpi_os_printf("Creating %X threads to execute %X times each\n",
+		       num_threads, num_loops);
+
+	for (i = 0; i < (num_threads); i++) {
+		status =
+		    acpi_os_execute(OSL_DEBUGGER_EXEC_THREAD,
+				    acpi_db_method_thread,
+				    &acpi_gbl_db_method_info);
+		if (ACPI_FAILURE(status)) {
+			break;
+		}
+	}
+
+	/* Wait for all threads to complete */
+
+	(void)acpi_os_wait_semaphore(main_thread_gate, 1, ACPI_WAIT_FOREVER);
+
+	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+	acpi_os_printf("All threads (%X) have completed\n", num_threads);
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+
+cleanup_and_exit:
+
+	/* Cleanup and exit */
+
+	(void)acpi_os_delete_semaphore(main_thread_gate);
+	(void)acpi_os_delete_semaphore(thread_complete_gate);
+	(void)acpi_os_delete_semaphore(info_gate);
+
+	acpi_os_free(acpi_gbl_db_method_info.threads);
+	acpi_gbl_db_method_info.threads = NULL;
+}
diff --git a/drivers/acpi/acpica/dbfileio.c b/drivers/acpi/acpica/dbfileio.c
new file mode 100644
index 0000000..d0e6b20
--- /dev/null
+++ b/drivers/acpi/acpica/dbfileio.c
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ *
+ * Module Name: dbfileio - Debugger file I/O commands. These can't usually
+ *              be used when running the debugger in Ring 0 (Kernel mode)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdebug.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbfileio")
+
+#ifdef ACPI_DEBUGGER
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_close_debug_file
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: If open, close the current debug output file
+ *
+ ******************************************************************************/
+void acpi_db_close_debug_file(void)
+{
+
+#ifdef ACPI_APPLICATION
+
+	if (acpi_gbl_debug_file) {
+		fclose(acpi_gbl_debug_file);
+		acpi_gbl_debug_file = NULL;
+		acpi_gbl_db_output_to_file = FALSE;
+		acpi_os_printf("Debug output file %s closed\n",
+			       acpi_gbl_db_debug_filename);
+	}
+#endif
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_open_debug_file
+ *
+ * PARAMETERS:  name                - Filename to open
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Open a file where debug output will be directed.
+ *
+ ******************************************************************************/
+
+void acpi_db_open_debug_file(char *name)
+{
+
+#ifdef ACPI_APPLICATION
+
+	acpi_db_close_debug_file();
+	acpi_gbl_debug_file = fopen(name, "w+");
+	if (!acpi_gbl_debug_file) {
+		acpi_os_printf("Could not open debug file %s\n", name);
+		return;
+	}
+
+	acpi_os_printf("Debug output file %s opened\n", name);
+	strncpy(acpi_gbl_db_debug_filename, name,
+		sizeof(acpi_gbl_db_debug_filename));
+	acpi_gbl_db_output_to_file = TRUE;
+
+#endif
+}
+#endif
+
+#ifdef ACPI_APPLICATION
+#include "acapps.h"
+
+/*******************************************************************************
+ *
+ * FUNCTION:    ae_local_load_table
+ *
+ * PARAMETERS:  table           - pointer to a buffer containing the entire
+ *                                table to be loaded
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to load a table from the caller's
+ *              buffer. The buffer must contain an entire ACPI Table including
+ *              a valid header. The header fields will be verified, and if it
+ *              is determined that the table is invalid, the call will fail.
+ *
+ ******************************************************************************/
+
+static acpi_status ae_local_load_table(struct acpi_table_header *table)
+{
+	acpi_status status = AE_OK;
+
+	ACPI_FUNCTION_TRACE(ae_local_load_table);
+
+#if 0
+/*    struct acpi_table_desc          table_info; */
+
+	if (!table) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	table_info.pointer = table;
+	status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/* Install the new table into the local data structures */
+
+	status = acpi_tb_init_table_descriptor(&table_info);
+	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 */
+
+		acpi_tb_delete_single_table(&table_info);
+		return_ACPI_STATUS(status);
+	}
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
+	status =
+	    acpi_ns_load_table(table_info.installed_desc, acpi_gbl_root_node);
+	if (ACPI_FAILURE(status)) {
+
+		/* Uninstall table and free the buffer */
+
+		acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_DSDT);
+		return_ACPI_STATUS(status);
+	}
+#endif
+#endif
+
+	return_ACPI_STATUS(status);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_table_from_file
+ *
+ * PARAMETERS:  filename        - File where table is located
+ *              return_table    - Where a pointer to the table is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load an ACPI table from a file
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_get_table_from_file(char *filename,
+			    struct acpi_table_header **return_table,
+			    u8 must_be_aml_file)
+{
+#ifdef ACPI_APPLICATION
+	acpi_status status;
+	struct acpi_table_header *table;
+	u8 is_aml_table = TRUE;
+
+	status = acpi_ut_read_table_from_file(filename, &table);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	if (must_be_aml_file) {
+		is_aml_table = acpi_ut_is_aml_table(table);
+		if (!is_aml_table) {
+			ACPI_EXCEPTION((AE_INFO, AE_OK,
+					"Input for -e is not an AML table: "
+					"\"%4.4s\" (must be DSDT/SSDT)",
+					table->signature));
+			return (AE_TYPE);
+		}
+	}
+
+	if (is_aml_table) {
+
+		/* Attempt to recognize and install the table */
+
+		status = ae_local_load_table(table);
+		if (ACPI_FAILURE(status)) {
+			if (status == AE_ALREADY_EXISTS) {
+				acpi_os_printf
+				    ("Table %4.4s is already installed\n",
+				     table->signature);
+			} else {
+				acpi_os_printf("Could not install table, %s\n",
+					       acpi_format_exception(status));
+			}
+
+			return (status);
+		}
+
+		acpi_tb_print_table_header(0, table);
+
+		fprintf(stderr,
+			"Acpi table [%4.4s] successfully installed and loaded\n",
+			table->signature);
+	}
+
+	acpi_gbl_acpi_hardware_present = FALSE;
+	if (return_table) {
+		*return_table = table;
+	}
+
+#endif				/* ACPI_APPLICATION */
+	return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbhistry.c b/drivers/acpi/acpica/dbhistry.c
new file mode 100644
index 0000000..9c66a9e
--- /dev/null
+++ b/drivers/acpi/acpica/dbhistry.c
@@ -0,0 +1,239 @@
+/******************************************************************************
+ *
+ * Module Name: dbhistry - debugger HISTORY command
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbhistry")
+
+#define HI_NO_HISTORY       0
+#define HI_RECORD_HISTORY   1
+#define HISTORY_SIZE        40
+typedef struct history_info {
+	char *command;
+	u32 cmd_num;
+
+} HISTORY_INFO;
+
+static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE];
+static u16 acpi_gbl_lo_history = 0;
+static u16 acpi_gbl_num_history = 0;
+static u16 acpi_gbl_next_history_index = 0;
+u32 acpi_gbl_next_cmd_num = 1;
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_add_to_history
+ *
+ * PARAMETERS:  command_line    - Command to add
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add a command line to the history buffer.
+ *
+ ******************************************************************************/
+
+void acpi_db_add_to_history(char *command_line)
+{
+	u16 cmd_len;
+	u16 buffer_len;
+
+	/* Put command into the next available slot */
+
+	cmd_len = (u16)strlen(command_line);
+	if (!cmd_len) {
+		return;
+	}
+
+	if (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command !=
+	    NULL) {
+		buffer_len =
+		    (u16)
+		    strlen(acpi_gbl_history_buffer[acpi_gbl_next_history_index].
+			   command);
+
+		if (cmd_len > buffer_len) {
+			acpi_os_free(acpi_gbl_history_buffer
+				     [acpi_gbl_next_history_index].command);
+			acpi_gbl_history_buffer[acpi_gbl_next_history_index].
+			    command = acpi_os_allocate(cmd_len + 1);
+		}
+	} else {
+		acpi_gbl_history_buffer[acpi_gbl_next_history_index].command =
+		    acpi_os_allocate(cmd_len + 1);
+	}
+
+	strcpy(acpi_gbl_history_buffer[acpi_gbl_next_history_index].command,
+	       command_line);
+
+	acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num =
+	    acpi_gbl_next_cmd_num;
+
+	/* Adjust indexes */
+
+	if ((acpi_gbl_num_history == HISTORY_SIZE) &&
+	    (acpi_gbl_next_history_index == acpi_gbl_lo_history)) {
+		acpi_gbl_lo_history++;
+		if (acpi_gbl_lo_history >= HISTORY_SIZE) {
+			acpi_gbl_lo_history = 0;
+		}
+	}
+
+	acpi_gbl_next_history_index++;
+	if (acpi_gbl_next_history_index >= HISTORY_SIZE) {
+		acpi_gbl_next_history_index = 0;
+	}
+
+	acpi_gbl_next_cmd_num++;
+	if (acpi_gbl_num_history < HISTORY_SIZE) {
+		acpi_gbl_num_history++;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_history
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the contents of the history buffer
+ *
+ ******************************************************************************/
+
+void acpi_db_display_history(void)
+{
+	u32 i;
+	u16 history_index;
+
+	history_index = acpi_gbl_lo_history;
+
+	/* Dump entire history buffer */
+
+	for (i = 0; i < acpi_gbl_num_history; i++) {
+		if (acpi_gbl_history_buffer[history_index].command) {
+			acpi_os_printf("%3ld %s\n",
+				       acpi_gbl_history_buffer[history_index].
+				       cmd_num,
+				       acpi_gbl_history_buffer[history_index].
+				       command);
+		}
+
+		history_index++;
+		if (history_index >= HISTORY_SIZE) {
+			history_index = 0;
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_from_history
+ *
+ * PARAMETERS:  command_num_arg         - String containing the number of the
+ *                                        command to be retrieved
+ *
+ * RETURN:      Pointer to the retrieved command. Null on error.
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+char *acpi_db_get_from_history(char *command_num_arg)
+{
+	u32 cmd_num;
+
+	if (command_num_arg == NULL) {
+		cmd_num = acpi_gbl_next_cmd_num - 1;
+	}
+
+	else {
+		cmd_num = strtoul(command_num_arg, NULL, 0);
+	}
+
+	return (acpi_db_get_history_by_index(cmd_num));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_history_by_index
+ *
+ * PARAMETERS:  cmd_num             - Index of the desired history entry.
+ *                                    Values are 0...(acpi_gbl_next_cmd_num - 1)
+ *
+ * RETURN:      Pointer to the retrieved command. Null on error.
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+char *acpi_db_get_history_by_index(u32 cmd_num)
+{
+	u32 i;
+	u16 history_index;
+
+	/* Search history buffer */
+
+	history_index = acpi_gbl_lo_history;
+	for (i = 0; i < acpi_gbl_num_history; i++) {
+		if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) {
+
+			/* Found the command, return it */
+
+			return (acpi_gbl_history_buffer[history_index].command);
+		}
+
+		/* History buffer is circular */
+
+		history_index++;
+		if (history_index >= HISTORY_SIZE) {
+			history_index = 0;
+		}
+	}
+
+	acpi_os_printf("Invalid history number: %u\n", history_index);
+	return (NULL);
+}
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c
new file mode 100644
index 0000000..0480254
--- /dev/null
+++ b/drivers/acpi/acpica/dbinput.c
@@ -0,0 +1,1267 @@
+/*******************************************************************************
+ *
+ * Module Name: dbinput - user front-end to the AML debugger
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbinput")
+
+/* Local prototypes */
+static u32 acpi_db_get_line(char *input_buffer);
+
+static u32 acpi_db_match_command(char *user_command);
+
+static void acpi_db_single_thread(void);
+
+static void acpi_db_display_command_info(char *command, u8 display_all);
+
+static void acpi_db_display_help(char *command);
+
+static u8
+acpi_db_match_command_help(char *command,
+			   const struct acpi_db_command_help *help);
+
+/*
+ * Top-level debugger commands.
+ *
+ * This list of commands must match the string table below it
+ */
+enum acpi_ex_debugger_commands {
+	CMD_NOT_FOUND = 0,
+	CMD_NULL,
+	CMD_ALLOCATIONS,
+	CMD_ARGS,
+	CMD_ARGUMENTS,
+	CMD_BREAKPOINT,
+	CMD_BUSINFO,
+	CMD_CALL,
+	CMD_DEBUG,
+	CMD_DISASSEMBLE,
+	CMD_DISASM,
+	CMD_DUMP,
+	CMD_EVALUATE,
+	CMD_EXECUTE,
+	CMD_EXIT,
+	CMD_FIND,
+	CMD_GO,
+	CMD_HANDLERS,
+	CMD_HELP,
+	CMD_HELP2,
+	CMD_HISTORY,
+	CMD_HISTORY_EXE,
+	CMD_HISTORY_LAST,
+	CMD_INFORMATION,
+	CMD_INTEGRITY,
+	CMD_INTO,
+	CMD_LEVEL,
+	CMD_LIST,
+	CMD_LOCALS,
+	CMD_LOCKS,
+	CMD_METHODS,
+	CMD_NAMESPACE,
+	CMD_NOTIFY,
+	CMD_OBJECTS,
+	CMD_OSI,
+	CMD_OWNER,
+	CMD_PATHS,
+	CMD_PREDEFINED,
+	CMD_PREFIX,
+	CMD_QUIT,
+	CMD_REFERENCES,
+	CMD_RESOURCES,
+	CMD_RESULTS,
+	CMD_SET,
+	CMD_STATS,
+	CMD_STOP,
+	CMD_TABLES,
+	CMD_TEMPLATE,
+	CMD_TRACE,
+	CMD_TREE,
+	CMD_TYPE,
+#ifdef ACPI_APPLICATION
+	CMD_ENABLEACPI,
+	CMD_EVENT,
+	CMD_GPE,
+	CMD_GPES,
+	CMD_SCI,
+	CMD_SLEEP,
+
+	CMD_CLOSE,
+	CMD_LOAD,
+	CMD_OPEN,
+	CMD_UNLOAD,
+
+	CMD_TERMINATE,
+	CMD_THREADS,
+
+	CMD_TEST,
+#endif
+};
+
+#define CMD_FIRST_VALID     2
+
+/* Second parameter is the required argument count */
+
+static const struct acpi_db_command_info acpi_gbl_db_commands[] = {
+	{"<NOT FOUND>", 0},
+	{"<NULL>", 0},
+	{"ALLOCATIONS", 0},
+	{"ARGS", 0},
+	{"ARGUMENTS", 0},
+	{"BREAKPOINT", 1},
+	{"BUSINFO", 0},
+	{"CALL", 0},
+	{"DEBUG", 1},
+	{"DISASSEMBLE", 1},
+	{"DISASM", 1},
+	{"DUMP", 1},
+	{"EVALUATE", 1},
+	{"EXECUTE", 1},
+	{"EXIT", 0},
+	{"FIND", 1},
+	{"GO", 0},
+	{"HANDLERS", 0},
+	{"HELP", 0},
+	{"?", 0},
+	{"HISTORY", 0},
+	{"!", 1},
+	{"!!", 0},
+	{"INFORMATION", 0},
+	{"INTEGRITY", 0},
+	{"INTO", 0},
+	{"LEVEL", 0},
+	{"LIST", 0},
+	{"LOCALS", 0},
+	{"LOCKS", 0},
+	{"METHODS", 0},
+	{"NAMESPACE", 0},
+	{"NOTIFY", 2},
+	{"OBJECTS", 0},
+	{"OSI", 0},
+	{"OWNER", 1},
+	{"PATHS", 0},
+	{"PREDEFINED", 0},
+	{"PREFIX", 0},
+	{"QUIT", 0},
+	{"REFERENCES", 1},
+	{"RESOURCES", 0},
+	{"RESULTS", 0},
+	{"SET", 3},
+	{"STATS", 1},
+	{"STOP", 0},
+	{"TABLES", 0},
+	{"TEMPLATE", 1},
+	{"TRACE", 1},
+	{"TREE", 0},
+	{"TYPE", 1},
+#ifdef ACPI_APPLICATION
+	{"ENABLEACPI", 0},
+	{"EVENT", 1},
+	{"GPE", 1},
+	{"GPES", 0},
+	{"SCI", 0},
+	{"SLEEP", 0},
+
+	{"CLOSE", 0},
+	{"LOAD", 1},
+	{"OPEN", 1},
+	{"UNLOAD", 1},
+
+	{"TERMINATE", 0},
+	{"THREADS", 3},
+
+	{"TEST", 1},
+#endif
+	{NULL, 0}
+};
+
+/*
+ * Help for all debugger commands. First argument is the number of lines
+ * of help to output for the command.
+ */
+static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
+	{0, "\nGeneral-Purpose Commands:", "\n"},
+	{1, "  Allocations", "Display list of current memory allocations\n"},
+	{2, "  Dump <Address>|<Namepath>", "\n"},
+	{0, "       [Byte|Word|Dword|Qword]",
+	 "Display ACPI objects or memory\n"},
+	{1, "  Handlers", "Info about global handlers\n"},
+	{1, "  Help [Command]", "This help screen or individual command\n"},
+	{1, "  History", "Display command history buffer\n"},
+	{1, "  Level <DebugLevel>] [console]",
+	 "Get/Set debug level for file or console\n"},
+	{1, "  Locks", "Current status of internal mutexes\n"},
+	{1, "  Osi [Install|Remove <name>]",
+	 "Display or modify global _OSI list\n"},
+	{1, "  Quit or Exit", "Exit this command\n"},
+	{8, "  Stats <SubCommand>",
+	 "Display namespace and memory statistics\n"},
+	{1, "     Allocations", "Display list of current memory allocations\n"},
+	{1, "     Memory", "Dump internal memory lists\n"},
+	{1, "     Misc", "Namespace search and mutex stats\n"},
+	{1, "     Objects", "Summary of namespace objects\n"},
+	{1, "     Sizes", "Sizes for each of the internal objects\n"},
+	{1, "     Stack", "Display CPU stack usage\n"},
+	{1, "     Tables", "Info about current ACPI table(s)\n"},
+	{1, "  Tables", "Display info about loaded ACPI tables\n"},
+	{1, "  ! <CommandNumber>", "Execute command from history buffer\n"},
+	{1, "  !!", "Execute last command again\n"},
+
+	{0, "\nNamespace Access Commands:", "\n"},
+	{1, "  Businfo", "Display system bus info\n"},
+	{1, "  Disassemble <Method>", "Disassemble a control method\n"},
+	{1, "  Find <AcpiName> (? is wildcard)",
+	 "Find ACPI name(s) with wildcards\n"},
+	{1, "  Integrity", "Validate namespace integrity\n"},
+	{1, "  Methods", "Display list of loaded control methods\n"},
+	{1, "  Namespace [Object] [Depth]",
+	 "Display loaded namespace tree/subtree\n"},
+	{1, "  Notify <Object> <Value>", "Send a notification on Object\n"},
+	{1, "  Objects [ObjectType]",
+	 "Display summary of all objects or just given type\n"},
+	{1, "  Owner <OwnerId> [Depth]",
+	 "Display loaded namespace by object owner\n"},
+	{1, "  Paths", "Display full pathnames of namespace objects\n"},
+	{1, "  Predefined", "Check all predefined names\n"},
+	{1, "  Prefix [<Namepath>]", "Set or Get current execution prefix\n"},
+	{1, "  References <Addr>", "Find all references to object at addr\n"},
+	{1, "  Resources [DeviceName]",
+	 "Display Device resources (no arg = all devices)\n"},
+	{1, "  Set N <NamedObject> <Value>", "Set value for named integer\n"},
+	{1, "  Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
+	{1, "  Type <Object>", "Display object type\n"},
+
+	{0, "\nControl Method Execution Commands:", "\n"},
+	{1, "  Arguments (or Args)", "Display method arguments\n"},
+	{1, "  Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"},
+	{1, "  Call", "Run to next control method invocation\n"},
+	{1, "  Debug <Namepath> [Arguments]", "Single Step a control method\n"},
+	{6, "  Evaluate", "Synonym for Execute\n"},
+	{5, "  Execute <Namepath> [Arguments]", "Execute control method\n"},
+	{1, "     Hex Integer", "Integer method argument\n"},
+	{1, "     \"Ascii String\"", "String method argument\n"},
+	{1, "     (Hex Byte List)", "Buffer method argument\n"},
+	{1, "     [Package Element List]", "Package method argument\n"},
+	{1, "  Go", "Allow method to run to completion\n"},
+	{1, "  Information", "Display info about the current method\n"},
+	{1, "  Into", "Step into (not over) a method call\n"},
+	{1, "  List [# of Aml Opcodes]", "Display method ASL statements\n"},
+	{1, "  Locals", "Display method local variables\n"},
+	{1, "  Results", "Display method result stack\n"},
+	{1, "  Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"},
+	{1, "  Stop", "Terminate control method\n"},
+	{5, "  Trace <State> [<Namepath>] [Once]",
+	 "Trace control method execution\n"},
+	{1, "     Enable", "Enable all messages\n"},
+	{1, "     Disable", "Disable tracing\n"},
+	{1, "     Method", "Enable method execution messages\n"},
+	{1, "     Opcode", "Enable opcode execution messages\n"},
+	{1, "  Tree", "Display control method calling tree\n"},
+	{1, "  <Enter>", "Single step next AML opcode (over calls)\n"},
+
+#ifdef ACPI_APPLICATION
+	{0, "\nHardware Simulation Commands:", "\n"},
+	{1, "  EnableAcpi", "Enable ACPI (hardware) mode\n"},
+	{1, "  Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
+	{1, "  Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"},
+	{1, "  Gpes", "Display info on all GPE devices\n"},
+	{1, "  Sci", "Generate an SCI\n"},
+	{1, "  Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
+
+	{0, "\nFile I/O Commands:", "\n"},
+	{1, "  Close", "Close debug output file\n"},
+	{1, "  Load <Input Filename>", "Load ACPI table from a file\n"},
+	{1, "  Open <Output Filename>", "Open a file for debug output\n"},
+	{1, "  Unload <Namepath>",
+	 "Unload an ACPI table via namespace object\n"},
+
+	{0, "\nUser Space Commands:", "\n"},
+	{1, "  Terminate", "Delete namespace and all internal objects\n"},
+	{1, "  Thread <Threads><Loops><NamePath>",
+	 "Spawn threads to execute method(s)\n"},
+
+	{0, "\nDebug Test Commands:", "\n"},
+	{3, "  Test <TestName>", "Invoke a debug test\n"},
+	{1, "     Objects", "Read/write/compare all namespace data objects\n"},
+	{1, "     Predefined",
+	 "Execute all ACPI predefined names (_STA, etc.)\n"},
+#endif
+	{0, NULL, NULL}
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_match_command_help
+ *
+ * PARAMETERS:  command             - Command string to match
+ *              help                - Help table entry to attempt match
+ *
+ * RETURN:      TRUE if command matched, FALSE otherwise
+ *
+ * DESCRIPTION: Attempt to match a command in the help table in order to
+ *              print help information for a single command.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_db_match_command_help(char *command,
+			   const struct acpi_db_command_help *help)
+{
+	char *invocation = help->invocation;
+	u32 line_count;
+
+	/* Valid commands in the help table begin with a couple of spaces */
+
+	if (*invocation != ' ') {
+		return (FALSE);
+	}
+
+	while (*invocation == ' ') {
+		invocation++;
+	}
+
+	/* Match command name (full command or substring) */
+
+	while ((*command) && (*invocation) && (*invocation != ' ')) {
+		if (tolower((int)*command) != tolower((int)*invocation)) {
+			return (FALSE);
+		}
+
+		invocation++;
+		command++;
+	}
+
+	/* Print the appropriate number of help lines */
+
+	line_count = help->line_count;
+	while (line_count) {
+		acpi_os_printf("%-38s : %s", help->invocation,
+			       help->description);
+		help++;
+		line_count--;
+	}
+
+	return (TRUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_command_info
+ *
+ * PARAMETERS:  command             - Command string to match
+ *              display_all         - Display all matching commands, or just
+ *                                    the first one (substring match)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display help information for a Debugger command.
+ *
+ ******************************************************************************/
+
+static void acpi_db_display_command_info(char *command, u8 display_all)
+{
+	const struct acpi_db_command_help *next;
+	u8 matched;
+
+	next = acpi_gbl_db_command_help;
+	while (next->invocation) {
+		matched = acpi_db_match_command_help(command, next);
+		if (!display_all && matched) {
+			return;
+		}
+
+		next++;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_help
+ *
+ * PARAMETERS:  command             - Optional command string to display help.
+ *                                    if not specified, all debugger command
+ *                                    help strings are displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display help for a single debugger command, or all of them.
+ *
+ ******************************************************************************/
+
+static void acpi_db_display_help(char *command)
+{
+	const struct acpi_db_command_help *next = acpi_gbl_db_command_help;
+
+	if (!command) {
+
+		/* No argument to help, display help for all commands */
+
+		while (next->invocation) {
+			acpi_os_printf("%-38s%s", next->invocation,
+				       next->description);
+			next++;
+		}
+	} else {
+		/* Display help for all commands that match the subtring */
+
+		acpi_db_display_command_info(command, TRUE);
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_next_token
+ *
+ * PARAMETERS:  string          - Command buffer
+ *              next            - Return value, end of next token
+ *
+ * RETURN:      Pointer to the start of the next token.
+ *
+ * DESCRIPTION: Command line parsing. Get the next token on the command line
+ *
+ ******************************************************************************/
+
+char *acpi_db_get_next_token(char *string,
+			     char **next, acpi_object_type * return_type)
+{
+	char *start;
+	u32 depth;
+	acpi_object_type type = ACPI_TYPE_INTEGER;
+
+	/* At end of buffer? */
+
+	if (!string || !(*string)) {
+		return (NULL);
+	}
+
+	/* Remove any spaces at the beginning */
+
+	if (*string == ' ') {
+		while (*string && (*string == ' ')) {
+			string++;
+		}
+
+		if (!(*string)) {
+			return (NULL);
+		}
+	}
+
+	switch (*string) {
+	case '"':
+
+		/* This is a quoted string, scan until closing quote */
+
+		string++;
+		start = string;
+		type = ACPI_TYPE_STRING;
+
+		/* Find end of string */
+
+		while (*string && (*string != '"')) {
+			string++;
+		}
+		break;
+
+	case '(':
+
+		/* This is the start of a buffer, scan until closing paren */
+
+		string++;
+		start = string;
+		type = ACPI_TYPE_BUFFER;
+
+		/* Find end of buffer */
+
+		while (*string && (*string != ')')) {
+			string++;
+		}
+		break;
+
+	case '[':
+
+		/* This is the start of a package, scan until closing bracket */
+
+		string++;
+		depth = 1;
+		start = string;
+		type = ACPI_TYPE_PACKAGE;
+
+		/* Find end of package (closing bracket) */
+
+		while (*string) {
+
+			/* Handle String package elements */
+
+			if (*string == '"') {
+				/* Find end of string */
+
+				string++;
+				while (*string && (*string != '"')) {
+					string++;
+				}
+				if (!(*string)) {
+					break;
+				}
+			} else if (*string == '[') {
+				depth++;	/* A nested package declaration */
+			} else if (*string == ']') {
+				depth--;
+				if (depth == 0) {	/* Found final package closing bracket */
+					break;
+				}
+			}
+
+			string++;
+		}
+		break;
+
+	default:
+
+		start = string;
+
+		/* Find end of token */
+
+		while (*string && (*string != ' ')) {
+			string++;
+		}
+		break;
+	}
+
+	if (!(*string)) {
+		*next = NULL;
+	} else {
+		*string = 0;
+		*next = string + 1;
+	}
+
+	*return_type = type;
+	return (start);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_line
+ *
+ * PARAMETERS:  input_buffer        - Command line buffer
+ *
+ * RETURN:      Count of arguments to the command
+ *
+ * DESCRIPTION: Get the next command line from the user. Gets entire line
+ *              up to the next newline
+ *
+ ******************************************************************************/
+
+static u32 acpi_db_get_line(char *input_buffer)
+{
+	u32 i;
+	u32 count;
+	char *next;
+	char *this;
+
+	if (acpi_ut_safe_strcpy
+	    (acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf),
+	     input_buffer)) {
+		acpi_os_printf
+		    ("Buffer overflow while parsing input line (max %u characters)\n",
+		     sizeof(acpi_gbl_db_parsed_buf));
+		return (0);
+	}
+
+	this = acpi_gbl_db_parsed_buf;
+	for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++) {
+		acpi_gbl_db_args[i] = acpi_db_get_next_token(this, &next,
+							     &acpi_gbl_db_arg_types
+							     [i]);
+		if (!acpi_gbl_db_args[i]) {
+			break;
+		}
+
+		this = next;
+	}
+
+	/* Uppercase the actual command */
+
+	if (acpi_gbl_db_args[0]) {
+		acpi_ut_strupr(acpi_gbl_db_args[0]);
+	}
+
+	count = i;
+	if (count) {
+		count--;	/* Number of args only */
+	}
+
+	return (count);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_match_command
+ *
+ * PARAMETERS:  user_command            - User command line
+ *
+ * RETURN:      Index into command array, -1 if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+static u32 acpi_db_match_command(char *user_command)
+{
+	u32 i;
+
+	if (!user_command || user_command[0] == 0) {
+		return (CMD_NULL);
+	}
+
+	for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) {
+		if (strstr(acpi_gbl_db_commands[i].name, user_command) ==
+		    acpi_gbl_db_commands[i].name) {
+			return (i);
+		}
+	}
+
+	/* Command not recognized */
+
+	return (CMD_NOT_FOUND);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_command_dispatch
+ *
+ * PARAMETERS:  input_buffer        - Command line buffer
+ *              walk_state          - Current walk
+ *              op                  - Current (executing) parse op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Command dispatcher.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_command_dispatch(char *input_buffer,
+			 struct acpi_walk_state * walk_state,
+			 union acpi_parse_object * op)
+{
+	u32 temp;
+	u32 command_index;
+	u32 param_count;
+	char *command_line;
+	acpi_status status = AE_CTRL_TRUE;
+
+	/* If acpi_terminate has been called, terminate this thread */
+
+	if (acpi_gbl_db_terminate_loop) {
+		return (AE_CTRL_TERMINATE);
+	}
+
+	/* Find command and add to the history buffer */
+
+	param_count = acpi_db_get_line(input_buffer);
+	command_index = acpi_db_match_command(acpi_gbl_db_args[0]);
+	temp = 0;
+
+	/*
+	 * We don't want to add the !! command to the history buffer. It
+	 * would cause an infinite loop because it would always be the
+	 * previous command.
+	 */
+	if (command_index != CMD_HISTORY_LAST) {
+		acpi_db_add_to_history(input_buffer);
+	}
+
+	/* Verify that we have the minimum number of params */
+
+	if (param_count < acpi_gbl_db_commands[command_index].min_args) {
+		acpi_os_printf
+		    ("%u parameters entered, [%s] requires %u parameters\n",
+		     param_count, acpi_gbl_db_commands[command_index].name,
+		     acpi_gbl_db_commands[command_index].min_args);
+
+		acpi_db_display_command_info(acpi_gbl_db_commands
+					     [command_index].name, FALSE);
+		return (AE_CTRL_TRUE);
+	}
+
+	/* Decode and dispatch the command */
+
+	switch (command_index) {
+	case CMD_NULL:
+
+		if (op) {
+			return (AE_OK);
+		}
+		break;
+
+	case CMD_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+		acpi_ut_dump_allocations((u32)-1, NULL);
+#endif
+		break;
+
+	case CMD_ARGS:
+	case CMD_ARGUMENTS:
+
+		acpi_db_display_arguments();
+		break;
+
+	case CMD_BREAKPOINT:
+
+		acpi_db_set_method_breakpoint(acpi_gbl_db_args[1], walk_state,
+					      op);
+		break;
+
+	case CMD_BUSINFO:
+
+		acpi_db_get_bus_info();
+		break;
+
+	case CMD_CALL:
+
+		acpi_db_set_method_call_breakpoint(op);
+		status = AE_OK;
+		break;
+
+	case CMD_DEBUG:
+
+		acpi_db_execute(acpi_gbl_db_args[1],
+				&acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2],
+				EX_SINGLE_STEP);
+		break;
+
+	case CMD_DISASSEMBLE:
+	case CMD_DISASM:
+
+		(void)acpi_db_disassemble_method(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_DUMP:
+
+		acpi_db_decode_and_display_object(acpi_gbl_db_args[1],
+						  acpi_gbl_db_args[2]);
+		break;
+
+	case CMD_EVALUATE:
+	case CMD_EXECUTE:
+
+		acpi_db_execute(acpi_gbl_db_args[1],
+				&acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2],
+				EX_NO_SINGLE_STEP);
+		break;
+
+	case CMD_FIND:
+
+		status = acpi_db_find_name_in_namespace(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_GO:
+
+		acpi_gbl_cm_single_step = FALSE;
+		return (AE_OK);
+
+	case CMD_HANDLERS:
+
+		acpi_db_display_handlers();
+		break;
+
+	case CMD_HELP:
+	case CMD_HELP2:
+
+		acpi_db_display_help(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_HISTORY:
+
+		acpi_db_display_history();
+		break;
+
+	case CMD_HISTORY_EXE:	/* ! command */
+
+		command_line = acpi_db_get_from_history(acpi_gbl_db_args[1]);
+		if (!command_line) {
+			return (AE_CTRL_TRUE);
+		}
+
+		status = acpi_db_command_dispatch(command_line, walk_state, op);
+		return (status);
+
+	case CMD_HISTORY_LAST:	/* !! command */
+
+		command_line = acpi_db_get_from_history(NULL);
+		if (!command_line) {
+			return (AE_CTRL_TRUE);
+		}
+
+		status = acpi_db_command_dispatch(command_line, walk_state, op);
+		return (status);
+
+	case CMD_INFORMATION:
+
+		acpi_db_display_method_info(op);
+		break;
+
+	case CMD_INTEGRITY:
+
+		acpi_db_check_integrity();
+		break;
+
+	case CMD_INTO:
+
+		if (op) {
+			acpi_gbl_cm_single_step = TRUE;
+			return (AE_OK);
+		}
+		break;
+
+	case CMD_LEVEL:
+
+		if (param_count == 0) {
+			acpi_os_printf
+			    ("Current debug level for file output is:    %8.8lX\n",
+			     acpi_gbl_db_debug_level);
+			acpi_os_printf
+			    ("Current debug level for console output is: %8.8lX\n",
+			     acpi_gbl_db_console_debug_level);
+		} else if (param_count == 2) {
+			temp = acpi_gbl_db_console_debug_level;
+			acpi_gbl_db_console_debug_level =
+			    strtoul(acpi_gbl_db_args[1], NULL, 16);
+			acpi_os_printf
+			    ("Debug Level for console output was %8.8lX, now %8.8lX\n",
+			     temp, acpi_gbl_db_console_debug_level);
+		} else {
+			temp = acpi_gbl_db_debug_level;
+			acpi_gbl_db_debug_level =
+			    strtoul(acpi_gbl_db_args[1], NULL, 16);
+			acpi_os_printf
+			    ("Debug Level for file output was %8.8lX, now %8.8lX\n",
+			     temp, acpi_gbl_db_debug_level);
+		}
+		break;
+
+	case CMD_LIST:
+
+		acpi_db_disassemble_aml(acpi_gbl_db_args[1], op);
+		break;
+
+	case CMD_LOCKS:
+
+		acpi_db_display_locks();
+		break;
+
+	case CMD_LOCALS:
+
+		acpi_db_display_locals();
+		break;
+
+	case CMD_METHODS:
+
+		status = acpi_db_display_objects("METHOD", acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_NAMESPACE:
+
+		acpi_db_dump_namespace(acpi_gbl_db_args[1],
+				       acpi_gbl_db_args[2]);
+		break;
+
+	case CMD_NOTIFY:
+
+		temp = strtoul(acpi_gbl_db_args[2], NULL, 0);
+		acpi_db_send_notify(acpi_gbl_db_args[1], temp);
+		break;
+
+	case CMD_OBJECTS:
+
+		acpi_ut_strupr(acpi_gbl_db_args[1]);
+		status =
+		    acpi_db_display_objects(acpi_gbl_db_args[1],
+					    acpi_gbl_db_args[2]);
+		break;
+
+	case CMD_OSI:
+
+		acpi_db_display_interfaces(acpi_gbl_db_args[1],
+					   acpi_gbl_db_args[2]);
+		break;
+
+	case CMD_OWNER:
+
+		acpi_db_dump_namespace_by_owner(acpi_gbl_db_args[1],
+						acpi_gbl_db_args[2]);
+		break;
+
+	case CMD_PATHS:
+
+		acpi_db_dump_namespace_paths();
+		break;
+
+	case CMD_PREFIX:
+
+		acpi_db_set_scope(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_REFERENCES:
+
+		acpi_db_find_references(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_RESOURCES:
+
+		acpi_db_display_resources(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_RESULTS:
+
+		acpi_db_display_results();
+		break;
+
+	case CMD_SET:
+
+		acpi_db_set_method_data(acpi_gbl_db_args[1],
+					acpi_gbl_db_args[2],
+					acpi_gbl_db_args[3]);
+		break;
+
+	case CMD_STATS:
+
+		status = acpi_db_display_statistics(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_STOP:
+
+		return (AE_NOT_IMPLEMENTED);
+
+	case CMD_TABLES:
+
+		acpi_db_display_table_info(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_TEMPLATE:
+
+		acpi_db_display_template(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_TRACE:
+
+		acpi_db_trace(acpi_gbl_db_args[1], acpi_gbl_db_args[2],
+			      acpi_gbl_db_args[3]);
+		break;
+
+	case CMD_TREE:
+
+		acpi_db_display_calling_tree();
+		break;
+
+	case CMD_TYPE:
+
+		acpi_db_display_object_type(acpi_gbl_db_args[1]);
+		break;
+
+#ifdef ACPI_APPLICATION
+
+		/* Hardware simulation commands. */
+
+	case CMD_ENABLEACPI:
+#if (!ACPI_REDUCED_HARDWARE)
+
+		status = acpi_enable();
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiEnable failed (Status=%X)\n",
+				       status);
+			return (status);
+		}
+#endif				/* !ACPI_REDUCED_HARDWARE */
+		break;
+
+	case CMD_EVENT:
+
+		acpi_os_printf("Event command not implemented\n");
+		break;
+
+	case CMD_GPE:
+
+		acpi_db_generate_gpe(acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
+		break;
+
+	case CMD_GPES:
+
+		acpi_db_display_gpes();
+		break;
+
+	case CMD_SCI:
+
+		acpi_db_generate_sci();
+		break;
+
+	case CMD_SLEEP:
+
+		status = acpi_db_sleep(acpi_gbl_db_args[1]);
+		break;
+
+		/* File I/O commands. */
+
+	case CMD_CLOSE:
+
+		acpi_db_close_debug_file();
+		break;
+
+	case CMD_LOAD:
+
+		status =
+		    acpi_db_get_table_from_file(acpi_gbl_db_args[1], NULL,
+						FALSE);
+		break;
+
+	case CMD_OPEN:
+
+		acpi_db_open_debug_file(acpi_gbl_db_args[1]);
+		break;
+
+		/* User space commands. */
+
+	case CMD_TERMINATE:
+
+		acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+		acpi_ut_subsystem_shutdown();
+
+		/*
+		 * TBD: [Restructure] Need some way to re-initialize without
+		 * re-creating the semaphores!
+		 */
+
+		acpi_gbl_db_terminate_loop = TRUE;
+		/*  acpi_initialize (NULL); */
+		break;
+
+	case CMD_THREADS:
+
+		acpi_db_create_execution_threads(acpi_gbl_db_args[1],
+						 acpi_gbl_db_args[2],
+						 acpi_gbl_db_args[3]);
+		break;
+
+		/* Debug test commands. */
+
+	case CMD_PREDEFINED:
+
+		acpi_db_check_predefined_names();
+		break;
+
+	case CMD_TEST:
+
+		acpi_db_execute_test(acpi_gbl_db_args[1]);
+		break;
+
+	case CMD_UNLOAD:
+
+		acpi_db_unload_acpi_table(acpi_gbl_db_args[1]);
+		break;
+#endif
+
+	case CMD_EXIT:
+	case CMD_QUIT:
+
+		if (op) {
+			acpi_os_printf("Method execution terminated\n");
+			return (AE_CTRL_TERMINATE);
+		}
+
+		if (!acpi_gbl_db_output_to_file) {
+			acpi_dbg_level = ACPI_DEBUG_DEFAULT;
+		}
+#ifdef ACPI_APPLICATION
+		acpi_db_close_debug_file();
+#endif
+		acpi_gbl_db_terminate_loop = TRUE;
+		return (AE_CTRL_TERMINATE);
+
+	case CMD_NOT_FOUND:
+	default:
+
+		acpi_os_printf("%s: unknown command\n", acpi_gbl_db_args[0]);
+		return (AE_CTRL_TRUE);
+	}
+
+	if (ACPI_SUCCESS(status)) {
+		status = AE_CTRL_TRUE;
+	}
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_thread
+ *
+ * PARAMETERS:  context         - Not used
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context)
+{
+	acpi_status status = AE_OK;
+	acpi_status Mstatus;
+
+	while (status != AE_CTRL_TERMINATE && !acpi_gbl_db_terminate_loop) {
+		acpi_gbl_method_executing = FALSE;
+		acpi_gbl_step_to_next_call = FALSE;
+
+		Mstatus = acpi_os_acquire_mutex(acpi_gbl_db_command_ready,
+						ACPI_WAIT_FOREVER);
+		if (ACPI_FAILURE(Mstatus)) {
+			return;
+		}
+
+		status =
+		    acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL);
+
+		acpi_os_release_mutex(acpi_gbl_db_command_complete);
+	}
+	acpi_gbl_db_threads_terminated = TRUE;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_single_thread
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void acpi_db_single_thread(void)
+{
+
+	acpi_gbl_method_executing = FALSE;
+	acpi_gbl_step_to_next_call = FALSE;
+
+	(void)acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_user_commands
+ *
+ * PARAMETERS:  prompt              - User prompt (depends on mode)
+ *              op                  - Current executing parse op
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Command line execution for the AML debugger. Commands are
+ *              matched and dispatched here.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
+{
+	acpi_status status = AE_OK;
+
+	acpi_os_printf("\n");
+
+	/* TBD: [Restructure] Need a separate command line buffer for step mode */
+
+	while (!acpi_gbl_db_terminate_loop) {
+
+		/* Force output to console until a command is entered */
+
+		acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+
+		/* Different prompt if method is executing */
+
+		if (!acpi_gbl_method_executing) {
+			acpi_os_printf("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
+		} else {
+			acpi_os_printf("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
+		}
+
+		/* Get the user input line */
+
+		status = acpi_os_get_line(acpi_gbl_db_line_buf,
+					  ACPI_DB_LINE_BUFFER_SIZE, NULL);
+		if (ACPI_FAILURE(status)) {
+			ACPI_EXCEPTION((AE_INFO, status,
+					"While parsing command line"));
+			return (status);
+		}
+
+		/* Check for single or multithreaded debug */
+
+		if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+			/*
+			 * Signal the debug thread that we have a command to execute,
+			 * and wait for the command to complete.
+			 */
+			acpi_os_release_mutex(acpi_gbl_db_command_ready);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+
+			status =
+			    acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
+						  ACPI_WAIT_FOREVER);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+		} else {
+			/* Just call to the command line interpreter */
+
+			acpi_db_single_thread();
+		}
+	}
+
+	return (status);
+}
diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c
new file mode 100644
index 0000000..01e5a71
--- /dev/null
+++ b/drivers/acpi/acpica/dbmethod.c
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ *
+ * Module Name: dbmethod - Debug commands for control methods
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "acparser.h"
+#include "acpredef.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbmethod")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_method_breakpoint
+ *
+ * PARAMETERS:  location            - AML offset of breakpoint
+ *              walk_state          - Current walk info
+ *              op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ *              AML offset
+ *
+ ******************************************************************************/
+void
+acpi_db_set_method_breakpoint(char *location,
+			      struct acpi_walk_state *walk_state,
+			      union acpi_parse_object *op)
+{
+	u32 address;
+	u32 aml_offset;
+
+	if (!op) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	/* Get and verify the breakpoint address */
+
+	address = strtoul(location, NULL, 16);
+	aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
+					walk_state->parser_state.aml_start);
+	if (address <= aml_offset) {
+		acpi_os_printf("Breakpoint %X is beyond current address %X\n",
+			       address, aml_offset);
+	}
+
+	/* Save breakpoint in current walk */
+
+	walk_state->user_breakpoint = address;
+	acpi_os_printf("Breakpoint set at AML offset %X\n", address);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_method_call_breakpoint
+ *
+ * PARAMETERS:  op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ *              AML offset
+ *
+ ******************************************************************************/
+
+void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op)
+{
+
+	if (!op) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	acpi_gbl_step_to_next_call = TRUE;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_method_data
+ *
+ * PARAMETERS:  type_arg        - L for local, A for argument
+ *              index_arg       - which one
+ *              value_arg       - Value to set.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a local or argument for the running control method.
+ *              NOTE: only object supported is Number.
+ *
+ ******************************************************************************/
+
+void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg)
+{
+	char type;
+	u32 index;
+	u32 value;
+	struct acpi_walk_state *walk_state;
+	union acpi_operand_object *obj_desc;
+	acpi_status status;
+	struct acpi_namespace_node *node;
+
+	/* Validate type_arg */
+
+	acpi_ut_strupr(type_arg);
+	type = type_arg[0];
+	if ((type != 'L') && (type != 'A') && (type != 'N')) {
+		acpi_os_printf("Invalid SET operand: %s\n", type_arg);
+		return;
+	}
+
+	value = strtoul(value_arg, NULL, 16);
+
+	if (type == 'N') {
+		node = acpi_db_convert_to_node(index_arg);
+		if (!node) {
+			return;
+		}
+
+		if (node->type != ACPI_TYPE_INTEGER) {
+			acpi_os_printf("Can only set Integer nodes\n");
+			return;
+		}
+		obj_desc = node->object;
+		obj_desc->integer.value = value;
+		return;
+	}
+
+	/* Get the index and value */
+
+	index = strtoul(index_arg, NULL, 16);
+
+	walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+	if (!walk_state) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	/* Create and initialize the new object */
+
+	obj_desc = acpi_ut_create_integer_object((u64)value);
+	if (!obj_desc) {
+		acpi_os_printf("Could not create an internal object\n");
+		return;
+	}
+
+	/* Store the new object into the target */
+
+	switch (type) {
+	case 'A':
+
+		/* Set a method argument */
+
+		if (index > ACPI_METHOD_MAX_ARG) {
+			acpi_os_printf("Arg%u - Invalid argument name\n",
+				       index);
+			goto cleanup;
+		}
+
+		status = acpi_ds_store_object_to_local(ACPI_REFCLASS_ARG,
+						       index, obj_desc,
+						       walk_state);
+		if (ACPI_FAILURE(status)) {
+			goto cleanup;
+		}
+
+		obj_desc = walk_state->arguments[index].object;
+
+		acpi_os_printf("Arg%u: ", index);
+		acpi_db_display_internal_object(obj_desc, walk_state);
+		break;
+
+	case 'L':
+
+		/* Set a method local */
+
+		if (index > ACPI_METHOD_MAX_LOCAL) {
+			acpi_os_printf
+			    ("Local%u - Invalid local variable name\n", index);
+			goto cleanup;
+		}
+
+		status = acpi_ds_store_object_to_local(ACPI_REFCLASS_LOCAL,
+						       index, obj_desc,
+						       walk_state);
+		if (ACPI_FAILURE(status)) {
+			goto cleanup;
+		}
+
+		obj_desc = walk_state->local_variables[index].object;
+
+		acpi_os_printf("Local%u: ", index);
+		acpi_db_display_internal_object(obj_desc, walk_state);
+		break;
+
+	default:
+
+		break;
+	}
+
+cleanup:
+	acpi_ut_remove_reference(obj_desc);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_disassemble_aml
+ *
+ * PARAMETERS:  statements          - Number of statements to disassemble
+ *              op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ *              of statements specified.
+ *
+ ******************************************************************************/
+
+void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op)
+{
+	u32 num_statements = 8;
+
+	if (!op) {
+		acpi_os_printf("There is no method currently executing\n");
+		return;
+	}
+
+	if (statements) {
+		num_statements = strtoul(statements, NULL, 0);
+	}
+#ifdef ACPI_DISASSEMBLER
+	acpi_dm_disassemble(NULL, op, num_statements);
+#endif
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_disassemble_method
+ *
+ * PARAMETERS:  name            - Name of control method
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ *              of statements specified.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_disassemble_method(char *name)
+{
+	acpi_status status;
+	union acpi_parse_object *op;
+	struct acpi_walk_state *walk_state;
+	union acpi_operand_object *obj_desc;
+	struct acpi_namespace_node *method;
+
+	method = acpi_db_convert_to_node(name);
+	if (!method) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (method->type != ACPI_TYPE_METHOD) {
+		ACPI_ERROR((AE_INFO, "%s (%s): Object must be a control method",
+			    name, acpi_ut_get_type_name(method->type)));
+		return (AE_BAD_PARAMETER);
+	}
+
+	obj_desc = method->object;
+
+	op = acpi_ps_create_scope_op(obj_desc->method.aml_start);
+	if (!op) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Create and initialize a new walk state */
+
+	walk_state = acpi_ds_create_walk_state(0, op, NULL, NULL);
+	if (!walk_state) {
+		return (AE_NO_MEMORY);
+	}
+
+	status = acpi_ds_init_aml_walk(walk_state, op, NULL,
+				       obj_desc->method.aml_start,
+				       obj_desc->method.aml_length, NULL,
+				       ACPI_IMODE_LOAD_PASS1);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
+	walk_state->owner_id = obj_desc->method.owner_id;
+
+	/* Push start scope on scope stack and make it current */
+
+	status = acpi_ds_scope_stack_push(method, method->type, walk_state);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Parse the entire method AML including deferred operators */
+
+	walk_state->parse_flags &= ~ACPI_PARSE_DELETE_TREE;
+	walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE;
+
+	status = acpi_ps_parse_aml(walk_state);
+
+#ifdef ACPI_DISASSEMBLER
+	(void)acpi_dm_parse_deferred_ops(op);
+
+	/* Now we can disassemble the method */
+
+	acpi_gbl_dm_opt_verbose = FALSE;
+	acpi_dm_disassemble(NULL, op, 0);
+	acpi_gbl_dm_opt_verbose = TRUE;
+#endif
+
+	acpi_ps_delete_parse_tree(op);
+
+	/* Method cleanup */
+
+	acpi_ns_delete_namespace_subtree(method);
+	acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
+	acpi_ut_release_owner_id(&obj_desc->method.owner_id);
+	return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c
new file mode 100644
index 0000000..04ff1eb
--- /dev/null
+++ b/drivers/acpi/acpica/dbnames.c
@@ -0,0 +1,947 @@
+/*******************************************************************************
+ *
+ * Module Name: dbnames - Debugger commands for the acpi namespace
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "acpredef.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbnames")
+
+/* Local prototypes */
+static acpi_status
+acpi_db_walk_and_match_name(acpi_handle obj_handle,
+			    u32 nesting_level,
+			    void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
+				  u32 nesting_level,
+				  void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
+				  u32 nesting_level,
+				  void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_object_counts(acpi_handle obj_handle,
+			       u32 nesting_level,
+			       void *context, void **return_value);
+
+static acpi_status
+acpi_db_integrity_walk(acpi_handle obj_handle,
+		       u32 nesting_level, void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_references(acpi_handle obj_handle,
+			    u32 nesting_level,
+			    void *context, void **return_value);
+
+static acpi_status
+acpi_db_bus_walk(acpi_handle obj_handle,
+		 u32 nesting_level, void *context, void **return_value);
+
+/*
+ * Arguments for the Objects command
+ * These object types map directly to the ACPI_TYPES
+ */
+static struct acpi_db_argument_info acpi_db_object_types[] = {
+	{"ANY"},
+	{"INTEGERS"},
+	{"STRINGS"},
+	{"BUFFERS"},
+	{"PACKAGES"},
+	{"FIELDS"},
+	{"DEVICES"},
+	{"EVENTS"},
+	{"METHODS"},
+	{"MUTEXES"},
+	{"REGIONS"},
+	{"POWERRESOURCES"},
+	{"PROCESSORS"},
+	{"THERMALZONES"},
+	{"BUFFERFIELDS"},
+	{"DDBHANDLES"},
+	{"DEBUG"},
+	{"REGIONFIELDS"},
+	{"BANKFIELDS"},
+	{"INDEXFIELDS"},
+	{"REFERENCES"},
+	{"ALIASES"},
+	{"METHODALIASES"},
+	{"NOTIFY"},
+	{"ADDRESSHANDLER"},
+	{"RESOURCE"},
+	{"RESOURCEFIELD"},
+	{"SCOPES"},
+	{NULL}			/* Must be null terminated */
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_scope
+ *
+ * PARAMETERS:  name                - New scope path
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Set the "current scope" as maintained by this utility.
+ *              The scope is used as a prefix to ACPI paths.
+ *
+ ******************************************************************************/
+
+void acpi_db_set_scope(char *name)
+{
+	acpi_status status;
+	struct acpi_namespace_node *node;
+
+	if (!name || name[0] == 0) {
+		acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
+		return;
+	}
+
+	acpi_db_prep_namestring(name);
+
+	if (ACPI_IS_ROOT_PREFIX(name[0])) {
+
+		/* Validate new scope from the root */
+
+		status = acpi_ns_get_node(acpi_gbl_root_node, name,
+					  ACPI_NS_NO_UPSEARCH, &node);
+		if (ACPI_FAILURE(status)) {
+			goto error_exit;
+		}
+
+		acpi_gbl_db_scope_buf[0] = 0;
+	} else {
+		/* Validate new scope relative to old scope */
+
+		status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
+					  ACPI_NS_NO_UPSEARCH, &node);
+		if (ACPI_FAILURE(status)) {
+			goto error_exit;
+		}
+	}
+
+	/* Build the final pathname */
+
+	if (acpi_ut_safe_strcat
+	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
+		status = AE_BUFFER_OVERFLOW;
+		goto error_exit;
+	}
+
+	if (acpi_ut_safe_strcat
+	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
+		status = AE_BUFFER_OVERFLOW;
+		goto error_exit;
+	}
+
+	acpi_gbl_db_scope_node = node;
+	acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
+	return;
+
+error_exit:
+
+	acpi_os_printf("Could not attach scope: %s, %s\n",
+		       name, acpi_format_exception(status));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_namespace
+ *
+ * PARAMETERS:  start_arg       - Node to begin namespace dump
+ *              depth_arg       - Maximum tree depth to be dumped
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
+ *              with type and other information.
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
+{
+	acpi_handle subtree_entry = acpi_gbl_root_node;
+	u32 max_depth = ACPI_UINT32_MAX;
+
+	/* No argument given, just start at the root and dump entire namespace */
+
+	if (start_arg) {
+		subtree_entry = acpi_db_convert_to_node(start_arg);
+		if (!subtree_entry) {
+			return;
+		}
+
+		/* Now we can check for the depth argument */
+
+		if (depth_arg) {
+			max_depth = strtoul(depth_arg, NULL, 0);
+		}
+	}
+
+	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+	acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
+		       ((struct acpi_namespace_node *)subtree_entry)->name.
+		       ascii, subtree_entry);
+
+	/* Display the subtree */
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
+			     ACPI_OWNER_ID_MAX, subtree_entry);
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_namespace_paths
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump entire namespace with full object pathnames and object
+ *              type information. Alternative to "namespace" command.
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_namespace_paths(void)
+{
+
+	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+	acpi_os_printf("ACPI Namespace (from root):\n");
+
+	/* Display the entire namespace */
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
+				  ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
+				  acpi_gbl_root_node);
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_namespace_by_owner
+ *
+ * PARAMETERS:  owner_arg       - Owner ID whose nodes will be displayed
+ *              depth_arg       - Maximum tree depth to be dumped
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
+{
+	acpi_handle subtree_entry = acpi_gbl_root_node;
+	u32 max_depth = ACPI_UINT32_MAX;
+	acpi_owner_id owner_id;
+
+	owner_id = (acpi_owner_id) strtoul(owner_arg, NULL, 0);
+
+	/* Now we can check for the depth argument */
+
+	if (depth_arg) {
+		max_depth = strtoul(depth_arg, NULL, 0);
+	}
+
+	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+	acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);
+
+	/* Display the subtree */
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
+			     owner_id, subtree_entry);
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_and_match_name
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
+ *              are supported -- '?' matches any character.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_and_match_name(acpi_handle obj_handle,
+			    u32 nesting_level,
+			    void *context, void **return_value)
+{
+	acpi_status status;
+	char *requested_name = (char *)context;
+	u32 i;
+	struct acpi_buffer buffer;
+	struct acpi_walk_info info;
+
+	/* Check for a name match */
+
+	for (i = 0; i < 4; i++) {
+
+		/* Wildcard support */
+
+		if ((requested_name[i] != '?') &&
+		    (requested_name[i] != ((struct acpi_namespace_node *)
+					   obj_handle)->name.ascii[i])) {
+
+			/* No match, just exit */
+
+			return (AE_OK);
+		}
+	}
+
+	/* Get the full pathname to this object */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could Not get pathname for object %p\n",
+			       obj_handle);
+	} else {
+		info.owner_id = ACPI_OWNER_ID_MAX;
+		info.debug_level = ACPI_UINT32_MAX;
+		info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+		acpi_os_printf("%32s", (char *)buffer.pointer);
+		(void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
+					      NULL);
+		ACPI_FREE(buffer.pointer);
+	}
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_find_name_in_namespace
+ *
+ * PARAMETERS:  name_arg        - The 4-character ACPI name to find.
+ *                                wildcards are supported.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Search the namespace for a given name (with wildcards)
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_find_name_in_namespace(char *name_arg)
+{
+	char acpi_name[5] = "____";
+	char *acpi_name_ptr = acpi_name;
+
+	if (strlen(name_arg) > ACPI_NAME_SIZE) {
+		acpi_os_printf("Name must be no longer than 4 characters\n");
+		return (AE_OK);
+	}
+
+	/* Pad out name with underscores as necessary to create a 4-char name */
+
+	acpi_ut_strupr(name_arg);
+	while (*name_arg) {
+		*acpi_name_ptr = *name_arg;
+		acpi_name_ptr++;
+		name_arg++;
+	}
+
+	/* Walk the namespace from the root */
+
+	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
+				  NULL, acpi_name, NULL);
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_predefined_names
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Detect and display predefined ACPI names (names that start with
+ *              an underscore)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
+				  u32 nesting_level,
+				  void *context, void **return_value)
+{
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+	u32 *count = (u32 *)context;
+	const union acpi_predefined_info *predefined;
+	const union acpi_predefined_info *package = NULL;
+	char *pathname;
+	char string_buffer[48];
+
+	predefined = acpi_ut_match_predefined_method(node->name.ascii);
+	if (!predefined) {
+		return (AE_OK);
+	}
+
+	pathname = acpi_ns_get_external_pathname(node);
+	if (!pathname) {
+		return (AE_OK);
+	}
+
+	/* If method returns a package, the info is in the next table entry */
+
+	if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
+		package = predefined + 1;
+	}
+
+	acpi_ut_get_expected_return_types(string_buffer,
+					  predefined->info.expected_btypes);
+
+	acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
+		       METHOD_GET_ARG_COUNT(predefined->info.argument_list),
+		       string_buffer);
+
+	if (package) {
+		acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
+			       package->ret_info.type,
+			       package->ret_info.object_type1,
+			       package->ret_info.count1);
+	}
+
+	acpi_os_printf("\n");
+
+	/* Check that the declared argument count matches the ACPI spec */
+
+	acpi_ns_check_acpi_compliance(pathname, node, predefined);
+
+	ACPI_FREE(pathname);
+	(*count)++;
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_check_predefined_names
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Validate all predefined names in the namespace
+ *
+ ******************************************************************************/
+
+void acpi_db_check_predefined_names(void)
+{
+	u32 count = 0;
+
+	/* Search all nodes in namespace */
+
+	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX,
+				  acpi_db_walk_for_predefined_names, NULL,
+				  (void *)&count, NULL);
+
+	acpi_os_printf("Found %u predefined names in the namespace\n", count);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_object_counts
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_object_counts(acpi_handle obj_handle,
+			       u32 nesting_level,
+			       void *context, void **return_value)
+{
+	struct acpi_object_info *info = (struct acpi_object_info *)context;
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+
+	if (node->type > ACPI_TYPE_NS_NODE_MAX) {
+		acpi_os_printf("[%4.4s]: Unknown object type %X\n",
+			       node->name.ascii, node->type);
+	} else {
+		info->types[node->type]++;
+	}
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_specific_objects
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
+				  u32 nesting_level,
+				  void *context, void **return_value)
+{
+	struct acpi_walk_info *info = (struct acpi_walk_info *)context;
+	struct acpi_buffer buffer;
+	acpi_status status;
+
+	info->count++;
+
+	/* Get and display the full pathname to this object */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could Not get pathname for object %p\n",
+			       obj_handle);
+		return (AE_OK);
+	}
+
+	acpi_os_printf("%32s", (char *)buffer.pointer);
+	ACPI_FREE(buffer.pointer);
+
+	/* Dump short info about the object */
+
+	(void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_objects
+ *
+ * PARAMETERS:  obj_type_arg        - Type of object to display
+ *              display_count_arg   - Max depth to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display objects in the namespace of the requested type
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
+{
+	struct acpi_walk_info info;
+	acpi_object_type type;
+	struct acpi_object_info *object_info;
+	u32 i;
+	u32 total_objects = 0;
+
+	/* No argument means display summary/count of all object types */
+
+	if (!obj_type_arg) {
+		object_info =
+		    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
+
+		/* Walk the namespace from the root */
+
+		(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+					  ACPI_UINT32_MAX,
+					  acpi_db_walk_for_object_counts, NULL,
+					  (void *)object_info, NULL);
+
+		acpi_os_printf("\nSummary of namespace objects:\n\n");
+
+		for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
+			acpi_os_printf("%8u %s\n", object_info->types[i],
+				       acpi_ut_get_type_name(i));
+
+			total_objects += object_info->types[i];
+		}
+
+		acpi_os_printf("\n%8u Total namespace objects\n\n",
+			       total_objects);
+
+		ACPI_FREE(object_info);
+		return (AE_OK);
+	}
+
+	/* Get the object type */
+
+	type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
+	if (type == ACPI_TYPE_NOT_FOUND) {
+		acpi_os_printf("Invalid or unsupported argument\n");
+		return (AE_OK);
+	}
+
+	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+	acpi_os_printf
+	    ("Objects of type [%s] defined in the current ACPI Namespace:\n",
+	     acpi_ut_get_type_name(type));
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+
+	info.count = 0;
+	info.owner_id = ACPI_OWNER_ID_MAX;
+	info.debug_level = ACPI_UINT32_MAX;
+	info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+	/* Walk the namespace from the root */
+
+	(void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+				  acpi_db_walk_for_specific_objects, NULL,
+				  (void *)&info, NULL);
+
+	acpi_os_printf
+	    ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
+	     info.count, acpi_ut_get_type_name(type));
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_integrity_walk
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Examine one NS node for valid values.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_integrity_walk(acpi_handle obj_handle,
+		       u32 nesting_level, void *context, void **return_value)
+{
+	struct acpi_integrity_info *info =
+	    (struct acpi_integrity_info *)context;
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+	union acpi_operand_object *object;
+	u8 alias = TRUE;
+
+	info->nodes++;
+
+	/* Verify the NS node, and dereference aliases */
+
+	while (alias) {
+		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
+			acpi_os_printf
+			    ("Invalid Descriptor Type for Node %p [%s] - "
+			     "is %2.2X should be %2.2X\n", node,
+			     acpi_ut_get_descriptor_name(node),
+			     ACPI_GET_DESCRIPTOR_TYPE(node),
+			     ACPI_DESC_TYPE_NAMED);
+			return (AE_OK);
+		}
+
+		if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
+		    (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
+			node = (struct acpi_namespace_node *)node->object;
+		} else {
+			alias = FALSE;
+		}
+	}
+
+	if (node->type > ACPI_TYPE_LOCAL_MAX) {
+		acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
+			       node, node->type);
+		return (AE_OK);
+	}
+
+	if (!acpi_ut_valid_acpi_name(node->name.ascii)) {
+		acpi_os_printf("Invalid AcpiName for Node %p\n", node);
+		return (AE_OK);
+	}
+
+	object = acpi_ns_get_attached_object(node);
+	if (object) {
+		info->objects++;
+		if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
+			acpi_os_printf
+			    ("Invalid Descriptor Type for Object %p [%s]\n",
+			     object, acpi_ut_get_descriptor_name(object));
+		}
+	}
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_check_integrity
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check entire namespace for data structure integrity
+ *
+ ******************************************************************************/
+
+void acpi_db_check_integrity(void)
+{
+	struct acpi_integrity_info info = { 0, 0 };
+
+	/* Search all nodes in namespace */
+
+	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
+				  (void *)&info, NULL);
+
+	acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
+		       info.nodes, info.objects);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_references
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check if this namespace object refers to the target object
+ *              that is passed in as the context value.
+ *
+ * Note: Currently doesn't check subobjects within the Node's object
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_references(acpi_handle obj_handle,
+			    u32 nesting_level,
+			    void *context, void **return_value)
+{
+	union acpi_operand_object *obj_desc =
+	    (union acpi_operand_object *)context;
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+
+	/* Check for match against the namespace node itself */
+
+	if (node == (void *)obj_desc) {
+		acpi_os_printf("Object is a Node [%4.4s]\n",
+			       acpi_ut_get_node_name(node));
+	}
+
+	/* Check for match against the object attached to the node */
+
+	if (acpi_ns_get_attached_object(node) == obj_desc) {
+		acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
+			       node, acpi_ut_get_node_name(node));
+	}
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_find_references
+ *
+ * PARAMETERS:  object_arg      - String with hex value of the object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Search namespace for all references to the input object
+ *
+ ******************************************************************************/
+
+void acpi_db_find_references(char *object_arg)
+{
+	union acpi_operand_object *obj_desc;
+	acpi_size address;
+
+	/* Convert string to object pointer */
+
+	address = strtoul(object_arg, NULL, 16);
+	obj_desc = ACPI_TO_POINTER(address);
+
+	/* Search all nodes in namespace */
+
+	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX, acpi_db_walk_for_references,
+				  NULL, (void *)obj_desc, NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_bus_walk
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display info about device objects that have a corresponding
+ *              _PRT method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_bus_walk(acpi_handle obj_handle,
+		 u32 nesting_level, void *context, void **return_value)
+{
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+	acpi_status status;
+	struct acpi_buffer buffer;
+	struct acpi_namespace_node *temp_node;
+	struct acpi_device_info *info;
+	u32 i;
+
+	if ((node->type != ACPI_TYPE_DEVICE) &&
+	    (node->type != ACPI_TYPE_PROCESSOR)) {
+		return (AE_OK);
+	}
+
+	/* Exit if there is no _PRT under this device */
+
+	status = acpi_get_handle(node, METHOD_NAME__PRT,
+				 ACPI_CAST_PTR(acpi_handle, &temp_node));
+	if (ACPI_FAILURE(status)) {
+		return (AE_OK);
+	}
+
+	/* Get the full path to this device object */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could Not get pathname for object %p\n",
+			       obj_handle);
+		return (AE_OK);
+	}
+
+	status = acpi_get_object_info(obj_handle, &info);
+	if (ACPI_FAILURE(status)) {
+		return (AE_OK);
+	}
+
+	/* Display the full path */
+
+	acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
+	ACPI_FREE(buffer.pointer);
+
+	if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
+		acpi_os_printf(" - Is PCI Root Bridge");
+	}
+	acpi_os_printf("\n");
+
+	/* _PRT info */
+
+	acpi_os_printf("_PRT: %p\n", temp_node);
+
+	/* Dump _ADR, _HID, _UID, _CID */
+
+	if (info->valid & ACPI_VALID_ADR) {
+		acpi_os_printf("_ADR: %8.8X%8.8X\n",
+			       ACPI_FORMAT_UINT64(info->address));
+	} else {
+		acpi_os_printf("_ADR: <Not Present>\n");
+	}
+
+	if (info->valid & ACPI_VALID_HID) {
+		acpi_os_printf("_HID: %s\n", info->hardware_id.string);
+	} else {
+		acpi_os_printf("_HID: <Not Present>\n");
+	}
+
+	if (info->valid & ACPI_VALID_UID) {
+		acpi_os_printf("_UID: %s\n", info->unique_id.string);
+	} else {
+		acpi_os_printf("_UID: <Not Present>\n");
+	}
+
+	if (info->valid & ACPI_VALID_CID) {
+		for (i = 0; i < info->compatible_id_list.count; i++) {
+			acpi_os_printf("_CID: %s\n",
+				       info->compatible_id_list.ids[i].string);
+		}
+	} else {
+		acpi_os_printf("_CID: <Not Present>\n");
+	}
+
+	ACPI_FREE(info);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_bus_info
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display info about system busses.
+ *
+ ******************************************************************************/
+
+void acpi_db_get_bus_info(void)
+{
+	/* Search all nodes in namespace */
+
+	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
+				  NULL);
+}
diff --git a/drivers/acpi/acpica/dbobject.c b/drivers/acpi/acpica/dbobject.c
new file mode 100644
index 0000000..116f6db8
--- /dev/null
+++ b/drivers/acpi/acpica/dbobject.c
@@ -0,0 +1,533 @@
+/*******************************************************************************
+ *
+ * Module Name: dbobject - ACPI object decode and display
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbobject")
+
+/* Local prototypes */
+static void acpi_db_decode_node(struct acpi_namespace_node *node);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_method_info
+ *
+ * PARAMETERS:  status          - Method execution status
+ *              walk_state      - Current state of the parse tree walk
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Called when a method has been aborted because of an error.
+ *              Dumps the method execution stack, and the method locals/args,
+ *              and disassembles the AML opcode that failed.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_dump_method_info(acpi_status status, struct acpi_walk_state *walk_state)
+{
+	struct acpi_thread_state *thread;
+
+	/* Ignore control codes, they are not errors */
+
+	if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) {
+		return;
+	}
+
+	/* We may be executing a deferred opcode */
+
+	if (walk_state->deferred_node) {
+		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
+		return;
+	}
+
+	/*
+	 * If there is no Thread, we are not actually executing a method.
+	 * This can happen when the iASL compiler calls the interpreter
+	 * to perform constant folding.
+	 */
+	thread = walk_state->thread;
+	if (!thread) {
+		return;
+	}
+
+	/* Display the method locals and arguments */
+
+	acpi_os_printf("\n");
+	acpi_db_decode_locals(walk_state);
+	acpi_os_printf("\n");
+	acpi_db_decode_arguments(walk_state);
+	acpi_os_printf("\n");
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_internal_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
+{
+	u32 i;
+
+	if (!obj_desc) {
+		acpi_os_printf(" Uninitialized");
+		return;
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+		acpi_os_printf(" %p [%s]", obj_desc,
+			       acpi_ut_get_descriptor_name(obj_desc));
+		return;
+	}
+
+	acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc));
+
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_INTEGER:
+
+		acpi_os_printf(" %8.8X%8.8X",
+			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		acpi_os_printf("(%u) \"%.24s",
+			       obj_desc->string.length,
+			       obj_desc->string.pointer);
+
+		if (obj_desc->string.length > 24) {
+			acpi_os_printf("...");
+		} else {
+			acpi_os_printf("\"");
+		}
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		acpi_os_printf("(%u)", obj_desc->buffer.length);
+		for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
+			acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]);
+		}
+		break;
+
+	default:
+
+		acpi_os_printf(" %p", obj_desc);
+		break;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_node
+ *
+ * PARAMETERS:  node        - Object to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of a namespace node
+ *
+ ******************************************************************************/
+
+static void acpi_db_decode_node(struct acpi_namespace_node *node)
+{
+
+	acpi_os_printf("<Node>          Name %4.4s",
+		       acpi_ut_get_node_name(node));
+
+	if (node->flags & ANOBJ_METHOD_ARG) {
+		acpi_os_printf(" [Method Arg]");
+	}
+	if (node->flags & ANOBJ_METHOD_LOCAL) {
+		acpi_os_printf(" [Method Local]");
+	}
+
+	switch (node->type) {
+
+		/* These types have no attached object */
+
+	case ACPI_TYPE_DEVICE:
+
+		acpi_os_printf(" Device");
+		break;
+
+	case ACPI_TYPE_THERMAL:
+
+		acpi_os_printf(" Thermal Zone");
+		break;
+
+	default:
+
+		acpi_db_decode_internal_object(acpi_ns_get_attached_object
+					       (node));
+		break;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_internal_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *              walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of an internal object
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_internal_object(union acpi_operand_object *obj_desc,
+				struct acpi_walk_state *walk_state)
+{
+	u8 type;
+
+	acpi_os_printf("%p ", obj_desc);
+
+	if (!obj_desc) {
+		acpi_os_printf("<Null Object>\n");
+		return;
+	}
+
+	/* Decode the object type */
+
+	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
+	case ACPI_DESC_TYPE_PARSER:
+
+		acpi_os_printf("<Parser> ");
+		break;
+
+	case ACPI_DESC_TYPE_NAMED:
+
+		acpi_db_decode_node((struct acpi_namespace_node *)obj_desc);
+		break;
+
+	case ACPI_DESC_TYPE_OPERAND:
+
+		type = obj_desc->common.type;
+		if (type > ACPI_TYPE_LOCAL_MAX) {
+			acpi_os_printf(" Type %X [Invalid Type]", (u32)type);
+			return;
+		}
+
+		/* Decode the ACPI object type */
+
+		switch (obj_desc->common.type) {
+		case ACPI_TYPE_LOCAL_REFERENCE:
+
+			acpi_os_printf("[%s] ",
+				       acpi_ut_get_reference_name(obj_desc));
+
+			/* Decode the refererence */
+
+			switch (obj_desc->reference.class) {
+			case ACPI_REFCLASS_LOCAL:
+
+				acpi_os_printf("%X ",
+					       obj_desc->reference.value);
+				if (walk_state) {
+					obj_desc = walk_state->local_variables
+					    [obj_desc->reference.value].object;
+					acpi_os_printf("%p", obj_desc);
+					acpi_db_decode_internal_object
+					    (obj_desc);
+				}
+				break;
+
+			case ACPI_REFCLASS_ARG:
+
+				acpi_os_printf("%X ",
+					       obj_desc->reference.value);
+				if (walk_state) {
+					obj_desc = walk_state->arguments
+					    [obj_desc->reference.value].object;
+					acpi_os_printf("%p", obj_desc);
+					acpi_db_decode_internal_object
+					    (obj_desc);
+				}
+				break;
+
+			case ACPI_REFCLASS_INDEX:
+
+				switch (obj_desc->reference.target_type) {
+				case ACPI_TYPE_BUFFER_FIELD:
+
+					acpi_os_printf("%p",
+						       obj_desc->reference.
+						       object);
+					acpi_db_decode_internal_object
+					    (obj_desc->reference.object);
+					break;
+
+				case ACPI_TYPE_PACKAGE:
+
+					acpi_os_printf("%p",
+						       obj_desc->reference.
+						       where);
+					if (!obj_desc->reference.where) {
+						acpi_os_printf
+						    (" Uninitialized WHERE pointer");
+					} else {
+						acpi_db_decode_internal_object(*
+									       (obj_desc->
+										reference.
+										where));
+					}
+					break;
+
+				default:
+
+					acpi_os_printf
+					    ("Unknown index target type");
+					break;
+				}
+				break;
+
+			case ACPI_REFCLASS_REFOF:
+
+				if (!obj_desc->reference.object) {
+					acpi_os_printf
+					    ("Uninitialized reference subobject pointer");
+					break;
+				}
+
+				/* Reference can be to a Node or an Operand object */
+
+				switch (ACPI_GET_DESCRIPTOR_TYPE
+					(obj_desc->reference.object)) {
+				case ACPI_DESC_TYPE_NAMED:
+
+					acpi_db_decode_node(obj_desc->reference.
+							    object);
+					break;
+
+				case ACPI_DESC_TYPE_OPERAND:
+
+					acpi_db_decode_internal_object
+					    (obj_desc->reference.object);
+					break;
+
+				default:
+					break;
+				}
+				break;
+
+			case ACPI_REFCLASS_NAME:
+
+				acpi_db_decode_node(obj_desc->reference.node);
+				break;
+
+			case ACPI_REFCLASS_DEBUG:
+			case ACPI_REFCLASS_TABLE:
+
+				acpi_os_printf("\n");
+				break;
+
+			default:	/* Unknown reference class */
+
+				acpi_os_printf("%2.2X\n",
+					       obj_desc->reference.class);
+				break;
+			}
+			break;
+
+		default:
+
+			acpi_os_printf("<Obj>          ");
+			acpi_db_decode_internal_object(obj_desc);
+			break;
+		}
+		break;
+
+	default:
+
+		acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
+			       acpi_ut_get_descriptor_name(obj_desc));
+		break;
+	}
+
+	acpi_os_printf("\n");
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_locals
+ *
+ * PARAMETERS:  walk_state      - State for current method
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_locals(struct acpi_walk_state *walk_state)
+{
+	u32 i;
+	union acpi_operand_object *obj_desc;
+	struct acpi_namespace_node *node;
+	u8 display_locals = FALSE;
+
+	obj_desc = walk_state->method_desc;
+	node = walk_state->method_node;
+
+	if (!node) {
+		acpi_os_printf
+		    ("No method node (Executing subtree for buffer or opregion)\n");
+		return;
+	}
+
+	if (node->type != ACPI_TYPE_METHOD) {
+		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
+		return;
+	}
+
+	/* Are any locals actually set? */
+
+	for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
+		obj_desc = walk_state->local_variables[i].object;
+		if (obj_desc) {
+			display_locals = TRUE;
+			break;
+		}
+	}
+
+	/* If any are set, only display the ones that are set */
+
+	if (display_locals) {
+		acpi_os_printf
+		    ("\nInitialized Local Variables for method [%4.4s]:\n",
+		     acpi_ut_get_node_name(node));
+
+		for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
+			obj_desc = walk_state->local_variables[i].object;
+			if (obj_desc) {
+				acpi_os_printf("  Local%X: ", i);
+				acpi_db_display_internal_object(obj_desc,
+								walk_state);
+			}
+		}
+	} else {
+		acpi_os_printf
+		    ("No Local Variables are initialized for method [%4.4s]\n",
+		     acpi_ut_get_node_name(node));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_arguments
+ *
+ * PARAMETERS:  walk_state      - State for current method
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_arguments(struct acpi_walk_state *walk_state)
+{
+	u32 i;
+	union acpi_operand_object *obj_desc;
+	struct acpi_namespace_node *node;
+	u8 display_args = FALSE;
+
+	node = walk_state->method_node;
+	obj_desc = walk_state->method_desc;
+
+	if (!node) {
+		acpi_os_printf
+		    ("No method node (Executing subtree for buffer or opregion)\n");
+		return;
+	}
+
+	if (node->type != ACPI_TYPE_METHOD) {
+		acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
+		return;
+	}
+
+	/* Are any arguments actually set? */
+
+	for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
+		obj_desc = walk_state->arguments[i].object;
+		if (obj_desc) {
+			display_args = TRUE;
+			break;
+		}
+	}
+
+	/* If any are set, only display the ones that are set */
+
+	if (display_args) {
+		acpi_os_printf("Initialized Arguments for Method [%4.4s]:  "
+			       "(%X arguments defined for method invocation)\n",
+			       acpi_ut_get_node_name(node),
+			       obj_desc->method.param_count);
+
+		for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
+			obj_desc = walk_state->arguments[i].object;
+			if (obj_desc) {
+				acpi_os_printf("  Arg%u:   ", i);
+				acpi_db_display_internal_object(obj_desc,
+								walk_state);
+			}
+		}
+	} else {
+		acpi_os_printf
+		    ("No Arguments are initialized for method [%4.4s]\n",
+		     acpi_ut_get_node_name(node));
+	}
+}
diff --git a/drivers/acpi/acpica/dbstats.c b/drivers/acpi/acpica/dbstats.c
new file mode 100644
index 0000000..4ba0a20
--- /dev/null
+++ b/drivers/acpi/acpica/dbstats.c
@@ -0,0 +1,546 @@
+/*******************************************************************************
+ *
+ * Module Name: dbstats - Generation and display of ACPI table statistics
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbstats")
+
+/* Local prototypes */
+static void acpi_db_count_namespace_objects(void);
+
+static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc);
+
+static acpi_status
+acpi_db_classify_one_object(acpi_handle obj_handle,
+			    u32 nesting_level,
+			    void *context, void **return_value);
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+static void acpi_db_list_info(struct acpi_memory_list *list);
+#endif
+
+/*
+ * Statistics subcommands
+ */
+static struct acpi_db_argument_info acpi_db_stat_types[] = {
+	{"ALLOCATIONS"},
+	{"OBJECTS"},
+	{"MEMORY"},
+	{"MISC"},
+	{"TABLES"},
+	{"SIZES"},
+	{"STACK"},
+	{NULL}			/* Must be null terminated */
+};
+
+#define CMD_STAT_ALLOCATIONS     0
+#define CMD_STAT_OBJECTS         1
+#define CMD_STAT_MEMORY          2
+#define CMD_STAT_MISC            3
+#define CMD_STAT_TABLES          4
+#define CMD_STAT_SIZES           5
+#define CMD_STAT_STACK           6
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_list_info
+ *
+ * PARAMETERS:  list            - Memory list/cache to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about the input memory list or cache.
+ *
+ ******************************************************************************/
+
+static void acpi_db_list_info(struct acpi_memory_list *list)
+{
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+	u32 outstanding;
+#endif
+
+	acpi_os_printf("\n%s\n", list->list_name);
+
+	/* max_depth > 0 indicates a cache object */
+
+	if (list->max_depth > 0) {
+		acpi_os_printf
+		    ("    Cache: [Depth    MaxD Avail  Size]                "
+		     "%8.2X %8.2X %8.2X %8.2X\n", list->current_depth,
+		     list->max_depth, list->max_depth - list->current_depth,
+		     (list->current_depth * list->object_size));
+	}
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+	if (list->max_depth > 0) {
+		acpi_os_printf
+		    ("    Cache: [Requests Hits Misses ObjSize]             "
+		     "%8.2X %8.2X %8.2X %8.2X\n", list->requests, list->hits,
+		     list->requests - list->hits, list->object_size);
+	}
+
+	outstanding = acpi_db_get_cache_info(list);
+
+	if (list->object_size) {
+		acpi_os_printf
+		    ("    Mem:   [Alloc    Free Max    CurSize Outstanding] "
+		     "%8.2X %8.2X %8.2X %8.2X %8.2X\n", list->total_allocated,
+		     list->total_freed, list->max_occupied,
+		     outstanding * list->object_size, outstanding);
+	} else {
+		acpi_os_printf
+		    ("    Mem:   [Alloc Free Max CurSize Outstanding Total] "
+		     "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
+		     list->total_allocated, list->total_freed,
+		     list->max_occupied, list->current_total_size, outstanding,
+		     list->total_size);
+	}
+#endif
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_enumerate_object
+ *
+ * PARAMETERS:  obj_desc            - Object to be counted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add this object to the global counts, by object type.
+ *              Limited recursion handles subobjects and packages, and this
+ *              is probably acceptable within the AML debugger only.
+ *
+ ******************************************************************************/
+
+static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc)
+{
+	u32 i;
+
+	if (!obj_desc) {
+		return;
+	}
+
+	/* Enumerate this object first */
+
+	acpi_gbl_num_objects++;
+
+	if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
+		acpi_gbl_obj_type_count_misc++;
+	} else {
+		acpi_gbl_obj_type_count[obj_desc->common.type]++;
+	}
+
+	/* Count the sub-objects */
+
+	switch (obj_desc->common.type) {
+	case ACPI_TYPE_PACKAGE:
+
+		for (i = 0; i < obj_desc->package.count; i++) {
+			acpi_db_enumerate_object(obj_desc->package.elements[i]);
+		}
+		break;
+
+	case ACPI_TYPE_DEVICE:
+
+		acpi_db_enumerate_object(obj_desc->device.notify_list[0]);
+		acpi_db_enumerate_object(obj_desc->device.notify_list[1]);
+		acpi_db_enumerate_object(obj_desc->device.handler);
+		break;
+
+	case ACPI_TYPE_BUFFER_FIELD:
+
+		if (acpi_ns_get_secondary_object(obj_desc)) {
+			acpi_gbl_obj_type_count[ACPI_TYPE_BUFFER_FIELD]++;
+		}
+		break;
+
+	case ACPI_TYPE_REGION:
+
+		acpi_gbl_obj_type_count[ACPI_TYPE_LOCAL_REGION_FIELD]++;
+		acpi_db_enumerate_object(obj_desc->region.handler);
+		break;
+
+	case ACPI_TYPE_POWER:
+
+		acpi_db_enumerate_object(obj_desc->power_resource.
+					 notify_list[0]);
+		acpi_db_enumerate_object(obj_desc->power_resource.
+					 notify_list[1]);
+		break;
+
+	case ACPI_TYPE_PROCESSOR:
+
+		acpi_db_enumerate_object(obj_desc->processor.notify_list[0]);
+		acpi_db_enumerate_object(obj_desc->processor.notify_list[1]);
+		acpi_db_enumerate_object(obj_desc->processor.handler);
+		break;
+
+	case ACPI_TYPE_THERMAL:
+
+		acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[0]);
+		acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[1]);
+		acpi_db_enumerate_object(obj_desc->thermal_zone.handler);
+		break;
+
+	default:
+
+		break;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_classify_one_object
+ *
+ * PARAMETERS:  Callback for walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
+ *              the parent namespace node.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_classify_one_object(acpi_handle obj_handle,
+			    u32 nesting_level,
+			    void *context, void **return_value)
+{
+	struct acpi_namespace_node *node;
+	union acpi_operand_object *obj_desc;
+	u32 type;
+
+	acpi_gbl_num_nodes++;
+
+	node = (struct acpi_namespace_node *)obj_handle;
+	obj_desc = acpi_ns_get_attached_object(node);
+
+	acpi_db_enumerate_object(obj_desc);
+
+	type = node->type;
+	if (type > ACPI_TYPE_NS_NODE_MAX) {
+		acpi_gbl_node_type_count_misc++;
+	} else {
+		acpi_gbl_node_type_count[type]++;
+	}
+
+	return (AE_OK);
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+
+	/* TBD: These need to be counted during the initial parsing phase */
+
+	if (acpi_ps_is_named_op(op->opcode)) {
+		num_nodes++;
+	}
+
+	if (is_method) {
+		num_method_elements++;
+	}
+
+	num_grammar_elements++;
+	op = acpi_ps_get_depth_next(root, op);
+
+	size_of_parse_tree = (num_grammar_elements - num_method_elements) *
+	    (u32)sizeof(union acpi_parse_object);
+	size_of_method_trees =
+	    num_method_elements * (u32)sizeof(union acpi_parse_object);
+	size_of_node_entries =
+	    num_nodes * (u32)sizeof(struct acpi_namespace_node);
+	size_of_acpi_objects =
+	    num_nodes * (u32)sizeof(union acpi_operand_object);
+#endif
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_count_namespace_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Count and classify the entire namespace, including all
+ *              namespace nodes and attached objects.
+ *
+ ******************************************************************************/
+
+static void acpi_db_count_namespace_objects(void)
+{
+	u32 i;
+
+	acpi_gbl_num_nodes = 0;
+	acpi_gbl_num_objects = 0;
+
+	acpi_gbl_obj_type_count_misc = 0;
+	for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX - 1); i++) {
+		acpi_gbl_obj_type_count[i] = 0;
+		acpi_gbl_node_type_count[i] = 0;
+	}
+
+	(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				     ACPI_UINT32_MAX, FALSE,
+				     acpi_db_classify_one_object, NULL, NULL,
+				     NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_statistics
+ *
+ * PARAMETERS:  type_arg        - Subcommand
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display various statistics
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_display_statistics(char *type_arg)
+{
+	u32 i;
+	u32 temp;
+
+	acpi_ut_strupr(type_arg);
+	temp = acpi_db_match_argument(type_arg, acpi_db_stat_types);
+	if (temp == ACPI_TYPE_NOT_FOUND) {
+		acpi_os_printf("Invalid or unsupported argument\n");
+		return (AE_OK);
+	}
+
+	switch (temp) {
+	case CMD_STAT_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+		acpi_ut_dump_allocation_info();
+#endif
+		break;
+
+	case CMD_STAT_TABLES:
+
+		acpi_os_printf("ACPI Table Information (not implemented):\n\n");
+		break;
+
+	case CMD_STAT_OBJECTS:
+
+		acpi_db_count_namespace_objects();
+
+		acpi_os_printf
+		    ("\nObjects defined in the current namespace:\n\n");
+
+		acpi_os_printf("%16.16s %10.10s %10.10s\n",
+			       "ACPI_TYPE", "NODES", "OBJECTS");
+
+		for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) {
+			acpi_os_printf("%16.16s % 10ld% 10ld\n",
+				       acpi_ut_get_type_name(i),
+				       acpi_gbl_node_type_count[i],
+				       acpi_gbl_obj_type_count[i]);
+		}
+		acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
+			       acpi_gbl_node_type_count_misc,
+			       acpi_gbl_obj_type_count_misc);
+
+		acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:",
+			       acpi_gbl_num_nodes, acpi_gbl_num_objects);
+		break;
+
+	case CMD_STAT_MEMORY:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+		acpi_os_printf
+		    ("\n----Object Statistics (all in hex)---------\n");
+
+		acpi_db_list_info(acpi_gbl_global_list);
+		acpi_db_list_info(acpi_gbl_ns_node_list);
+#endif
+
+#ifdef ACPI_USE_LOCAL_CACHE
+		acpi_os_printf
+		    ("\n----Cache Statistics (all in hex)---------\n");
+		acpi_db_list_info(acpi_gbl_operand_cache);
+		acpi_db_list_info(acpi_gbl_ps_node_cache);
+		acpi_db_list_info(acpi_gbl_ps_node_ext_cache);
+		acpi_db_list_info(acpi_gbl_state_cache);
+#endif
+
+		break;
+
+	case CMD_STAT_MISC:
+
+		acpi_os_printf("\nMiscellaneous Statistics:\n\n");
+		acpi_os_printf("Calls to AcpiPsFind:.. ........% 7ld\n",
+			       acpi_gbl_ps_find_count);
+		acpi_os_printf("Calls to AcpiNsLookup:..........% 7ld\n",
+			       acpi_gbl_ns_lookup_count);
+
+		acpi_os_printf("\n");
+
+		acpi_os_printf("Mutex usage:\n\n");
+		for (i = 0; i < ACPI_NUM_MUTEX; i++) {
+			acpi_os_printf("%-28s:     % 7ld\n",
+				       acpi_ut_get_mutex_name(i),
+				       acpi_gbl_mutex_info[i].use_count);
+		}
+		break;
+
+	case CMD_STAT_SIZES:
+
+		acpi_os_printf("\nInternal object sizes:\n\n");
+
+		acpi_os_printf("Common         %3d\n",
+			       sizeof(struct acpi_object_common));
+		acpi_os_printf("Number         %3d\n",
+			       sizeof(struct acpi_object_integer));
+		acpi_os_printf("String         %3d\n",
+			       sizeof(struct acpi_object_string));
+		acpi_os_printf("Buffer         %3d\n",
+			       sizeof(struct acpi_object_buffer));
+		acpi_os_printf("Package        %3d\n",
+			       sizeof(struct acpi_object_package));
+		acpi_os_printf("BufferField    %3d\n",
+			       sizeof(struct acpi_object_buffer_field));
+		acpi_os_printf("Device         %3d\n",
+			       sizeof(struct acpi_object_device));
+		acpi_os_printf("Event          %3d\n",
+			       sizeof(struct acpi_object_event));
+		acpi_os_printf("Method         %3d\n",
+			       sizeof(struct acpi_object_method));
+		acpi_os_printf("Mutex          %3d\n",
+			       sizeof(struct acpi_object_mutex));
+		acpi_os_printf("Region         %3d\n",
+			       sizeof(struct acpi_object_region));
+		acpi_os_printf("PowerResource  %3d\n",
+			       sizeof(struct acpi_object_power_resource));
+		acpi_os_printf("Processor      %3d\n",
+			       sizeof(struct acpi_object_processor));
+		acpi_os_printf("ThermalZone    %3d\n",
+			       sizeof(struct acpi_object_thermal_zone));
+		acpi_os_printf("RegionField    %3d\n",
+			       sizeof(struct acpi_object_region_field));
+		acpi_os_printf("BankField      %3d\n",
+			       sizeof(struct acpi_object_bank_field));
+		acpi_os_printf("IndexField     %3d\n",
+			       sizeof(struct acpi_object_index_field));
+		acpi_os_printf("Reference      %3d\n",
+			       sizeof(struct acpi_object_reference));
+		acpi_os_printf("Notify         %3d\n",
+			       sizeof(struct acpi_object_notify_handler));
+		acpi_os_printf("AddressSpace   %3d\n",
+			       sizeof(struct acpi_object_addr_handler));
+		acpi_os_printf("Extra          %3d\n",
+			       sizeof(struct acpi_object_extra));
+		acpi_os_printf("Data           %3d\n",
+			       sizeof(struct acpi_object_data));
+
+		acpi_os_printf("\n");
+
+		acpi_os_printf("ParseObject    %3d\n",
+			       sizeof(struct acpi_parse_obj_common));
+		acpi_os_printf("ParseObjectNamed %3d\n",
+			       sizeof(struct acpi_parse_obj_named));
+		acpi_os_printf("ParseObjectAsl %3d\n",
+			       sizeof(struct acpi_parse_obj_asl));
+		acpi_os_printf("OperandObject  %3d\n",
+			       sizeof(union acpi_operand_object));
+		acpi_os_printf("NamespaceNode  %3d\n",
+			       sizeof(struct acpi_namespace_node));
+		acpi_os_printf("AcpiObject     %3d\n",
+			       sizeof(union acpi_object));
+
+		acpi_os_printf("\n");
+
+		acpi_os_printf("Generic State  %3d\n",
+			       sizeof(union acpi_generic_state));
+		acpi_os_printf("Common State   %3d\n",
+			       sizeof(struct acpi_common_state));
+		acpi_os_printf("Control State  %3d\n",
+			       sizeof(struct acpi_control_state));
+		acpi_os_printf("Update State   %3d\n",
+			       sizeof(struct acpi_update_state));
+		acpi_os_printf("Scope State    %3d\n",
+			       sizeof(struct acpi_scope_state));
+		acpi_os_printf("Parse Scope    %3d\n",
+			       sizeof(struct acpi_pscope_state));
+		acpi_os_printf("Package State  %3d\n",
+			       sizeof(struct acpi_pkg_state));
+		acpi_os_printf("Thread State   %3d\n",
+			       sizeof(struct acpi_thread_state));
+		acpi_os_printf("Result Values  %3d\n",
+			       sizeof(struct acpi_result_values));
+		acpi_os_printf("Notify Info    %3d\n",
+			       sizeof(struct acpi_notify_info));
+		break;
+
+	case CMD_STAT_STACK:
+#if defined(ACPI_DEBUG_OUTPUT)
+
+		temp =
+		    (u32)ACPI_PTR_DIFF(acpi_gbl_entry_stack_pointer,
+				       acpi_gbl_lowest_stack_pointer);
+
+		acpi_os_printf("\nSubsystem Stack Usage:\n\n");
+		acpi_os_printf("Entry Stack Pointer        %p\n",
+			       acpi_gbl_entry_stack_pointer);
+		acpi_os_printf("Lowest Stack Pointer       %p\n",
+			       acpi_gbl_lowest_stack_pointer);
+		acpi_os_printf("Stack Use                  %X (%u)\n", temp,
+			       temp);
+		acpi_os_printf("Deepest Procedure Nesting  %u\n",
+			       acpi_gbl_deepest_nesting);
+#endif
+		break;
+
+	default:
+
+		break;
+	}
+
+	acpi_os_printf("\n");
+	return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbtest.c b/drivers/acpi/acpica/dbtest.c
new file mode 100644
index 0000000..10ea8bf
--- /dev/null
+++ b/drivers/acpi/acpica/dbtest.c
@@ -0,0 +1,1057 @@
+/*******************************************************************************
+ *
+ * Module Name: dbtest - Various debug-related tests
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+#include "acpredef.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbtest")
+
+/* Local prototypes */
+static void acpi_db_test_all_objects(void);
+
+static acpi_status
+acpi_db_test_one_object(acpi_handle obj_handle,
+			u32 nesting_level, void *context, void **return_value);
+
+static acpi_status
+acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
+
+static acpi_status
+acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
+
+static acpi_status
+acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
+
+static acpi_status
+acpi_db_read_from_object(struct acpi_namespace_node *node,
+			 acpi_object_type expected_type,
+			 union acpi_object **value);
+
+static acpi_status
+acpi_db_write_to_object(struct acpi_namespace_node *node,
+			union acpi_object *value);
+
+static void acpi_db_evaluate_all_predefined_names(char *count_arg);
+
+static acpi_status
+acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
+				     u32 nesting_level,
+				     void *context, void **return_value);
+
+/*
+ * Test subcommands
+ */
+static struct acpi_db_argument_info acpi_db_test_types[] = {
+	{"OBJECTS"},
+	{"PREDEFINED"},
+	{NULL}			/* Must be null terminated */
+};
+
+#define CMD_TEST_OBJECTS        0
+#define CMD_TEST_PREDEFINED     1
+
+#define BUFFER_FILL_VALUE       0xFF
+
+/*
+ * Support for the special debugger read/write control methods.
+ * These methods are installed into the current namespace and are
+ * used to read and write the various namespace objects. The point
+ * is to force the AML interpreter do all of the work.
+ */
+#define ACPI_DB_READ_METHOD     "\\_T98"
+#define ACPI_DB_WRITE_METHOD    "\\_T99"
+
+static acpi_handle read_handle = NULL;
+static acpi_handle write_handle = NULL;
+
+/* ASL Definitions of the debugger read/write control methods */
+
+#if 0
+definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
+{
+	method(_T98, 1, not_serialized) {	/* Read */
+		return (de_ref_of(arg0))
+	}
+}
+
+definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
+{
+	method(_T99, 2, not_serialized) {	/* Write */
+		store(arg1, arg0)
+	}
+}
+#endif
+
+static unsigned char read_method_code[] = {
+	0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00,	/* 00000000    "SSDT...." */
+	0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00,	/* 00000008    "..Intel." */
+	0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00,	/* 00000010    "DEBUG..." */
+	0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C,	/* 00000018    "....INTL" */
+	0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54,	/* 00000020    "... .._T" */
+	0x39, 0x38, 0x01, 0xA4, 0x83, 0x68	/* 00000028    "98...h"   */
+};
+
+static unsigned char write_method_code[] = {
+	0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00,	/* 00000000    "SSDT...." */
+	0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00,	/* 00000008    "..Intel." */
+	0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00,	/* 00000010    "DEBUG..." */
+	0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C,	/* 00000018    "....INTL" */
+	0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54,	/* 00000020    "... .._T" */
+	0x39, 0x39, 0x02, 0x70, 0x69, 0x68	/* 00000028    "99.pih"   */
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_test
+ *
+ * PARAMETERS:  type_arg        - Subcommand
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Execute various debug tests.
+ *
+ * Note: Code is prepared for future expansion of the TEST command.
+ *
+ ******************************************************************************/
+
+void acpi_db_execute_test(char *type_arg)
+{
+	u32 temp;
+
+	acpi_ut_strupr(type_arg);
+	temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
+	if (temp == ACPI_TYPE_NOT_FOUND) {
+		acpi_os_printf("Invalid or unsupported argument\n");
+		return;
+	}
+
+	switch (temp) {
+	case CMD_TEST_OBJECTS:
+
+		acpi_db_test_all_objects();
+		break;
+
+	case CMD_TEST_PREDEFINED:
+
+		acpi_db_evaluate_all_predefined_names(NULL);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_all_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
+ *              namespace by reading/writing/comparing all data objects such
+ *              as integers, strings, buffers, fields, buffer fields, etc.
+ *
+ ******************************************************************************/
+
+static void acpi_db_test_all_objects(void)
+{
+	acpi_status status;
+
+	/* Install the debugger read-object control method if necessary */
+
+	if (!read_handle) {
+		status = acpi_install_method(read_method_code);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf
+			    ("%s, Could not install debugger read method\n",
+			     acpi_format_exception(status));
+			return;
+		}
+
+		status =
+		    acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf
+			    ("Could not obtain handle for debug method %s\n",
+			     ACPI_DB_READ_METHOD);
+			return;
+		}
+	}
+
+	/* Install the debugger write-object control method if necessary */
+
+	if (!write_handle) {
+		status = acpi_install_method(write_method_code);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf
+			    ("%s, Could not install debugger write method\n",
+			     acpi_format_exception(status));
+			return;
+		}
+
+		status =
+		    acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf
+			    ("Could not obtain handle for debug method %s\n",
+			     ACPI_DB_WRITE_METHOD);
+			return;
+		}
+	}
+
+	/* Walk the entire namespace, testing each supported named data object */
+
+	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX, acpi_db_test_one_object,
+				  NULL, NULL, NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_one_object
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test one namespace object. Supported types are Integer,
+ *              String, Buffer, buffer_field, and field_unit. All other object
+ *              types are simply ignored.
+ *
+ *              Note: Support for Packages is not implemented.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_one_object(acpi_handle obj_handle,
+			u32 nesting_level, void *context, void **return_value)
+{
+	struct acpi_namespace_node *node;
+	union acpi_operand_object *obj_desc;
+	union acpi_operand_object *region_obj;
+	acpi_object_type local_type;
+	u32 bit_length = 0;
+	u32 byte_length = 0;
+	acpi_status status = AE_OK;
+
+	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
+	obj_desc = node->object;
+
+	/*
+	 * For the supported types, get the actual bit length or
+	 * byte length. Map the type to one of Integer/String/Buffer.
+	 */
+	switch (node->type) {
+	case ACPI_TYPE_INTEGER:
+
+		/* Integer width is either 32 or 64 */
+
+		local_type = ACPI_TYPE_INTEGER;
+		bit_length = acpi_gbl_integer_bit_width;
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		local_type = ACPI_TYPE_STRING;
+		byte_length = obj_desc->string.length;
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		local_type = ACPI_TYPE_BUFFER;
+		byte_length = obj_desc->buffer.length;
+		bit_length = byte_length * 8;
+		break;
+
+	case ACPI_TYPE_FIELD_UNIT:
+	case ACPI_TYPE_BUFFER_FIELD:
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+	case ACPI_TYPE_LOCAL_INDEX_FIELD:
+	case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+		local_type = ACPI_TYPE_INTEGER;
+		if (obj_desc) {
+			/*
+			 * Returned object will be a Buffer if the field length
+			 * is larger than the size of an Integer (32 or 64 bits
+			 * depending on the DSDT version).
+			 */
+			bit_length = obj_desc->common_field.bit_length;
+			byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
+			if (bit_length > acpi_gbl_integer_bit_width) {
+				local_type = ACPI_TYPE_BUFFER;
+			}
+		}
+		break;
+
+	default:
+
+		/* Ignore all other types */
+
+		return (AE_OK);
+	}
+
+	/* Emit the common prefix: Type:Name */
+
+	acpi_os_printf("%14s: %4.4s",
+		       acpi_ut_get_type_name(node->type), node->name.ascii);
+	if (!obj_desc) {
+		acpi_os_printf(" Ignoring, no attached object\n");
+		return (AE_OK);
+	}
+
+	/*
+	 * Check for unsupported region types. Note: acpi_exec simulates
+	 * access to system_memory, system_IO, PCI_Config, and EC.
+	 */
+	switch (node->type) {
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+		region_obj = obj_desc->field.region_obj;
+		switch (region_obj->region.space_id) {
+		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+		case ACPI_ADR_SPACE_SYSTEM_IO:
+		case ACPI_ADR_SPACE_PCI_CONFIG:
+		case ACPI_ADR_SPACE_EC:
+
+			break;
+
+		default:
+
+			acpi_os_printf
+			    ("    %s space is not supported [%4.4s]\n",
+			     acpi_ut_get_region_name(region_obj->region.
+						     space_id),
+			     region_obj->region.node->name.ascii);
+			return (AE_OK);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	/* At this point, we have resolved the object to one of the major types */
+
+	switch (local_type) {
+	case ACPI_TYPE_INTEGER:
+
+		status = acpi_db_test_integer_type(node, bit_length);
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		status = acpi_db_test_string_type(node, byte_length);
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		status = acpi_db_test_buffer_type(node, bit_length);
+		break;
+
+	default:
+
+		acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
+			       local_type);
+		break;
+	}
+
+	switch (node->type) {
+	case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+		region_obj = obj_desc->field.region_obj;
+		acpi_os_printf(" (%s)",
+			       acpi_ut_get_region_name(region_obj->region.
+						       space_id));
+		break;
+
+	default:
+		break;
+	}
+
+	acpi_os_printf("\n");
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_integer_type
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              bit_length          - Actual length of the object. Used for
+ *                                    support of arbitrary length field_unit
+ *                                    and buffer_field objects.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
+ *              write/read/compare of an arbitrary new value, then performs
+ *              a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
+{
+	union acpi_object *temp1 = NULL;
+	union acpi_object *temp2 = NULL;
+	union acpi_object *temp3 = NULL;
+	union acpi_object write_value;
+	u64 value_to_write;
+	acpi_status status;
+
+	if (bit_length > 64) {
+		acpi_os_printf(" Invalid length for an Integer: %u",
+			       bit_length);
+		return (AE_OK);
+	}
+
+	/* Read the original value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	acpi_os_printf(" (%4.4X/%3.3X) %8.8X%8.8X",
+		       bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
+		       ACPI_FORMAT_UINT64(temp1->integer.value));
+
+	value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
+	if (temp1->integer.value == value_to_write) {
+		value_to_write = 0;
+	}
+
+	/* Write a new value */
+
+	write_value.type = ACPI_TYPE_INTEGER;
+	write_value.integer.value = value_to_write;
+	status = acpi_db_write_to_object(node, &write_value);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Ensure that we can read back the new value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	if (temp2->integer.value != value_to_write) {
+		acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
+			       ACPI_FORMAT_UINT64(temp2->integer.value),
+			       ACPI_FORMAT_UINT64(value_to_write));
+	}
+
+	/* Write back the original value */
+
+	write_value.integer.value = temp1->integer.value;
+	status = acpi_db_write_to_object(node, &write_value);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Ensure that we can read back the original value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	if (temp3->integer.value != temp1->integer.value) {
+		acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
+			       ACPI_FORMAT_UINT64(temp3->integer.value),
+			       ACPI_FORMAT_UINT64(temp1->integer.value));
+	}
+
+exit:
+	if (temp1) {
+		acpi_os_free(temp1);
+	}
+	if (temp2) {
+		acpi_os_free(temp2);
+	}
+	if (temp3) {
+		acpi_os_free(temp3);
+	}
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_buffer_type
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              bit_length          - Actual length of the object.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
+ *              write/read/compare of an arbitrary new value, then performs
+ *              a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
+{
+	union acpi_object *temp1 = NULL;
+	union acpi_object *temp2 = NULL;
+	union acpi_object *temp3 = NULL;
+	u8 *buffer;
+	union acpi_object write_value;
+	acpi_status status;
+	u32 byte_length;
+	u32 i;
+	u8 extra_bits;
+
+	byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
+	if (byte_length == 0) {
+		acpi_os_printf(" Ignoring zero length buffer");
+		return (AE_OK);
+	}
+
+	/* Allocate a local buffer */
+
+	buffer = ACPI_ALLOCATE_ZEROED(byte_length);
+	if (!buffer) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Read the original value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Emit a few bytes of the buffer */
+
+	acpi_os_printf(" (%4.4X/%3.3X)", bit_length, temp1->buffer.length);
+	for (i = 0; ((i < 4) && (i < byte_length)); i++) {
+		acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
+	}
+	acpi_os_printf("... ");
+
+	/*
+	 * Write a new value.
+	 *
+	 * Handle possible extra bits at the end of the buffer. Can
+	 * happen for field_units larger than an integer, but the bit
+	 * count is not an integral number of bytes. Zero out the
+	 * unused bits.
+	 */
+	memset(buffer, BUFFER_FILL_VALUE, byte_length);
+	extra_bits = bit_length % 8;
+	if (extra_bits) {
+		buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
+	}
+
+	write_value.type = ACPI_TYPE_BUFFER;
+	write_value.buffer.length = byte_length;
+	write_value.buffer.pointer = buffer;
+
+	status = acpi_db_write_to_object(node, &write_value);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Ensure that we can read back the new value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
+		acpi_os_printf(" MISMATCH 2: New buffer value");
+	}
+
+	/* Write back the original value */
+
+	write_value.buffer.length = byte_length;
+	write_value.buffer.pointer = temp1->buffer.pointer;
+
+	status = acpi_db_write_to_object(node, &write_value);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Ensure that we can read back the original value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
+		acpi_os_printf(" MISMATCH 3: While restoring original buffer");
+	}
+
+exit:
+	ACPI_FREE(buffer);
+	if (temp1) {
+		acpi_os_free(temp1);
+	}
+	if (temp2) {
+		acpi_os_free(temp2);
+	}
+	if (temp3) {
+		acpi_os_free(temp3);
+	}
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_string_type
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              byte_length         - Actual length of the object.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test read/write for an String-valued object. Performs a
+ *              write/read/compare of an arbitrary new value, then performs
+ *              a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
+{
+	union acpi_object *temp1 = NULL;
+	union acpi_object *temp2 = NULL;
+	union acpi_object *temp3 = NULL;
+	char *value_to_write = "Test String from AML Debugger";
+	union acpi_object write_value;
+	acpi_status status;
+
+	/* Read the original value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	acpi_os_printf(" (%4.4X/%3.3X) \"%s\"", (temp1->string.length * 8),
+		       temp1->string.length, temp1->string.pointer);
+
+	/* Write a new value */
+
+	write_value.type = ACPI_TYPE_STRING;
+	write_value.string.length = strlen(value_to_write);
+	write_value.string.pointer = value_to_write;
+
+	status = acpi_db_write_to_object(node, &write_value);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Ensure that we can read back the new value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	if (strcmp(temp2->string.pointer, value_to_write)) {
+		acpi_os_printf(" MISMATCH 2: %s, expecting %s",
+			       temp2->string.pointer, value_to_write);
+	}
+
+	/* Write back the original value */
+
+	write_value.string.length = strlen(temp1->string.pointer);
+	write_value.string.pointer = temp1->string.pointer;
+
+	status = acpi_db_write_to_object(node, &write_value);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Ensure that we can read back the original value */
+
+	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
+		acpi_os_printf(" MISMATCH 3: %s, expecting %s",
+			       temp3->string.pointer, temp1->string.pointer);
+	}
+
+exit:
+	if (temp1) {
+		acpi_os_free(temp1);
+	}
+	if (temp2) {
+		acpi_os_free(temp2);
+	}
+	if (temp3) {
+		acpi_os_free(temp3);
+	}
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_read_from_object
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              expected_type       - Object type expected from the read
+ *              value               - Where the value read is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Performs a read from the specified object by invoking the
+ *              special debugger control method that reads the object. Thus,
+ *              the AML interpreter is doing all of the work, increasing the
+ *              validity of the test.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_read_from_object(struct acpi_namespace_node *node,
+			 acpi_object_type expected_type,
+			 union acpi_object **value)
+{
+	union acpi_object *ret_value;
+	struct acpi_object_list param_objects;
+	union acpi_object params[2];
+	struct acpi_buffer return_obj;
+	acpi_status status;
+
+	params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
+	params[0].reference.actual_type = node->type;
+	params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
+
+	param_objects.count = 1;
+	param_objects.pointer = params;
+
+	return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+	acpi_gbl_method_executing = TRUE;
+	status = acpi_evaluate_object(read_handle, NULL,
+				      &param_objects, &return_obj);
+	acpi_gbl_method_executing = FALSE;
+
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not read from object, %s",
+			       acpi_format_exception(status));
+		return (status);
+	}
+
+	ret_value = (union acpi_object *)return_obj.pointer;
+
+	switch (ret_value->type) {
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_BUFFER:
+	case ACPI_TYPE_STRING:
+		/*
+		 * Did we receive the type we wanted? Most important for the
+		 * Integer/Buffer case (when a field is larger than an Integer,
+		 * it should return a Buffer).
+		 */
+		if (ret_value->type != expected_type) {
+			acpi_os_printf
+			    (" Type mismatch: Expected %s, Received %s",
+			     acpi_ut_get_type_name(expected_type),
+			     acpi_ut_get_type_name(ret_value->type));
+
+			return (AE_TYPE);
+		}
+
+		*value = ret_value;
+		break;
+
+	default:
+
+		acpi_os_printf(" Unsupported return object type, %s",
+			       acpi_ut_get_type_name(ret_value->type));
+
+		acpi_os_free(return_obj.pointer);
+		return (AE_TYPE);
+	}
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_write_to_object
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              value               - Value to be written
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Performs a write to the specified object by invoking the
+ *              special debugger control method that writes the object. Thus,
+ *              the AML interpreter is doing all of the work, increasing the
+ *              validity of the test.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_write_to_object(struct acpi_namespace_node *node,
+			union acpi_object *value)
+{
+	struct acpi_object_list param_objects;
+	union acpi_object params[2];
+	acpi_status status;
+
+	params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
+	params[0].reference.actual_type = node->type;
+	params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
+
+	/* Copy the incoming user parameter */
+
+	memcpy(&params[1], value, sizeof(union acpi_object));
+
+	param_objects.count = 2;
+	param_objects.pointer = params;
+
+	acpi_gbl_method_executing = TRUE;
+	status = acpi_evaluate_object(write_handle, NULL, &param_objects, NULL);
+	acpi_gbl_method_executing = FALSE;
+
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not write to object, %s",
+			       acpi_format_exception(status));
+	}
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_evaluate_all_predefined_names
+ *
+ * PARAMETERS:  count_arg           - Max number of methods to execute
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Namespace batch execution. Execute predefined names in the
+ *              namespace, up to the max count, if specified.
+ *
+ ******************************************************************************/
+
+static void acpi_db_evaluate_all_predefined_names(char *count_arg)
+{
+	struct acpi_db_execute_walk info;
+
+	info.count = 0;
+	info.max_count = ACPI_UINT32_MAX;
+
+	if (count_arg) {
+		info.max_count = strtoul(count_arg, NULL, 0);
+	}
+
+	/* Search all nodes in namespace */
+
+	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+				  ACPI_UINT32_MAX,
+				  acpi_db_evaluate_one_predefined_name, NULL,
+				  (void *)&info, NULL);
+
+	acpi_os_printf("Evaluated %u predefined names in the namespace\n",
+		       info.count);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_evaluate_one_predefined_name
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Batch execution module. Currently only executes predefined
+ *              ACPI names.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
+				     u32 nesting_level,
+				     void *context, void **return_value)
+{
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+	struct acpi_db_execute_walk *info =
+	    (struct acpi_db_execute_walk *)context;
+	char *pathname;
+	const union acpi_predefined_info *predefined;
+	struct acpi_device_info *obj_info;
+	struct acpi_object_list param_objects;
+	union acpi_object params[ACPI_METHOD_NUM_ARGS];
+	union acpi_object *this_param;
+	struct acpi_buffer return_obj;
+	acpi_status status;
+	u16 arg_type_list;
+	u8 arg_count;
+	u8 arg_type;
+	u32 i;
+
+	/* The name must be a predefined ACPI name */
+
+	predefined = acpi_ut_match_predefined_method(node->name.ascii);
+	if (!predefined) {
+		return (AE_OK);
+	}
+
+	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
+		return (AE_OK);
+	}
+
+	pathname = acpi_ns_get_external_pathname(node);
+	if (!pathname) {
+		return (AE_OK);
+	}
+
+	/* Get the object info for number of method parameters */
+
+	status = acpi_get_object_info(obj_handle, &obj_info);
+	if (ACPI_FAILURE(status)) {
+		ACPI_FREE(pathname);
+		return (status);
+	}
+
+	param_objects.count = 0;
+	param_objects.pointer = NULL;
+
+	if (obj_info->type == ACPI_TYPE_METHOD) {
+
+		/* Setup default parameters (with proper types) */
+
+		arg_type_list = predefined->info.argument_list;
+		arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
+
+		/*
+		 * Setup the ACPI-required number of arguments, regardless of what
+		 * the actual method defines. If there is a difference, then the
+		 * method is wrong and a warning will be issued during execution.
+		 */
+		this_param = params;
+		for (i = 0; i < arg_count; i++) {
+			arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
+			this_param->type = arg_type;
+
+			switch (arg_type) {
+			case ACPI_TYPE_INTEGER:
+
+				this_param->integer.value = 1;
+				break;
+
+			case ACPI_TYPE_STRING:
+
+				this_param->string.pointer =
+				    "This is the default argument string";
+				this_param->string.length =
+				    strlen(this_param->string.pointer);
+				break;
+
+			case ACPI_TYPE_BUFFER:
+
+				this_param->buffer.pointer = (u8 *)params;	/* just a garbage buffer */
+				this_param->buffer.length = 48;
+				break;
+
+			case ACPI_TYPE_PACKAGE:
+
+				this_param->package.elements = NULL;
+				this_param->package.count = 0;
+				break;
+
+			default:
+
+				acpi_os_printf
+				    ("%s: Unsupported argument type: %u\n",
+				     pathname, arg_type);
+				break;
+			}
+
+			this_param++;
+		}
+
+		param_objects.count = arg_count;
+		param_objects.pointer = params;
+	}
+
+	ACPI_FREE(obj_info);
+	return_obj.pointer = NULL;
+	return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+	/* Do the actual method execution */
+
+	acpi_gbl_method_executing = TRUE;
+
+	status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
+
+	acpi_os_printf("%-32s returned %s\n",
+		       pathname, acpi_format_exception(status));
+	acpi_gbl_method_executing = FALSE;
+	ACPI_FREE(pathname);
+
+	/* Ignore status from method execution */
+
+	status = AE_OK;
+
+	/* Update count, check if we have executed enough methods */
+
+	info->count++;
+	if (info->count >= info->max_count) {
+		status = AE_CTRL_TERMINATE;
+	}
+
+	return (status);
+}
diff --git a/drivers/acpi/acpica/dbutils.c b/drivers/acpi/acpica/dbutils.c
new file mode 100644
index 0000000..86790e0
--- /dev/null
+++ b/drivers/acpi/acpica/dbutils.c
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ *
+ * Module Name: dbutils - AML debugger utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbutils")
+
+/* Local prototypes */
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root);
+
+void acpi_db_dump_buffer(u32 address);
+#endif
+
+static char *gbl_hex_to_ascii = "0123456789ABCDEF";
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_match_argument
+ *
+ * PARAMETERS:  user_argument           - User command line
+ *              arguments               - Array of commands to match against
+ *
+ * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+acpi_object_type
+acpi_db_match_argument(char *user_argument,
+		       struct acpi_db_argument_info *arguments)
+{
+	u32 i;
+
+	if (!user_argument || user_argument[0] == 0) {
+		return (ACPI_TYPE_NOT_FOUND);
+	}
+
+	for (i = 0; arguments[i].name; i++) {
+		if (strstr(arguments[i].name, user_argument) ==
+		    arguments[i].name) {
+			return (i);
+		}
+	}
+
+	/* Argument not recognized */
+
+	return (ACPI_TYPE_NOT_FOUND);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_output_destination
+ *
+ * PARAMETERS:  output_flags        - Current flags word
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set the current destination for debugger output. Also sets
+ *              the debug output level accordingly.
+ *
+ ******************************************************************************/
+
+void acpi_db_set_output_destination(u32 output_flags)
+{
+
+	acpi_gbl_db_output_flags = (u8)output_flags;
+
+	if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) &&
+	    acpi_gbl_db_output_to_file) {
+		acpi_dbg_level = acpi_gbl_db_debug_level;
+	} else {
+		acpi_dbg_level = acpi_gbl_db_console_debug_level;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_external_object
+ *
+ * PARAMETERS:  obj_desc        - External ACPI object to dump
+ *              level           - Nesting level.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump the contents of an ACPI external object
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level)
+{
+	u32 i;
+
+	if (!obj_desc) {
+		acpi_os_printf("[Null Object]\n");
+		return;
+	}
+
+	for (i = 0; i < level; i++) {
+		acpi_os_printf(" ");
+	}
+
+	switch (obj_desc->type) {
+	case ACPI_TYPE_ANY:
+
+		acpi_os_printf("[Null Object] (Type=0)\n");
+		break;
+
+	case ACPI_TYPE_INTEGER:
+
+		acpi_os_printf("[Integer] = %8.8X%8.8X\n",
+			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		acpi_os_printf("[String] Length %.2X = ",
+			       obj_desc->string.length);
+		acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
+		acpi_os_printf("\n");
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		acpi_os_printf("[Buffer] Length %.2X = ",
+			       obj_desc->buffer.length);
+		if (obj_desc->buffer.length) {
+			if (obj_desc->buffer.length > 16) {
+				acpi_os_printf("\n");
+			}
+			acpi_ut_debug_dump_buffer(ACPI_CAST_PTR
+						  (u8,
+						   obj_desc->buffer.pointer),
+						  obj_desc->buffer.length,
+						  DB_BYTE_DISPLAY, _COMPONENT);
+		} else {
+			acpi_os_printf("\n");
+		}
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+
+		acpi_os_printf("[Package] Contains %u Elements:\n",
+			       obj_desc->package.count);
+
+		for (i = 0; i < obj_desc->package.count; i++) {
+			acpi_db_dump_external_object(&obj_desc->package.
+						     elements[i], level + 1);
+		}
+		break;
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		acpi_os_printf("[Object Reference] = ");
+		acpi_db_display_internal_object(obj_desc->reference.handle,
+						NULL);
+		break;
+
+	case ACPI_TYPE_PROCESSOR:
+
+		acpi_os_printf("[Processor]\n");
+		break;
+
+	case ACPI_TYPE_POWER:
+
+		acpi_os_printf("[Power Resource]\n");
+		break;
+
+	default:
+
+		acpi_os_printf("[Unknown Type] %X\n", obj_desc->type);
+		break;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_prep_namestring
+ *
+ * PARAMETERS:  name            - String to prepare
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Translate all forward slashes and dots to backslashes.
+ *
+ ******************************************************************************/
+
+void acpi_db_prep_namestring(char *name)
+{
+
+	if (!name) {
+		return;
+	}
+
+	acpi_ut_strupr(name);
+
+	/* Convert a leading forward slash to a backslash */
+
+	if (*name == '/') {
+		*name = '\\';
+	}
+
+	/* Ignore a leading backslash, this is the root prefix */
+
+	if (ACPI_IS_ROOT_PREFIX(*name)) {
+		name++;
+	}
+
+	/* Convert all slash path separators to dots */
+
+	while (*name) {
+		if ((*name == '/') || (*name == '\\')) {
+			*name = '.';
+		}
+
+		name++;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_local_ns_lookup
+ *
+ * PARAMETERS:  name            - Name to lookup
+ *
+ * RETURN:      Pointer to a namespace node, null on failure
+ *
+ * DESCRIPTION: Lookup a name in the ACPI namespace
+ *
+ * Note: Currently begins search from the root. Could be enhanced to use
+ * the current prefix (scope) node as the search beginning point.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name)
+{
+	char *internal_path;
+	acpi_status status;
+	struct acpi_namespace_node *node = NULL;
+
+	acpi_db_prep_namestring(name);
+
+	/* Build an internal namestring */
+
+	status = acpi_ns_internalize_name(name, &internal_path);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Invalid namestring: %s\n", name);
+		return (NULL);
+	}
+
+	/*
+	 * Lookup the name.
+	 * (Uses root node as the search starting point)
+	 */
+	status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
+				ACPI_IMODE_EXECUTE,
+				ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
+				NULL, &node);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not locate name: %s, %s\n",
+			       name, acpi_format_exception(status));
+	}
+
+	ACPI_FREE(internal_path);
+	return (node);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_uint32_to_hex_string
+ *
+ * PARAMETERS:  value           - The value to be converted to string
+ *              buffer          - Buffer for result (not less than 11 bytes)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
+ *
+ * NOTE: It is the caller's responsibility to ensure that the length of buffer
+ *       is sufficient.
+ *
+ ******************************************************************************/
+
+void acpi_db_uint32_to_hex_string(u32 value, char *buffer)
+{
+	int i;
+
+	if (value == 0) {
+		strcpy(buffer, "0");
+		return;
+	}
+
+	buffer[8] = '\0';
+
+	for (i = 7; i >= 0; i--) {
+		buffer[i] = gbl_hex_to_ascii[value & 0x0F];
+		value = value >> 4;
+	}
+}
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_second_pass_parse
+ *
+ * PARAMETERS:  root            - Root of the parse tree
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
+ *              second pass to parse the control methods
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root)
+{
+	union acpi_parse_object *op = root;
+	union acpi_parse_object *method;
+	union acpi_parse_object *search_op;
+	union acpi_parse_object *start_op;
+	acpi_status status = AE_OK;
+	u32 base_aml_offset;
+	struct acpi_walk_state *walk_state;
+
+	ACPI_FUNCTION_ENTRY();
+
+	acpi_os_printf("Pass two parse ....\n");
+
+	while (op) {
+		if (op->common.aml_opcode == AML_METHOD_OP) {
+			method = op;
+
+			/* Create a new walk state for the parse */
+
+			walk_state =
+			    acpi_ds_create_walk_state(0, NULL, NULL, NULL);
+			if (!walk_state) {
+				return (AE_NO_MEMORY);
+			}
+
+			/* Init the Walk State */
+
+			walk_state->parser_state.aml =
+			    walk_state->parser_state.aml_start =
+			    method->named.data;
+			walk_state->parser_state.aml_end =
+			    walk_state->parser_state.pkg_end =
+			    method->named.data + method->named.length;
+			walk_state->parser_state.start_scope = op;
+
+			walk_state->descending_callback =
+			    acpi_ds_load1_begin_op;
+			walk_state->ascending_callback = acpi_ds_load1_end_op;
+
+			/* Perform the AML parse */
+
+			status = acpi_ps_parse_aml(walk_state);
+
+			base_aml_offset =
+			    (method->common.value.arg)->common.aml_offset + 1;
+			start_op = (method->common.value.arg)->common.next;
+			search_op = start_op;
+
+			while (search_op) {
+				search_op->common.aml_offset += base_aml_offset;
+				search_op =
+				    acpi_ps_get_depth_next(start_op, search_op);
+			}
+		}
+
+		if (op->common.aml_opcode == AML_REGION_OP) {
+
+			/* TBD: [Investigate] this isn't quite the right thing to do! */
+			/*
+			 *
+			 * Method = (ACPI_DEFERRED_OP *) Op;
+			 * Status = acpi_ps_parse_aml (Op, Method->Body, Method->body_length);
+			 */
+		}
+
+		if (ACPI_FAILURE(status)) {
+			break;
+		}
+
+		op = acpi_ps_get_depth_next(root, op);
+	}
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_buffer
+ *
+ * PARAMETERS:  address             - Pointer to the buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print a portion of a buffer
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_buffer(u32 address)
+{
+
+	acpi_os_printf("\nLocation %X:\n", address);
+
+	acpi_dbg_level |= ACPI_LV_TABLES;
+	acpi_ut_debug_dump_buffer(ACPI_TO_POINTER(address), 64, DB_BYTE_DISPLAY,
+				  ACPI_UINT32_MAX);
+}
+#endif
diff --git a/drivers/acpi/acpica/dbxface.c b/drivers/acpi/acpica/dbxface.c
new file mode 100644
index 0000000..342298a
--- /dev/null
+++ b/drivers/acpi/acpica/dbxface.c
@@ -0,0 +1,513 @@
+/*******************************************************************************
+ *
+ * Module Name: dbxface - AML Debugger external interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbxface")
+
+/* Local prototypes */
+static acpi_status
+acpi_db_start_command(struct acpi_walk_state *walk_state,
+		      union acpi_parse_object *op);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void acpi_db_method_end(struct acpi_walk_state *walk_state);
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_start_command
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *              op              - Current executing Op, from AML interpreter
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enter debugger command loop
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_start_command(struct acpi_walk_state *walk_state,
+		      union acpi_parse_object *op)
+{
+	acpi_status status;
+
+	/* TBD: [Investigate] are there namespace locking issues here? */
+
+	/* acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */
+
+	/* Go into the command loop and await next user command */
+
+	acpi_gbl_method_executing = TRUE;
+	status = AE_CTRL_TRUE;
+	while (status == AE_CTRL_TRUE) {
+		if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) {
+
+			/* Handshake with the front-end that gets user command lines */
+
+			acpi_os_release_mutex(acpi_gbl_db_command_complete);
+
+			status =
+			    acpi_os_acquire_mutex(acpi_gbl_db_command_ready,
+						  ACPI_WAIT_FOREVER);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+		} else {
+			/* Single threaded, we must get a command line ourselves */
+
+			/* Force output to console until a command is entered */
+
+			acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+
+			/* Different prompt if method is executing */
+
+			if (!acpi_gbl_method_executing) {
+				acpi_os_printf("%1c ",
+					       ACPI_DEBUGGER_COMMAND_PROMPT);
+			} else {
+				acpi_os_printf("%1c ",
+					       ACPI_DEBUGGER_EXECUTE_PROMPT);
+			}
+
+			/* Get the user input line */
+
+			status = acpi_os_get_line(acpi_gbl_db_line_buf,
+						  ACPI_DB_LINE_BUFFER_SIZE,
+						  NULL);
+			if (ACPI_FAILURE(status)) {
+				ACPI_EXCEPTION((AE_INFO, status,
+						"While parsing command line"));
+				return (status);
+			}
+		}
+
+		status =
+		    acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state,
+					     op);
+	}
+
+	/* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_single_step
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *              op              - Current executing op (from aml interpreter)
+ *              opcode_class    - Class of the current AML Opcode
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called just before execution of an AML opcode.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_single_step(struct acpi_walk_state * walk_state,
+		    union acpi_parse_object * op, u32 opcode_class)
+{
+	union acpi_parse_object *next;
+	acpi_status status = AE_OK;
+	u32 original_debug_level;
+	union acpi_parse_object *display_op;
+	union acpi_parse_object *parent_op;
+	u32 aml_offset;
+
+	ACPI_FUNCTION_ENTRY();
+
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return (AE_OK);
+	}
+#endif
+
+	/* Check the abort flag */
+
+	if (acpi_gbl_abort_method) {
+		acpi_gbl_abort_method = FALSE;
+		return (AE_ABORT_METHOD);
+	}
+
+	aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
+					walk_state->parser_state.aml_start);
+
+	/* Check for single-step breakpoint */
+
+	if (walk_state->method_breakpoint &&
+	    (walk_state->method_breakpoint <= aml_offset)) {
+
+		/* Check if the breakpoint has been reached or passed */
+		/* Hit the breakpoint, resume single step, reset breakpoint */
+
+		acpi_os_printf("***Break*** at AML offset %X\n", aml_offset);
+		acpi_gbl_cm_single_step = TRUE;
+		acpi_gbl_step_to_next_call = FALSE;
+		walk_state->method_breakpoint = 0;
+	}
+
+	/* Check for user breakpoint (Must be on exact Aml offset) */
+
+	else if (walk_state->user_breakpoint &&
+		 (walk_state->user_breakpoint == aml_offset)) {
+		acpi_os_printf("***UserBreakpoint*** at AML offset %X\n",
+			       aml_offset);
+		acpi_gbl_cm_single_step = TRUE;
+		acpi_gbl_step_to_next_call = FALSE;
+		walk_state->method_breakpoint = 0;
+	}
+
+	/*
+	 * Check if this is an opcode that we are interested in --
+	 * namely, opcodes that have arguments
+	 */
+	if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
+		return (AE_OK);
+	}
+
+	switch (opcode_class) {
+	case AML_CLASS_UNKNOWN:
+	case AML_CLASS_ARGUMENT:	/* constants, literals, etc. do nothing */
+
+		return (AE_OK);
+
+	default:
+
+		/* All other opcodes -- continue */
+		break;
+	}
+
+	/*
+	 * Under certain debug conditions, display this opcode and its operands
+	 */
+	if ((acpi_gbl_db_output_to_file) ||
+	    (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) {
+		if ((acpi_gbl_db_output_to_file) ||
+		    (acpi_dbg_level & ACPI_LV_PARSE)) {
+			acpi_os_printf
+			    ("\n[AmlDebug] Next AML Opcode to execute:\n");
+		}
+
+		/*
+		 * Display this op (and only this op - zero out the NEXT field
+		 * temporarily, and disable parser trace output for the duration of
+		 * the display because we don't want the extraneous debug output)
+		 */
+		original_debug_level = acpi_dbg_level;
+		acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
+		next = op->common.next;
+		op->common.next = NULL;
+
+		display_op = op;
+		parent_op = op->common.parent;
+		if (parent_op) {
+			if ((walk_state->control_state) &&
+			    (walk_state->control_state->common.state ==
+			     ACPI_CONTROL_PREDICATE_EXECUTING)) {
+				/*
+				 * We are executing the predicate of an IF or WHILE statement
+				 * Search upwards for the containing IF or WHILE so that the
+				 * entire predicate can be displayed.
+				 */
+				while (parent_op) {
+					if ((parent_op->common.aml_opcode ==
+					     AML_IF_OP)
+					    || (parent_op->common.aml_opcode ==
+						AML_WHILE_OP)) {
+						display_op = parent_op;
+						break;
+					}
+					parent_op = parent_op->common.parent;
+				}
+			} else {
+				while (parent_op) {
+					if ((parent_op->common.aml_opcode ==
+					     AML_IF_OP)
+					    || (parent_op->common.aml_opcode ==
+						AML_ELSE_OP)
+					    || (parent_op->common.aml_opcode ==
+						AML_SCOPE_OP)
+					    || (parent_op->common.aml_opcode ==
+						AML_METHOD_OP)
+					    || (parent_op->common.aml_opcode ==
+						AML_WHILE_OP)) {
+						break;
+					}
+					display_op = parent_op;
+					parent_op = parent_op->common.parent;
+				}
+			}
+		}
+
+		/* Now we can display it */
+
+#ifdef ACPI_DISASSEMBLER
+		acpi_dm_disassemble(walk_state, display_op, ACPI_UINT32_MAX);
+#endif
+
+		if ((op->common.aml_opcode == AML_IF_OP) ||
+		    (op->common.aml_opcode == AML_WHILE_OP)) {
+			if (walk_state->control_state->common.value) {
+				acpi_os_printf
+				    ("Predicate = [True], IF block was executed\n");
+			} else {
+				acpi_os_printf
+				    ("Predicate = [False], Skipping IF block\n");
+			}
+		} else if (op->common.aml_opcode == AML_ELSE_OP) {
+			acpi_os_printf
+			    ("Predicate = [False], ELSE block was executed\n");
+		}
+
+		/* Restore everything */
+
+		op->common.next = next;
+		acpi_os_printf("\n");
+		if ((acpi_gbl_db_output_to_file) ||
+		    (acpi_dbg_level & ACPI_LV_PARSE)) {
+			acpi_os_printf("\n");
+		}
+		acpi_dbg_level = original_debug_level;
+	}
+
+	/* If we are not single stepping, just continue executing the method */
+
+	if (!acpi_gbl_cm_single_step) {
+		return (AE_OK);
+	}
+
+	/*
+	 * If we are executing a step-to-call command,
+	 * Check if this is a method call.
+	 */
+	if (acpi_gbl_step_to_next_call) {
+		if (op->common.aml_opcode != AML_INT_METHODCALL_OP) {
+
+			/* Not a method call, just keep executing */
+
+			return (AE_OK);
+		}
+
+		/* Found a method call, stop executing */
+
+		acpi_gbl_step_to_next_call = FALSE;
+	}
+
+	/*
+	 * If the next opcode is a method call, we will "step over" it
+	 * by default.
+	 */
+	if (op->common.aml_opcode == AML_INT_METHODCALL_OP) {
+
+		/* Force no more single stepping while executing called method */
+
+		acpi_gbl_cm_single_step = FALSE;
+
+		/*
+		 * Set the breakpoint on/before the call, it will stop execution
+		 * as soon as we return
+		 */
+		walk_state->method_breakpoint = 1;	/* Must be non-zero! */
+	}
+
+	status = acpi_db_start_command(walk_state, op);
+
+	/* User commands complete, continue execution of the interrupted method */
+
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_debugger
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Init and start debugger
+ *
+ ******************************************************************************/
+
+acpi_status acpi_initialize_debugger(void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(acpi_initialize_debugger);
+
+	/* Init globals */
+
+	acpi_gbl_db_buffer = NULL;
+	acpi_gbl_db_filename = NULL;
+	acpi_gbl_db_output_to_file = FALSE;
+
+	acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2;
+	acpi_gbl_db_console_debug_level = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
+	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+
+	acpi_gbl_db_opt_no_ini_methods = FALSE;
+
+	acpi_gbl_db_buffer = acpi_os_allocate(ACPI_DEBUG_BUFFER_SIZE);
+	if (!acpi_gbl_db_buffer) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+	memset(acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE);
+
+	/* Initial scope is the root */
+
+	acpi_gbl_db_scope_buf[0] = AML_ROOT_PREFIX;
+	acpi_gbl_db_scope_buf[1] = 0;
+	acpi_gbl_db_scope_node = acpi_gbl_root_node;
+
+	/* Initialize user commands loop */
+
+	acpi_gbl_db_terminate_loop = FALSE;
+
+	/*
+	 * If configured for multi-thread support, the debug executor runs in
+	 * a separate thread so that the front end can be in another address
+	 * space, environment, or even another machine.
+	 */
+	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+
+		/* These were created with one unit, grab it */
+
+		status = acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
+					       ACPI_WAIT_FOREVER);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not get debugger mutex\n");
+			return_ACPI_STATUS(status);
+		}
+
+		status = acpi_os_acquire_mutex(acpi_gbl_db_command_ready,
+					       ACPI_WAIT_FOREVER);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not get debugger mutex\n");
+			return_ACPI_STATUS(status);
+		}
+
+		/* Create the debug execution thread to execute commands */
+
+		acpi_gbl_db_threads_terminated = FALSE;
+		status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
+					 acpi_db_execute_thread, NULL);
+		if (ACPI_FAILURE(status)) {
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not start debugger thread"));
+			acpi_gbl_db_threads_terminated = TRUE;
+			return_ACPI_STATUS(status);
+		}
+	} else {
+		acpi_gbl_db_thread_id = acpi_os_get_thread_id();
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_initialize_debugger)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_terminate_debugger
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Stop debugger
+ *
+ ******************************************************************************/
+void acpi_terminate_debugger(void)
+{
+
+	/* Terminate the AML Debugger */
+
+	acpi_gbl_db_terminate_loop = TRUE;
+
+	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+		acpi_os_release_mutex(acpi_gbl_db_command_ready);
+
+		/* Wait the AML Debugger threads */
+
+		while (!acpi_gbl_db_threads_terminated) {
+			acpi_os_sleep(100);
+		}
+	}
+
+	if (acpi_gbl_db_buffer) {
+		acpi_os_free(acpi_gbl_db_buffer);
+		acpi_gbl_db_buffer = NULL;
+	}
+
+	/* Ensure that debug output is now disabled */
+
+	acpi_gbl_db_output_flags = ACPI_DB_DISABLE_OUTPUT;
+}
+
+ACPI_EXPORT_SYMBOL(acpi_terminate_debugger)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_set_debugger_thread_id
+ *
+ * PARAMETERS:  thread_id       - Debugger thread ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set debugger thread ID
+ *
+ ******************************************************************************/
+void acpi_set_debugger_thread_id(acpi_thread_id thread_id)
+{
+	acpi_gbl_db_thread_id = thread_id;
+}
+
+ACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id)
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 81f2d9e..07d22bf 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -405,7 +405,7 @@
 }
 
 ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
-#endif				/*  ACPI_FUTURE_USAGE  */
+#endif
 
 #if (!ACPI_REDUCED_HARDWARE)
 /*******************************************************************************
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index 075d654..1e4c5b6 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -618,6 +618,7 @@
 		break;
 
 	case ARGI_TARGETREF:
+	case ARGI_STORE_TARGET:
 
 		switch (destination_type) {
 		case ACPI_TYPE_INTEGER:
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index 7b10912..a1afe1a 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -209,7 +209,6 @@
 					 * (i.e., dereference the package index)
 					 * Delete the ref object, increment the returned object
 					 */
-					acpi_ut_remove_reference(stack_desc);
 					acpi_ut_add_reference(obj_desc);
 					*stack_ptr = obj_desc;
 				} else {
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index d2964af..424442d 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -307,6 +307,8 @@
 		case ARGI_TARGETREF:	/* Allows implicit conversion rules before store */
 		case ARGI_FIXED_TARGET:	/* No implicit conversion before store to target */
 		case ARGI_SIMPLE_TARGET:	/* Name, Local, or arg - no implicit conversion  */
+		case ARGI_STORE_TARGET:
+
 			/*
 			 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
 			 * A Namespace Node is OK as-is
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index a7eee24..c076e91 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -137,7 +137,7 @@
 		/* Destination is not a Reference object */
 
 		ACPI_ERROR((AE_INFO,
-			    "Target is not a Reference or Constant object - %s [%p]",
+			    "Target is not a Reference or Constant object - [%s] %p",
 			    acpi_ut_get_object_type_name(dest_desc),
 			    dest_desc));
 
@@ -189,7 +189,7 @@
 		 * displayed and otherwise has no effect -- see ACPI Specification
 		 */
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "**** Write to Debug Object: Object %p %s ****:\n\n",
+				  "**** Write to Debug Object: Object %p [%s] ****:\n\n",
 				  source_desc,
 				  acpi_ut_get_object_type_name(source_desc)));
 
@@ -341,7 +341,7 @@
 			/* All other types are invalid */
 
 			ACPI_ERROR((AE_INFO,
-				    "Source must be Integer/Buffer/String type, not %s",
+				    "Source must be type [Integer/Buffer/String], found [%s]",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
@@ -352,8 +352,9 @@
 		break;
 
 	default:
-		ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField"));
-		status = AE_AML_OPERAND_TYPE;
+		ACPI_ERROR((AE_INFO,
+			    "Target is not of type [Package/BufferField]"));
+		status = AE_AML_TARGET_TYPE;
 		break;
 	}
 
@@ -373,20 +374,20 @@
  *
  * DESCRIPTION: Store the object to the named object.
  *
- *              The Assignment of an object to a named object is handled here
- *              The value passed in will replace the current value (if any)
- *              with the input value.
+ * The assignment of an object to a named object is handled here.
+ * The value passed in will replace the current value (if any)
+ * with the input value.
  *
- *              When storing into an object the data is converted to the
- *              target object type then stored in the object. This means
- *              that the target object type (for an initialized target) will
- *              not be changed by a store operation. A copy_object can change
- *              the target type, however.
+ * When storing into an object the data is converted to the
+ * target object type then stored in the object. This means
+ * that the target object type (for an initialized target) will
+ * not be changed by a store operation. A copy_object can change
+ * the target type, however.
  *
- *              The implicit_conversion flag is set to NO/FALSE only when
- *              storing to an arg_x -- as per the rules of the ACPI spec.
+ * The implicit_conversion flag is set to NO/FALSE only when
+ * storing to an arg_x -- as per the rules of the ACPI spec.
  *
- *              Assumes parameters are already validated.
+ * Assumes parameters are already validated.
  *
  ******************************************************************************/
 
@@ -408,11 +409,75 @@
 	target_type = acpi_ns_get_type(node);
 	target_desc = acpi_ns_get_attached_object(node);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
 			  source_desc,
 			  acpi_ut_get_object_type_name(source_desc), node,
 			  acpi_ut_get_type_name(target_type)));
 
+	/* Only limited target types possible for everything except copy_object */
+
+	if (walk_state->opcode != AML_COPY_OP) {
+		/*
+		 * Only copy_object allows all object types to be overwritten. For
+		 * target_ref(s), there are restrictions on the object types that
+		 * are allowed.
+		 *
+		 * Allowable operations/typing for Store:
+		 *
+		 * 1) Simple Store
+		 *      Integer     --> Integer (Named/Local/Arg)
+		 *      String      --> String  (Named/Local/Arg)
+		 *      Buffer      --> Buffer  (Named/Local/Arg)
+		 *      Package     --> Package (Named/Local/Arg)
+		 *
+		 * 2) Store with implicit conversion
+		 *      Integer     --> String or Buffer  (Named)
+		 *      String      --> Integer or Buffer (Named)
+		 *      Buffer      --> Integer or String (Named)
+		 */
+		switch (target_type) {
+		case ACPI_TYPE_PACKAGE:
+			/*
+			 * Here, can only store a package to an existing package.
+			 * Storing a package to a Local/Arg is OK, and handled
+			 * elsewhere.
+			 */
+			if (walk_state->opcode == AML_STORE_OP) {
+				if (source_desc->common.type !=
+				    ACPI_TYPE_PACKAGE) {
+					ACPI_ERROR((AE_INFO,
+						    "Cannot assign type [%s] to [Package] "
+						    "(source must be type Pkg)",
+						    acpi_ut_get_object_type_name
+						    (source_desc)));
+
+					return_ACPI_STATUS(AE_AML_TARGET_TYPE);
+				}
+				break;
+			}
+
+			/* Fallthrough */
+
+		case ACPI_TYPE_DEVICE:
+		case ACPI_TYPE_EVENT:
+		case ACPI_TYPE_MUTEX:
+		case ACPI_TYPE_REGION:
+		case ACPI_TYPE_POWER:
+		case ACPI_TYPE_PROCESSOR:
+		case ACPI_TYPE_THERMAL:
+
+			ACPI_ERROR((AE_INFO,
+				    "Target must be [Buffer/Integer/String/Reference], found [%s] (%4.4s)",
+				    acpi_ut_get_type_name(node->type),
+				    node->name.ascii));
+
+			return_ACPI_STATUS(AE_AML_TARGET_TYPE);
+
+		default:
+			break;
+		}
+	}
+
 	/*
 	 * Resolve the source object to an actual value
 	 * (If it is a reference object)
@@ -425,13 +490,13 @@
 	/* Do the actual store operation */
 
 	switch (target_type) {
-	case ACPI_TYPE_INTEGER:
-	case ACPI_TYPE_STRING:
-	case ACPI_TYPE_BUFFER:
 		/*
 		 * The simple data types all support implicit source operand
 		 * conversion before the store.
 		 */
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_STRING:
+	case ACPI_TYPE_BUFFER:
 
 		if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) {
 			/*
@@ -467,7 +532,7 @@
 						       new_desc->common.type);
 
 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-					  "Store %s into %s via Convert/Attach\n",
+					  "Store type [%s] into [%s] via Convert/Attach\n",
 					  acpi_ut_get_object_type_name
 					  (source_desc),
 					  acpi_ut_get_object_type_name
@@ -491,15 +556,12 @@
 
 	default:
 		/*
-		 * No conversions for all other types. Directly store a copy of
-		 * the source object. This is the ACPI spec-defined behavior for
-		 * the copy_object operator.
+		 * copy_object operator: No conversions for all other types.
+		 * Instead, directly store a copy of the source object.
 		 *
-		 * NOTE: For the Store operator, this is a departure from the
-		 * ACPI spec, which states "If conversion is impossible, abort
-		 * the running control method". Instead, this code implements
-		 * "If conversion is impossible, treat the Store operation as
-		 * a CopyObject".
+		 * This is the ACPI spec-defined behavior for the copy_object
+		 * operator. (Note, for this default case, all normal
+		 * Store/Target operations exited above with an error).
 		 */
 		status = acpi_ex_store_direct_to_node(source_desc, node,
 						      walk_state);
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index 3101607..d1841de 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -122,9 +122,10 @@
 			/* Conversion successful but still not a valid type */
 
 			ACPI_ERROR((AE_INFO,
-				    "Cannot assign type %s to %s (must be type Int/Str/Buf)",
+				    "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
 				    acpi_ut_get_object_type_name(source_desc),
 				    acpi_ut_get_type_name(target_type)));
+
 			status = AE_AML_OPERAND_TYPE;
 		}
 		break;
@@ -275,7 +276,7 @@
 		/*
 		 * All other types come here.
 		 */
-		ACPI_WARNING((AE_INFO, "Store into type %s not implemented",
+		ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",
 			      acpi_ut_get_object_type_name(dest_desc)));
 
 		status = AE_NOT_IMPLEMENTED;
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 0f1daba..37aa5c4 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -60,7 +60,6 @@
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
-#ifdef	ACPI_FUTURE_USAGE
 static acpi_status
 acpi_ns_dump_one_object_path(acpi_handle obj_handle,
 			     u32 level, void *context, void **return_value);
@@ -68,7 +67,6 @@
 static acpi_status
 acpi_ns_get_max_depth(acpi_handle obj_handle,
 		      u32 level, void *context, void **return_value);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*******************************************************************************
  *
@@ -625,7 +623,6 @@
 	return (AE_OK);
 }
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_objects
@@ -680,9 +677,7 @@
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 }
-#endif				/* ACPI_FUTURE_USAGE */
 
-#ifdef	ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_one_object_path, acpi_ns_get_max_depth
@@ -810,7 +805,6 @@
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 }
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*******************************************************************************
  *
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 0eb5431..0c20980 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -226,7 +226,7 @@
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
 	acpi_status status = AE_OK;
-	char type_buffer[48];	/* Room for 5 types */
+	char type_buffer[96];	/* Room for 10 types */
 
 	/* A Namespace node should not get here, but make sure */
 
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c
index 89984f3..cf2f2fa 100644
--- a/drivers/acpi/acpica/pstree.c
+++ b/drivers/acpi/acpica/pstree.c
@@ -183,7 +183,6 @@
 	}
 }
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ps_get_depth_next
@@ -317,4 +316,3 @@
 	return (child);
 }
 #endif
-#endif				/*  ACPI_FUTURE_USAGE  */
diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c
index 183cc1e..71d2877 100644
--- a/drivers/acpi/acpica/psutils.c
+++ b/drivers/acpi/acpica/psutils.c
@@ -205,7 +205,6 @@
 /*
  * Get op's name (4-byte name segment) or 0 if unnamed
  */
-#ifdef ACPI_FUTURE_USAGE
 u32 acpi_ps_get_name(union acpi_parse_object * op)
 {
 
@@ -219,7 +218,6 @@
 
 	return (op->named.name);
 }
-#endif				/*  ACPI_FUTURE_USAGE  */
 
 /*
  * Set op's name
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c
index c428bb3..2a09288 100644
--- a/drivers/acpi/acpica/rsdump.c
+++ b/drivers/acpi/acpica/rsdump.c
@@ -51,7 +51,6 @@
 /*
  * All functions in this module are used by the AML Debugger only
  */
-#if defined(ACPI_DEBUGGER)
 /* Local prototypes */
 static void acpi_rs_out_string(char *title, char *value);
 
@@ -565,5 +564,3 @@
 		acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
 	}
 }
-
-#endif
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c
index 52b024d..9486992 100644
--- a/drivers/acpi/acpica/rsutils.c
+++ b/drivers/acpi/acpica/rsutils.c
@@ -564,7 +564,6 @@
  *
  ******************************************************************************/
 
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
 			    struct acpi_buffer *ret_buffer)
@@ -596,7 +595,6 @@
 	acpi_ut_remove_reference(obj_desc);
 	return_ACPI_STATUS(status);
 }
-#endif				/*  ACPI_FUTURE_USAGE  */
 
 /*******************************************************************************
  *
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c
index de51f83..1e8cd57 100644
--- a/drivers/acpi/acpica/rsxface.c
+++ b/drivers/acpi/acpica/rsxface.c
@@ -220,7 +220,7 @@
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
-#ifdef ACPI_FUTURE_USAGE
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_get_possible_resources
@@ -262,7 +262,7 @@
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
-#endif				/*  ACPI_FUTURE_USAGE  */
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_set_current_resources
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
index 988e23b..ecaaaff 100644
--- a/drivers/acpi/acpica/utdecode.c
+++ b/drivers/acpi/acpica/utdecode.c
@@ -232,12 +232,27 @@
 
 char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
 {
+	ACPI_FUNCTION_TRACE(ut_get_object_type_name);
 
 	if (!obj_desc) {
-		return ("[NULL Object Descriptor]");
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
+		return_PTR("[NULL Object Descriptor]");
 	}
 
-	return (acpi_ut_get_type_name(obj_desc->common.type));
+	/* These descriptor types share a common area */
+
+	if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) &&
+	    (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_NAMED)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Invalid object descriptor type: 0x%2.2X [%s] (%p)\n",
+				  ACPI_GET_DESCRIPTOR_TYPE(obj_desc),
+				  acpi_ut_get_descriptor_name(obj_desc),
+				  obj_desc));
+
+		return_PTR("Invalid object");
+	}
+
+	return_PTR(acpi_ut_get_type_name(obj_desc->common.type));
 }
 
 /*******************************************************************************
@@ -407,8 +422,6 @@
 	"ACPI_MTX_Events",
 	"ACPI_MTX_Caches",
 	"ACPI_MTX_Memory",
-	"ACPI_MTX_CommandComplete",
-	"ACPI_MTX_CommandReady"
 };
 
 char *acpi_ut_get_mutex_name(u32 mutex_id)
diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c
index 75a94f5..d435b7b 100644
--- a/drivers/acpi/acpica/utfileio.c
+++ b/drivers/acpi/acpica/utfileio.c
@@ -45,6 +45,7 @@
 #include "accommon.h"
 #include "actables.h"
 #include "acapps.h"
+#include "errno.h"
 
 #ifdef ACPI_ASL_COMPILER
 #include "aslcompiler.h"
@@ -301,6 +302,11 @@
 	file = fopen(filename, "rb");
 	if (!file) {
 		perror("Could not open input file");
+
+		if (errno == ENOENT) {
+			return (AE_NOT_EXIST);
+		}
+
 		return (status);
 	}
 
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c
index 28ab3a1..ccd0745 100644
--- a/drivers/acpi/acpica/utinit.c
+++ b/drivers/acpi/acpica/utinit.c
@@ -241,8 +241,6 @@
 	acpi_gbl_disable_mem_tracking = FALSE;
 #endif
 
-	ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
-
 	return_ACPI_STATUS(AE_OK);
 }
 
@@ -284,6 +282,19 @@
 {
 	ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
 
+	/* Just exit if subsystem is already shutdown */
+
+	if (acpi_gbl_shutdown) {
+		ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
+		return_VOID;
+	}
+
+	/* Subsystem appears active, go ahead and shut it down */
+
+	acpi_gbl_shutdown = TRUE;
+	acpi_gbl_startup_flags = 0;
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
+
 #ifndef ACPI_ASL_COMPILER
 
 	/* Close the acpi_event Handling */
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 37b8b58..ce406e3 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -108,6 +108,21 @@
 	/* Create the reader/writer lock for namespace access */
 
 	status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+#ifdef ACPI_DEBUGGER
+
+	/* Debugger Support */
+
+	status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
+#endif
+
 	return_ACPI_STATUS(status);
 }
 
@@ -147,6 +162,12 @@
 	/* Delete the reader/writer lock */
 
 	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
+
+#ifdef ACPI_DEBUGGER
+	acpi_os_delete_mutex(acpi_gbl_db_command_ready);
+	acpi_os_delete_mutex(acpi_gbl_db_command_complete);
+#endif
+
 	return_VOID;
 }
 
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index 4f33281..f9c8f9c 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -67,23 +67,6 @@
 
 	ACPI_FUNCTION_TRACE(acpi_terminate);
 
-	/* Just exit if subsystem is already shutdown */
-
-	if (acpi_gbl_shutdown) {
-		ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
-		return_ACPI_STATUS(AE_OK);
-	}
-
-	/* Subsystem appears active, go ahead and shut it down */
-
-	acpi_gbl_shutdown = TRUE;
-	acpi_gbl_startup_flags = 0;
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
-
-	/* Terminate the AML Debugger if present */
-
-	ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
-
 	/* Shutdown and free all resources */
 
 	acpi_ut_subsystem_shutdown();
@@ -270,7 +253,7 @@
 }
 
 ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
-#endif				/*  ACPI_FUTURE_USAGE  */
+#endif
 
 /*****************************************************************************
  *
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
new file mode 100644
index 0000000..3c083d2
--- /dev/null
+++ b/drivers/acpi/cppc_acpi.c
@@ -0,0 +1,733 @@
+/*
+ * CPPC (Collaborative Processor Performance Control) methods used by CPUfreq drivers.
+ *
+ * (C) Copyright 2014, 2015 Linaro Ltd.
+ * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * CPPC describes a few methods for controlling CPU performance using
+ * information from a per CPU table called CPC. This table is described in
+ * the ACPI v5.0+ specification. The table consists of a list of
+ * registers which may be memory mapped or hardware registers and also may
+ * include some static integer values.
+ *
+ * CPU performance is on an abstract continuous scale as against a discretized
+ * P-state scale which is tied to CPU frequency only. In brief, the basic
+ * operation involves:
+ *
+ * - OS makes a CPU performance request. (Can provide min and max bounds)
+ *
+ * - Platform (such as BMC) is free to optimize request within requested bounds
+ *   depending on power/thermal budgets etc.
+ *
+ * - Platform conveys its decision back to OS
+ *
+ * The communication between OS and platform occurs through another medium
+ * called (PCC) Platform Communication Channel. This is a generic mailbox like
+ * mechanism which includes doorbell semantics to indicate register updates.
+ * See drivers/mailbox/pcc.c for details on PCC.
+ *
+ * Finer details about the PCC and CPPC spec are available in the ACPI v5.1 and
+ * above specifications.
+ */
+
+#define pr_fmt(fmt)	"ACPI CPPC: " fmt
+
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+
+#include <acpi/cppc_acpi.h>
+/*
+ * Lock to provide mutually exclusive access to the PCC
+ * channel. e.g. When the remote updates the shared region
+ * with new data, the reader needs to be protected from
+ * other CPUs activity on the same channel.
+ */
+static DEFINE_SPINLOCK(pcc_lock);
+
+/*
+ * The cpc_desc structure contains the ACPI register details
+ * as described in the per CPU _CPC tables. The details
+ * include the type of register (e.g. PCC, System IO, FFH etc.)
+ * and destination addresses which lets us READ/WRITE CPU performance
+ * information using the appropriate I/O methods.
+ */
+static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
+
+/* This layer handles all the PCC specifics for CPPC. */
+static struct mbox_chan *pcc_channel;
+static void __iomem *pcc_comm_addr;
+static u64 comm_base_addr;
+static int pcc_subspace_idx = -1;
+static u16 pcc_cmd_delay;
+static bool pcc_channel_acquired;
+
+/*
+ * Arbitrary Retries in case the remote processor is slow to respond
+ * to PCC commands.
+ */
+#define NUM_RETRIES 500
+
+static int send_pcc_cmd(u16 cmd)
+{
+	int retries, result = -EIO;
+	struct acpi_pcct_hw_reduced *pcct_ss = pcc_channel->con_priv;
+	struct acpi_pcct_shared_memory *generic_comm_base =
+		(struct acpi_pcct_shared_memory *) pcc_comm_addr;
+	u32 cmd_latency = pcct_ss->latency;
+
+	/* Min time OS should wait before sending next command. */
+	udelay(pcc_cmd_delay);
+
+	/* Write to the shared comm region. */
+	writew(cmd, &generic_comm_base->command);
+
+	/* Flip CMD COMPLETE bit */
+	writew(0, &generic_comm_base->status);
+
+	/* Ring doorbell */
+	result = mbox_send_message(pcc_channel, &cmd);
+	if (result < 0) {
+		pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n",
+				cmd, result);
+		return result;
+	}
+
+	/* Wait for a nominal time to let platform process command. */
+	udelay(cmd_latency);
+
+	/* Retry in case the remote processor was too slow to catch up. */
+	for (retries = NUM_RETRIES; retries > 0; retries--) {
+		if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) {
+			result = 0;
+			break;
+		}
+	}
+
+	mbox_client_txdone(pcc_channel, result);
+	return result;
+}
+
+static void cppc_chan_tx_done(struct mbox_client *cl, void *msg, int ret)
+{
+	if (ret)
+		pr_debug("TX did not complete: CMD sent:%x, ret:%d\n",
+				*(u16 *)msg, ret);
+	else
+		pr_debug("TX completed. CMD sent:%x, ret:%d\n",
+				*(u16 *)msg, ret);
+}
+
+struct mbox_client cppc_mbox_cl = {
+	.tx_done = cppc_chan_tx_done,
+	.knows_txdone = true,
+};
+
+static int acpi_get_psd(struct cpc_desc *cpc_ptr, acpi_handle handle)
+{
+	int result = -EFAULT;
+	acpi_status status = AE_OK;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
+	struct acpi_buffer state = {0, NULL};
+	union acpi_object  *psd = NULL;
+	struct acpi_psd_package *pdomain;
+
+	status = acpi_evaluate_object_typed(handle, "_PSD", NULL, &buffer,
+			ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	psd = buffer.pointer;
+	if (!psd || psd->package.count != 1) {
+		pr_debug("Invalid _PSD data\n");
+		goto end;
+	}
+
+	pdomain = &(cpc_ptr->domain_info);
+
+	state.length = sizeof(struct acpi_psd_package);
+	state.pointer = pdomain;
+
+	status = acpi_extract_package(&(psd->package.elements[0]),
+		&format, &state);
+	if (ACPI_FAILURE(status)) {
+		pr_debug("Invalid _PSD data for CPU:%d\n", cpc_ptr->cpu_id);
+		goto end;
+	}
+
+	if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
+		pr_debug("Unknown _PSD:num_entries for CPU:%d\n", cpc_ptr->cpu_id);
+		goto end;
+	}
+
+	if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
+		pr_debug("Unknown _PSD:revision for CPU: %d\n", cpc_ptr->cpu_id);
+		goto end;
+	}
+
+	if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+		pr_debug("Invalid _PSD:coord_type for CPU:%d\n", cpc_ptr->cpu_id);
+		goto end;
+	}
+
+	result = 0;
+end:
+	kfree(buffer.pointer);
+	return result;
+}
+
+/**
+ * acpi_get_psd_map - Map the CPUs in a common freq domain.
+ * @all_cpu_data: Ptrs to CPU specific CPPC data including PSD info.
+ *
+ *	Return: 0 for success or negative value for err.
+ */
+int acpi_get_psd_map(struct cpudata **all_cpu_data)
+{
+	int count_target;
+	int retval = 0;
+	unsigned int i, j;
+	cpumask_var_t covered_cpus;
+	struct cpudata *pr, *match_pr;
+	struct acpi_psd_package *pdomain;
+	struct acpi_psd_package *match_pdomain;
+	struct cpc_desc *cpc_ptr, *match_cpc_ptr;
+
+	if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))
+		return -ENOMEM;
+
+	/*
+	 * Now that we have _PSD data from all CPUs, lets setup P-state
+	 * domain info.
+	 */
+	for_each_possible_cpu(i) {
+		pr = all_cpu_data[i];
+		if (!pr)
+			continue;
+
+		if (cpumask_test_cpu(i, covered_cpus))
+			continue;
+
+		cpc_ptr = per_cpu(cpc_desc_ptr, i);
+		if (!cpc_ptr)
+			continue;
+
+		pdomain = &(cpc_ptr->domain_info);
+		cpumask_set_cpu(i, pr->shared_cpu_map);
+		cpumask_set_cpu(i, covered_cpus);
+		if (pdomain->num_processors <= 1)
+			continue;
+
+		/* Validate the Domain info */
+		count_target = pdomain->num_processors;
+		if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
+			pr->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+		else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
+			pr->shared_type = CPUFREQ_SHARED_TYPE_HW;
+		else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+			pr->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+		for_each_possible_cpu(j) {
+			if (i == j)
+				continue;
+
+			match_cpc_ptr = per_cpu(cpc_desc_ptr, j);
+			if (!match_cpc_ptr)
+				continue;
+
+			match_pdomain = &(match_cpc_ptr->domain_info);
+			if (match_pdomain->domain != pdomain->domain)
+				continue;
+
+			/* Here i and j are in the same domain */
+			if (match_pdomain->num_processors != count_target) {
+				retval = -EFAULT;
+				goto err_ret;
+			}
+
+			if (pdomain->coord_type != match_pdomain->coord_type) {
+				retval = -EFAULT;
+				goto err_ret;
+			}
+
+			cpumask_set_cpu(j, covered_cpus);
+			cpumask_set_cpu(j, pr->shared_cpu_map);
+		}
+
+		for_each_possible_cpu(j) {
+			if (i == j)
+				continue;
+
+			match_pr = all_cpu_data[j];
+			if (!match_pr)
+				continue;
+
+			match_cpc_ptr = per_cpu(cpc_desc_ptr, j);
+			if (!match_cpc_ptr)
+				continue;
+
+			match_pdomain = &(match_cpc_ptr->domain_info);
+			if (match_pdomain->domain != pdomain->domain)
+				continue;
+
+			match_pr->shared_type = pr->shared_type;
+			cpumask_copy(match_pr->shared_cpu_map,
+				     pr->shared_cpu_map);
+		}
+	}
+
+err_ret:
+	for_each_possible_cpu(i) {
+		pr = all_cpu_data[i];
+		if (!pr)
+			continue;
+
+		/* Assume no coordination on any error parsing domain info */
+		if (retval) {
+			cpumask_clear(pr->shared_cpu_map);
+			cpumask_set_cpu(i, pr->shared_cpu_map);
+			pr->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+		}
+	}
+
+	free_cpumask_var(covered_cpus);
+	return retval;
+}
+EXPORT_SYMBOL_GPL(acpi_get_psd_map);
+
+static int register_pcc_channel(int pcc_subspace_idx)
+{
+	struct acpi_pcct_subspace *cppc_ss;
+	unsigned int len;
+
+	if (pcc_subspace_idx >= 0) {
+		pcc_channel = pcc_mbox_request_channel(&cppc_mbox_cl,
+				pcc_subspace_idx);
+
+		if (IS_ERR(pcc_channel)) {
+			pr_err("Failed to find PCC communication channel\n");
+			return -ENODEV;
+		}
+
+		/*
+		 * The PCC mailbox controller driver should
+		 * have parsed the PCCT (global table of all
+		 * PCC channels) and stored pointers to the
+		 * subspace communication region in con_priv.
+		 */
+		cppc_ss = pcc_channel->con_priv;
+
+		if (!cppc_ss) {
+			pr_err("No PCC subspace found for CPPC\n");
+			return -ENODEV;
+		}
+
+		/*
+		 * This is the shared communication region
+		 * for the OS and Platform to communicate over.
+		 */
+		comm_base_addr = cppc_ss->base_address;
+		len = cppc_ss->length;
+		pcc_cmd_delay = cppc_ss->min_turnaround_time;
+
+		pcc_comm_addr = acpi_os_ioremap(comm_base_addr, len);
+		if (!pcc_comm_addr) {
+			pr_err("Failed to ioremap PCC comm region mem\n");
+			return -ENOMEM;
+		}
+
+		/* Set flag so that we dont come here for each CPU. */
+		pcc_channel_acquired = true;
+	}
+
+	return 0;
+}
+
+/*
+ * An example CPC table looks like the following.
+ *
+ *	Name(_CPC, Package()
+ *			{
+ *			17,
+ *			NumEntries
+ *			1,
+ *			// Revision
+ *			ResourceTemplate(){Register(PCC, 32, 0, 0x120, 2)},
+ *			// Highest Performance
+ *			ResourceTemplate(){Register(PCC, 32, 0, 0x124, 2)},
+ *			// Nominal Performance
+ *			ResourceTemplate(){Register(PCC, 32, 0, 0x128, 2)},
+ *			// Lowest Nonlinear Performance
+ *			ResourceTemplate(){Register(PCC, 32, 0, 0x12C, 2)},
+ *			// Lowest Performance
+ *			ResourceTemplate(){Register(PCC, 32, 0, 0x130, 2)},
+ *			// Guaranteed Performance Register
+ *			ResourceTemplate(){Register(PCC, 32, 0, 0x110, 2)},
+ *			// Desired Performance Register
+ *			ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},
+ *			..
+ *			..
+ *			..
+ *
+ *		}
+ * Each Register() encodes how to access that specific register.
+ * e.g. a sample PCC entry has the following encoding:
+ *
+ *	Register (
+ *		PCC,
+ *		AddressSpaceKeyword
+ *		8,
+ *		//RegisterBitWidth
+ *		8,
+ *		//RegisterBitOffset
+ *		0x30,
+ *		//RegisterAddress
+ *		9
+ *		//AccessSize (subspace ID)
+ *		0
+ *		)
+ *	}
+ */
+
+/**
+ * acpi_cppc_processor_probe - Search for per CPU _CPC objects.
+ * @pr: Ptr to acpi_processor containing this CPUs logical Id.
+ *
+ *	Return: 0 for success or negative value for err.
+ */
+int acpi_cppc_processor_probe(struct acpi_processor *pr)
+{
+	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *out_obj, *cpc_obj;
+	struct cpc_desc *cpc_ptr;
+	struct cpc_reg *gas_t;
+	acpi_handle handle = pr->handle;
+	unsigned int num_ent, i, cpc_rev;
+	acpi_status status;
+	int ret = -EFAULT;
+
+	/* Parse the ACPI _CPC table for this cpu. */
+	status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
+			ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status)) {
+		ret = -ENODEV;
+		goto out_buf_free;
+	}
+
+	out_obj = (union acpi_object *) output.pointer;
+
+	cpc_ptr = kzalloc(sizeof(struct cpc_desc), GFP_KERNEL);
+	if (!cpc_ptr) {
+		ret = -ENOMEM;
+		goto out_buf_free;
+	}
+
+	/* First entry is NumEntries. */
+	cpc_obj = &out_obj->package.elements[0];
+	if (cpc_obj->type == ACPI_TYPE_INTEGER)	{
+		num_ent = cpc_obj->integer.value;
+	} else {
+		pr_debug("Unexpected entry type(%d) for NumEntries\n",
+				cpc_obj->type);
+		goto out_free;
+	}
+
+	/* Only support CPPCv2. Bail otherwise. */
+	if (num_ent != CPPC_NUM_ENT) {
+		pr_debug("Firmware exports %d entries. Expected: %d\n",
+				num_ent, CPPC_NUM_ENT);
+		goto out_free;
+	}
+
+	/* Second entry should be revision. */
+	cpc_obj = &out_obj->package.elements[1];
+	if (cpc_obj->type == ACPI_TYPE_INTEGER)	{
+		cpc_rev = cpc_obj->integer.value;
+	} else {
+		pr_debug("Unexpected entry type(%d) for Revision\n",
+				cpc_obj->type);
+		goto out_free;
+	}
+
+	if (cpc_rev != CPPC_REV) {
+		pr_debug("Firmware exports revision:%d. Expected:%d\n",
+				cpc_rev, CPPC_REV);
+		goto out_free;
+	}
+
+	/* Iterate through remaining entries in _CPC */
+	for (i = 2; i < num_ent; i++) {
+		cpc_obj = &out_obj->package.elements[i];
+
+		if (cpc_obj->type == ACPI_TYPE_INTEGER)	{
+			cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
+			cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = cpc_obj->integer.value;
+		} else if (cpc_obj->type == ACPI_TYPE_BUFFER) {
+			gas_t = (struct cpc_reg *)
+				cpc_obj->buffer.pointer;
+
+			/*
+			 * The PCC Subspace index is encoded inside
+			 * the CPC table entries. The same PCC index
+			 * will be used for all the PCC entries,
+			 * so extract it only once.
+			 */
+			if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+				if (pcc_subspace_idx < 0)
+					pcc_subspace_idx = gas_t->access_width;
+				else if (pcc_subspace_idx != gas_t->access_width) {
+					pr_debug("Mismatched PCC ids.\n");
+					goto out_free;
+				}
+			} else if (gas_t->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+				/* Support only PCC and SYS MEM type regs */
+				pr_debug("Unsupported register type: %d\n", gas_t->space_id);
+				goto out_free;
+			}
+
+			cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
+			memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
+		} else {
+			pr_debug("Err in entry:%d in CPC table of CPU:%d \n", i, pr->id);
+			goto out_free;
+		}
+	}
+	/* Store CPU Logical ID */
+	cpc_ptr->cpu_id = pr->id;
+
+	/* Plug it into this CPUs CPC descriptor. */
+	per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
+
+	/* Parse PSD data for this CPU */
+	ret = acpi_get_psd(cpc_ptr, handle);
+	if (ret)
+		goto out_free;
+
+	/* Register PCC channel once for all CPUs. */
+	if (!pcc_channel_acquired) {
+		ret = register_pcc_channel(pcc_subspace_idx);
+		if (ret)
+			goto out_free;
+	}
+
+	/* Everything looks okay */
+	pr_debug("Parsed CPC struct for CPU: %d\n", pr->id);
+
+	kfree(output.pointer);
+	return 0;
+
+out_free:
+	kfree(cpc_ptr);
+
+out_buf_free:
+	kfree(output.pointer);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(acpi_cppc_processor_probe);
+
+/**
+ * acpi_cppc_processor_exit - Cleanup CPC structs.
+ * @pr: Ptr to acpi_processor containing this CPUs logical Id.
+ *
+ * Return: Void
+ */
+void acpi_cppc_processor_exit(struct acpi_processor *pr)
+{
+	struct cpc_desc *cpc_ptr;
+	cpc_ptr = per_cpu(cpc_desc_ptr, pr->id);
+	kfree(cpc_ptr);
+}
+EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit);
+
+static u64 get_phys_addr(struct cpc_reg *reg)
+{
+	/* PCC communication addr space begins at byte offset 0x8. */
+	if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM)
+		return (u64)comm_base_addr + 0x8 + reg->address;
+	else
+		return reg->address;
+}
+
+static void cpc_read(struct cpc_reg *reg, u64 *val)
+{
+	u64 addr = get_phys_addr(reg);
+
+	acpi_os_read_memory((acpi_physical_address)addr,
+			val, reg->bit_width);
+}
+
+static void cpc_write(struct cpc_reg *reg, u64 val)
+{
+	u64 addr = get_phys_addr(reg);
+
+	acpi_os_write_memory((acpi_physical_address)addr,
+			val, reg->bit_width);
+}
+
+/**
+ * cppc_get_perf_caps - Get a CPUs performance capabilities.
+ * @cpunum: CPU from which to get capabilities info.
+ * @perf_caps: ptr to cppc_perf_caps. See cppc_acpi.h
+ *
+ * Return: 0 for success with perf_caps populated else -ERRNO.
+ */
+int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
+{
+	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
+	struct cpc_register_resource *highest_reg, *lowest_reg, *ref_perf,
+								 *nom_perf;
+	u64 high, low, ref, nom;
+	int ret = 0;
+
+	if (!cpc_desc) {
+		pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
+		return -ENODEV;
+	}
+
+	highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF];
+	lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF];
+	ref_perf = &cpc_desc->cpc_regs[REFERENCE_PERF];
+	nom_perf = &cpc_desc->cpc_regs[NOMINAL_PERF];
+
+	spin_lock(&pcc_lock);
+
+	/* Are any of the regs PCC ?*/
+	if ((highest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+			(lowest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+			(ref_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+			(nom_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) {
+		/* Ring doorbell once to update PCC subspace */
+		if (send_pcc_cmd(CMD_READ)) {
+			ret = -EIO;
+			goto out_err;
+		}
+	}
+
+	cpc_read(&highest_reg->cpc_entry.reg, &high);
+	perf_caps->highest_perf = high;
+
+	cpc_read(&lowest_reg->cpc_entry.reg, &low);
+	perf_caps->lowest_perf = low;
+
+	cpc_read(&ref_perf->cpc_entry.reg, &ref);
+	perf_caps->reference_perf = ref;
+
+	cpc_read(&nom_perf->cpc_entry.reg, &nom);
+	perf_caps->nominal_perf = nom;
+
+	if (!ref)
+		perf_caps->reference_perf = perf_caps->nominal_perf;
+
+	if (!high || !low || !nom)
+		ret = -EFAULT;
+
+out_err:
+	spin_unlock(&pcc_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cppc_get_perf_caps);
+
+/**
+ * cppc_get_perf_ctrs - Read a CPUs performance feedback counters.
+ * @cpunum: CPU from which to read counters.
+ * @perf_fb_ctrs: ptr to cppc_perf_fb_ctrs. See cppc_acpi.h
+ *
+ * Return: 0 for success with perf_fb_ctrs populated else -ERRNO.
+ */
+int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
+{
+	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
+	struct cpc_register_resource *delivered_reg, *reference_reg;
+	u64 delivered, reference;
+	int ret = 0;
+
+	if (!cpc_desc) {
+		pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
+		return -ENODEV;
+	}
+
+	delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR];
+	reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR];
+
+	spin_lock(&pcc_lock);
+
+	/* Are any of the regs PCC ?*/
+	if ((delivered_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+			(reference_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) {
+		/* Ring doorbell once to update PCC subspace */
+		if (send_pcc_cmd(CMD_READ)) {
+			ret = -EIO;
+			goto out_err;
+		}
+	}
+
+	cpc_read(&delivered_reg->cpc_entry.reg, &delivered);
+	cpc_read(&reference_reg->cpc_entry.reg, &reference);
+
+	if (!delivered || !reference) {
+		ret = -EFAULT;
+		goto out_err;
+	}
+
+	perf_fb_ctrs->delivered = delivered;
+	perf_fb_ctrs->reference = reference;
+
+	perf_fb_ctrs->delivered -= perf_fb_ctrs->prev_delivered;
+	perf_fb_ctrs->reference -= perf_fb_ctrs->prev_reference;
+
+	perf_fb_ctrs->prev_delivered = delivered;
+	perf_fb_ctrs->prev_reference = reference;
+
+out_err:
+	spin_unlock(&pcc_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs);
+
+/**
+ * cppc_set_perf - Set a CPUs performance controls.
+ * @cpu: CPU for which to set performance controls.
+ * @perf_ctrls: ptr to cppc_perf_ctrls. See cppc_acpi.h
+ *
+ * Return: 0 for success, -ERRNO otherwise.
+ */
+int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
+{
+	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
+	struct cpc_register_resource *desired_reg;
+	int ret = 0;
+
+	if (!cpc_desc) {
+		pr_debug("No CPC descriptor for CPU:%d\n", cpu);
+		return -ENODEV;
+	}
+
+	desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
+
+	spin_lock(&pcc_lock);
+
+	/*
+	 * Skip writing MIN/MAX until Linux knows how to come up with
+	 * useful values.
+	 */
+	cpc_write(&desired_reg->cpc_entry.reg, perf_ctrls->desired_perf);
+
+	/* Is this a PCC reg ?*/
+	if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+		/* Ring doorbell so Remote can get our perf request. */
+		if (send_pcc_cmd(CMD_WRITE))
+			ret = -EIO;
+	}
+
+	spin_unlock(&pcc_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cppc_set_perf);
diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
index 4ab4582..707cf62 100644
--- a/drivers/acpi/device_sysfs.c
+++ b/drivers/acpi/device_sysfs.c
@@ -26,6 +26,106 @@
 
 #include "internal.h"
 
+static ssize_t acpi_object_path(acpi_handle handle, char *buf)
+{
+	struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+	int result;
+
+	result = acpi_get_name(handle, ACPI_FULL_PATHNAME, &path);
+	if (result)
+		return result;
+
+	result = sprintf(buf, "%s\n", (char*)path.pointer);
+	kfree(path.pointer);
+	return result;
+}
+
+struct acpi_data_node_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct acpi_data_node *, char *);
+	ssize_t (*store)(struct acpi_data_node *, const char *, size_t count);
+};
+
+#define DATA_NODE_ATTR(_name)			\
+	static struct acpi_data_node_attr data_node_##_name =	\
+		__ATTR(_name, 0444, data_node_show_##_name, NULL)
+
+static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf)
+{
+	return acpi_object_path(dn->handle, buf);
+}
+
+DATA_NODE_ATTR(path);
+
+static struct attribute *acpi_data_node_default_attrs[] = {
+	&data_node_path.attr,
+	NULL
+};
+
+#define to_data_node(k) container_of(k, struct acpi_data_node, kobj)
+#define to_attr(a) container_of(a, struct acpi_data_node_attr, attr)
+
+static ssize_t acpi_data_node_attr_show(struct kobject *kobj,
+					struct attribute *attr, char *buf)
+{
+	struct acpi_data_node *dn = to_data_node(kobj);
+	struct acpi_data_node_attr *dn_attr = to_attr(attr);
+
+	return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO;
+}
+
+static const struct sysfs_ops acpi_data_node_sysfs_ops = {
+	.show	= acpi_data_node_attr_show,
+};
+
+static void acpi_data_node_release(struct kobject *kobj)
+{
+	struct acpi_data_node *dn = to_data_node(kobj);
+	complete(&dn->kobj_done);
+}
+
+static struct kobj_type acpi_data_node_ktype = {
+	.sysfs_ops = &acpi_data_node_sysfs_ops,
+	.default_attrs = acpi_data_node_default_attrs,
+	.release = acpi_data_node_release,
+};
+
+static void acpi_expose_nondev_subnodes(struct kobject *kobj,
+					struct acpi_device_data *data)
+{
+	struct list_head *list = &data->subnodes;
+	struct acpi_data_node *dn;
+
+	if (list_empty(list))
+		return;
+
+	list_for_each_entry(dn, list, sibling) {
+		int ret;
+
+		init_completion(&dn->kobj_done);
+		ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype,
+					   kobj, dn->name);
+		if (ret)
+			acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
+		else
+			acpi_expose_nondev_subnodes(&dn->kobj, &dn->data);
+	}
+}
+
+static void acpi_hide_nondev_subnodes(struct acpi_device_data *data)
+{
+	struct list_head *list = &data->subnodes;
+	struct acpi_data_node *dn;
+
+	if (list_empty(list))
+		return;
+
+	list_for_each_entry_reverse(dn, list, sibling) {
+		acpi_hide_nondev_subnodes(&dn->data);
+		kobject_put(&dn->kobj);
+	}
+}
+
 /**
  * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
  * @acpi_dev: ACPI device object.
@@ -323,20 +423,12 @@
 }
 static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL);
 
-static ssize_t
-acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
+static ssize_t acpi_device_path_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
-	int result;
 
-	result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
-	if (result)
-		goto end;
-
-	result = sprintf(buf, "%s\n", (char*)path.pointer);
-	kfree(path.pointer);
-end:
-	return result;
+	return acpi_object_path(acpi_dev->handle, buf);
 }
 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
 
@@ -475,6 +567,8 @@
 						    &dev_attr_real_power_state);
 	}
 
+	acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data);
+
 end:
 	return result;
 }
@@ -485,6 +579,8 @@
  */
 void acpi_device_remove_files(struct acpi_device *dev)
 {
+	acpi_hide_nondev_subnodes(&dev->data);
+
 	if (dev->flags.power_manageable) {
 		device_remove_file(&dev->dev, &dev_attr_power_state);
 		if (dev->power.flags.power_resources)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 42c66b6..f61a7c8 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -441,17 +441,31 @@
 
 static bool acpi_ec_guard_event(struct acpi_ec *ec)
 {
+	bool guarded = true;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ec->lock, flags);
+	/*
+	 * If firmware SCI_EVT clearing timing is "event", we actually
+	 * don't know when the SCI_EVT will be cleared by firmware after
+	 * evaluating _Qxx, so we need to re-check SCI_EVT after waiting an
+	 * acceptable period.
+	 *
+	 * The guarding period begins when EC_FLAGS_QUERY_PENDING is
+	 * flagged, which means SCI_EVT check has just been performed.
+	 * But if the current transaction is ACPI_EC_COMMAND_QUERY, the
+	 * guarding should have already been performed (via
+	 * EC_FLAGS_QUERY_GUARDING) and should not be applied so that the
+	 * ACPI_EC_COMMAND_QUERY transaction can be transitioned into
+	 * ACPI_EC_COMMAND_POLL state immediately.
+	 */
 	if (ec_event_clearing == ACPI_EC_EVT_TIMING_STATUS ||
 	    ec_event_clearing == ACPI_EC_EVT_TIMING_QUERY ||
 	    !test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags) ||
 	    (ec->curr && ec->curr->command == ACPI_EC_COMMAND_QUERY))
-		return false;
-
-	/*
-	 * Postpone the query submission to allow the firmware to proceed,
-	 * we shouldn't check SCI_EVT before the firmware reflagging it.
-	 */
-	return true;
+		guarded = false;
+	spin_unlock_irqrestore(&ec->lock, flags);
+	return guarded;
 }
 
 static int ec_transaction_polled(struct acpi_ec *ec)
@@ -597,6 +611,7 @@
 	unsigned long guard = usecs_to_jiffies(ec_polling_guard);
 	unsigned long timeout = ec->timestamp + guard;
 
+	/* Ensure guarding period before polling EC status */
 	do {
 		if (ec_busy_polling) {
 			/* Perform busy polling */
@@ -606,11 +621,13 @@
 		} else {
 			/*
 			 * Perform wait polling
-			 *
-			 * For SCI_EVT clearing timing of "event",
-			 * performing guarding before re-checking the
-			 * SCI_EVT. Otherwise, such guarding is not needed
-			 * due to the old practices.
+			 * 1. Wait the transaction to be completed by the
+			 *    GPE handler after the transaction enters
+			 *    ACPI_EC_COMMAND_POLL state.
+			 * 2. A special guarding logic is also required
+			 *    for event clearing mode "event" before the
+			 *    transaction enters ACPI_EC_COMMAND_POLL
+			 *    state.
 			 */
 			if (!ec_transaction_polled(ec) &&
 			    !acpi_ec_guard_event(ec))
@@ -620,7 +637,6 @@
 					       guard))
 				return 0;
 		}
-		/* Guard the register accesses for the polling modes */
 	} while (time_before(jiffies, timeout));
 	return -ETIME;
 }
@@ -929,6 +945,23 @@
 	return handler;
 }
 
+static struct acpi_ec_query_handler *
+acpi_ec_get_query_handler_by_value(struct acpi_ec *ec, u8 value)
+{
+	struct acpi_ec_query_handler *handler;
+	bool found = false;
+
+	mutex_lock(&ec->mutex);
+	list_for_each_entry(handler, &ec->list, node) {
+		if (value == handler->query_bit) {
+			found = true;
+			break;
+		}
+	}
+	mutex_unlock(&ec->mutex);
+	return found ? acpi_ec_get_query_handler(handler) : NULL;
+}
+
 static void acpi_ec_query_handler_release(struct kref *kref)
 {
 	struct acpi_ec_query_handler *handler =
@@ -964,14 +997,15 @@
 }
 EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
 
-void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,
+					  bool remove_all, u8 query_bit)
 {
 	struct acpi_ec_query_handler *handler, *tmp;
 	LIST_HEAD(free_list);
 
 	mutex_lock(&ec->mutex);
 	list_for_each_entry_safe(handler, tmp, &ec->list, node) {
-		if (query_bit == handler->query_bit) {
+		if (remove_all || query_bit == handler->query_bit) {
 			list_del_init(&handler->node);
 			list_add(&handler->node, &free_list);
 		}
@@ -980,6 +1014,11 @@
 	list_for_each_entry_safe(handler, tmp, &free_list, node)
 		acpi_ec_put_query_handler(handler);
 }
+
+void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+{
+	acpi_ec_remove_query_handlers(ec, false, query_bit);
+}
 EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
 
 static struct acpi_ec_query *acpi_ec_create_query(u8 *pval)
@@ -1025,7 +1064,6 @@
 {
 	u8 value = 0;
 	int result;
-	struct acpi_ec_query_handler *handler;
 	struct acpi_ec_query *q;
 
 	q = acpi_ec_create_query(&value);
@@ -1043,25 +1081,26 @@
 	if (result)
 		goto err_exit;
 
-	mutex_lock(&ec->mutex);
-	result = -ENODATA;
-	list_for_each_entry(handler, &ec->list, node) {
-		if (value == handler->query_bit) {
-			result = 0;
-			q->handler = acpi_ec_get_query_handler(handler);
-			ec_dbg_evt("Query(0x%02x) scheduled",
-				   q->handler->query_bit);
-			/*
-			 * It is reported that _Qxx are evaluated in a
-			 * parallel way on Windows:
-			 * https://bugzilla.kernel.org/show_bug.cgi?id=94411
-			 */
-			if (!schedule_work(&q->work))
-				result = -EBUSY;
-			break;
-		}
+	q->handler = acpi_ec_get_query_handler_by_value(ec, value);
+	if (!q->handler) {
+		result = -ENODATA;
+		goto err_exit;
 	}
-	mutex_unlock(&ec->mutex);
+
+	/*
+	 * It is reported that _Qxx are evaluated in a parallel way on
+	 * Windows:
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=94411
+	 *
+	 * Put this log entry before schedule_work() in order to make
+	 * it appearing before any other log entries occurred during the
+	 * work queue execution.
+	 */
+	ec_dbg_evt("Query(0x%02x) scheduled", value);
+	if (!schedule_work(&q->work)) {
+		ec_dbg_evt("Query(0x%02x) overlapped", value);
+		result = -EBUSY;
+	}
 
 err_exit:
 	if (result && q)
@@ -1354,19 +1393,13 @@
 static int acpi_ec_remove(struct acpi_device *device)
 {
 	struct acpi_ec *ec;
-	struct acpi_ec_query_handler *handler, *tmp;
 
 	if (!device)
 		return -EINVAL;
 
 	ec = acpi_driver_data(device);
 	ec_remove_handlers(ec);
-	mutex_lock(&ec->mutex);
-	list_for_each_entry_safe(handler, tmp, &ec->list, node) {
-		list_del(&handler->node);
-		kfree(handler);
-	}
-	mutex_unlock(&ec->mutex);
+	acpi_ec_remove_query_handlers(ec, true, 0);
 	release_region(ec->data_addr, 1);
 	release_region(ec->command_addr, 1);
 	device->driver_data = NULL;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index b9657af..1470ae4 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -351,13 +351,12 @@
 	return 0;
 }
 
-int __init init_acpi_device_notify(void)
+void __init init_acpi_device_notify(void)
 {
 	if (platform_notify || platform_notify_remove) {
 		printk(KERN_ERR PREFIX "Can't use platform_notify\n");
-		return 0;
+		return;
 	}
 	platform_notify = acpi_platform_notify;
 	platform_notify_remove = acpi_platform_notify_remove;
-	return 0;
 }
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 9e42621..c31787b 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -21,7 +21,7 @@
 #define PREFIX "ACPI: "
 
 acpi_status acpi_os_initialize1(void);
-int init_acpi_device_notify(void);
+void init_acpi_device_notify(void);
 int acpi_scan_init(void);
 void acpi_pci_root_init(void);
 void acpi_pci_link_init(void);
@@ -179,13 +179,13 @@
 #endif
 
 #ifdef CONFIG_ACPI_SLEEP
-int acpi_sleep_proc_init(void);
+void acpi_sleep_proc_init(void);
 int suspend_nvs_alloc(void);
 void suspend_nvs_free(void);
 int suspend_nvs_save(void);
 void suspend_nvs_restore(void);
 #else
-static inline int acpi_sleep_proc_init(void) { return 0; }
+static inline void acpi_sleep_proc_init(void) {}
 static inline int suspend_nvs_alloc(void) { return 0; }
 static inline void suspend_nvs_free(void) {}
 static inline int suspend_nvs_save(void) { return 0; }
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index c1b8d03..bc18aa2 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -706,7 +706,7 @@
 		flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "",
 		flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "",
 		flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "",
-		flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "",
+		flags & ACPI_NFIT_MEM_NOT_ARMED ? "not_armed " : "",
 		flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : "");
 }
 static DEVICE_ATTR_RO(flags);
@@ -815,7 +815,7 @@
 			flags |= NDD_ALIASING;
 
 		mem_flags = __to_nfit_memdev(nfit_mem)->flags;
-		if (mem_flags & ACPI_NFIT_MEM_ARMED)
+		if (mem_flags & ACPI_NFIT_MEM_NOT_ARMED)
 			flags |= NDD_UNARMED;
 
 		rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle);
@@ -839,7 +839,7 @@
 		  mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
 		  mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
 		  mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "",
-		  mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : "");
+		  mem_flags & ACPI_NFIT_MEM_NOT_ARMED ? " not_armed" : "");
 
 	}
 
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h
index 7e74015..329a1eb 100644
--- a/drivers/acpi/nfit.h
+++ b/drivers/acpi/nfit.h
@@ -24,7 +24,7 @@
 #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
 		| ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
-		| ACPI_NFIT_MEM_ARMED)
+		| ACPI_NFIT_MEM_NOT_ARMED)
 
 enum nfit_uuids {
 	NFIT_SPA_VOLATILE,
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 2f6e3c6..3935745 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -66,8 +66,6 @@
 /* stuff for debugger support */
 int acpi_in_debugger;
 EXPORT_SYMBOL(acpi_in_debugger);
-
-extern char line_buf[80];
 #endif				/*ENABLE_DEBUGGER */
 
 static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
@@ -1348,15 +1346,13 @@
 	return AE_OK;
 }
 
-#ifdef ACPI_FUTURE_USAGE
-u32 acpi_os_get_line(char *buffer)
+acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
 {
-
 #ifdef ENABLE_DEBUGGER
 	if (acpi_in_debugger) {
 		u32 chars;
 
-		kdb_read(buffer, sizeof(line_buf));
+		kdb_read(buffer, buffer_length);
 
 		/* remove the CR kdb includes */
 		chars = strlen(buffer) - 1;
@@ -1364,9 +1360,8 @@
 	}
 #endif
 
-	return 0;
+	return AE_OK;
 }
-#endif				/*  ACPI_FUTURE_USAGE  */
 
 acpi_status acpi_os_signal(u32 function, void *info)
 {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 393706a..850d7bf 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -652,6 +652,210 @@
 	kfree(root);
 }
 
+/*
+ * Following code to support acpi_pci_root_create() is copied from
+ * arch/x86/pci/acpi.c and modified so it could be reused by x86, IA64
+ * and ARM64.
+ */
+static void acpi_pci_root_validate_resources(struct device *dev,
+					     struct list_head *resources,
+					     unsigned long type)
+{
+	LIST_HEAD(list);
+	struct resource *res1, *res2, *root = NULL;
+	struct resource_entry *tmp, *entry, *entry2;
+
+	BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
+	root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
+
+	list_splice_init(resources, &list);
+	resource_list_for_each_entry_safe(entry, tmp, &list) {
+		bool free = false;
+		resource_size_t end;
+
+		res1 = entry->res;
+		if (!(res1->flags & type))
+			goto next;
+
+		/* Exclude non-addressable range or non-addressable portion */
+		end = min(res1->end, root->end);
+		if (end <= res1->start) {
+			dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
+				 res1);
+			free = true;
+			goto next;
+		} else if (res1->end != end) {
+			dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
+				 res1, (unsigned long long)end + 1,
+				 (unsigned long long)res1->end);
+			res1->end = end;
+		}
+
+		resource_list_for_each_entry(entry2, resources) {
+			res2 = entry2->res;
+			if (!(res2->flags & type))
+				continue;
+
+			/*
+			 * I don't like throwing away windows because then
+			 * our resources no longer match the ACPI _CRS, but
+			 * the kernel resource tree doesn't allow overlaps.
+			 */
+			if (resource_overlaps(res1, res2)) {
+				res2->start = min(res1->start, res2->start);
+				res2->end = max(res1->end, res2->end);
+				dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
+					 res2, res1);
+				free = true;
+				goto next;
+			}
+		}
+
+next:
+		resource_list_del(entry);
+		if (free)
+			resource_list_free_entry(entry);
+		else
+			resource_list_add_tail(entry, resources);
+	}
+}
+
+int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
+{
+	int ret;
+	struct list_head *list = &info->resources;
+	struct acpi_device *device = info->bridge;
+	struct resource_entry *entry, *tmp;
+	unsigned long flags;
+
+	flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT;
+	ret = acpi_dev_get_resources(device, list,
+				     acpi_dev_filter_resource_type_cb,
+				     (void *)flags);
+	if (ret < 0)
+		dev_warn(&device->dev,
+			 "failed to parse _CRS method, error code %d\n", ret);
+	else if (ret == 0)
+		dev_dbg(&device->dev,
+			"no IO and memory resources present in _CRS\n");
+	else {
+		resource_list_for_each_entry_safe(entry, tmp, list) {
+			if (entry->res->flags & IORESOURCE_DISABLED)
+				resource_list_destroy_entry(entry);
+			else
+				entry->res->name = info->name;
+		}
+		acpi_pci_root_validate_resources(&device->dev, list,
+						 IORESOURCE_MEM);
+		acpi_pci_root_validate_resources(&device->dev, list,
+						 IORESOURCE_IO);
+	}
+
+	return ret;
+}
+
+static void pci_acpi_root_add_resources(struct acpi_pci_root_info *info)
+{
+	struct resource_entry *entry, *tmp;
+	struct resource *res, *conflict, *root = NULL;
+
+	resource_list_for_each_entry_safe(entry, tmp, &info->resources) {
+		res = entry->res;
+		if (res->flags & IORESOURCE_MEM)
+			root = &iomem_resource;
+		else if (res->flags & IORESOURCE_IO)
+			root = &ioport_resource;
+		else
+			continue;
+
+		conflict = insert_resource_conflict(root, res);
+		if (conflict) {
+			dev_info(&info->bridge->dev,
+				 "ignoring host bridge window %pR (conflicts with %s %pR)\n",
+				 res, conflict->name, conflict);
+			resource_list_destroy_entry(entry);
+		}
+	}
+}
+
+static void __acpi_pci_root_release_info(struct acpi_pci_root_info *info)
+{
+	struct resource *res;
+	struct resource_entry *entry, *tmp;
+
+	if (!info)
+		return;
+
+	resource_list_for_each_entry_safe(entry, tmp, &info->resources) {
+		res = entry->res;
+		if (res->parent &&
+		    (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
+			release_resource(res);
+		resource_list_destroy_entry(entry);
+	}
+
+	info->ops->release_info(info);
+}
+
+static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
+{
+	struct resource *res;
+	struct resource_entry *entry;
+
+	resource_list_for_each_entry(entry, &bridge->windows) {
+		res = entry->res;
+		if (res->parent &&
+		    (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
+			release_resource(res);
+	}
+	__acpi_pci_root_release_info(bridge->release_data);
+}
+
+struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
+				     struct acpi_pci_root_ops *ops,
+				     struct acpi_pci_root_info *info,
+				     void *sysdata)
+{
+	int ret, busnum = root->secondary.start;
+	struct acpi_device *device = root->device;
+	int node = acpi_get_node(device->handle);
+	struct pci_bus *bus;
+
+	info->root = root;
+	info->bridge = device;
+	info->ops = ops;
+	INIT_LIST_HEAD(&info->resources);
+	snprintf(info->name, sizeof(info->name), "PCI Bus %04x:%02x",
+		 root->segment, busnum);
+
+	if (ops->init_info && ops->init_info(info))
+		goto out_release_info;
+	if (ops->prepare_resources)
+		ret = ops->prepare_resources(info);
+	else
+		ret = acpi_pci_probe_root_resources(info);
+	if (ret < 0)
+		goto out_release_info;
+
+	pci_acpi_root_add_resources(info);
+	pci_add_resource(&info->resources, &root->secondary);
+	bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
+				  sysdata, &info->resources);
+	if (!bus)
+		goto out_release_info;
+
+	pci_scan_child_bus(bus);
+	pci_set_host_bridge_release(to_pci_host_bridge(bus->bridge),
+				    acpi_pci_root_release_info, info);
+	if (node != NUMA_NO_NODE)
+		dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
+	return bus;
+
+out_release_info:
+	__acpi_pci_root_release_info(info);
+	return NULL;
+}
+
 void __init acpi_pci_root_init(void)
 {
 	acpi_hest_init();
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 75c28ea..2a35815 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -144,11 +144,9 @@
 	.release = single_release,
 };
 
-int __init acpi_sleep_proc_init(void)
+void __init acpi_sleep_proc_init(void)
 {
 	/* 'wakeup device' [R/W] */
 	proc_create("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
 		    acpi_root_dir, &acpi_system_wakeup_device_fops);
-
-	return 0;
 }
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 51e658f2..f4e02ae 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -242,6 +242,10 @@
 	if (pr->flags.need_hotplug_init)
 		return 0;
 
+	result = acpi_cppc_processor_probe(pr);
+	if (result)
+		return -ENODEV;
+
 	if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
 		acpi_processor_power_init(pr);
 
@@ -287,6 +291,8 @@
 
 	acpi_pss_perf_exit(pr, device);
 
+	acpi_cppc_processor_exit(pr);
+
 	return 0;
 }
 
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index 6d99450..88f4306 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -19,11 +19,133 @@
 
 #include "internal.h"
 
+static int acpi_data_get_property_array(struct acpi_device_data *data,
+					const char *name,
+					acpi_object_type type,
+					const union acpi_object **obj);
+
 /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
 static const u8 prp_uuid[16] = {
 	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
 	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
 };
+/* ACPI _DSD data subnodes UUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
+static const u8 ads_uuid[16] = {
+	0xe6, 0xe3, 0xb8, 0xdb, 0x86, 0x58, 0xa6, 0x4b,
+	0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b
+};
+
+static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
+					   const union acpi_object *desc,
+					   struct acpi_device_data *data);
+static bool acpi_extract_properties(const union acpi_object *desc,
+				    struct acpi_device_data *data);
+
+static bool acpi_nondev_subnode_ok(acpi_handle scope,
+				   const union acpi_object *link,
+				   struct list_head *list)
+{
+	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+	struct acpi_data_node *dn;
+	acpi_handle handle;
+	acpi_status status;
+
+	dn = kzalloc(sizeof(*dn), GFP_KERNEL);
+	if (!dn)
+		return false;
+
+	dn->name = link->package.elements[0].string.pointer;
+	dn->fwnode.type = FWNODE_ACPI_DATA;
+	INIT_LIST_HEAD(&dn->data.subnodes);
+
+	status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
+				 &handle);
+	if (ACPI_FAILURE(status))
+		goto fail;
+
+	status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
+					    ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status))
+		goto fail;
+
+	if (acpi_extract_properties(buf.pointer, &dn->data))
+		dn->handle = handle;
+
+	/*
+	 * The scope for the subnode object lookup is the one of the namespace
+	 * node (device) containing the object that has returned the package.
+	 * That is, it's the scope of that object's parent.
+	 */
+	status = acpi_get_parent(handle, &scope);
+	if (ACPI_SUCCESS(status)
+	    && acpi_enumerate_nondev_subnodes(scope, buf.pointer, &dn->data))
+		dn->handle = handle;
+
+	if (dn->handle) {
+		dn->data.pointer = buf.pointer;
+		list_add_tail(&dn->sibling, list);
+		return true;
+	}
+
+	acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
+
+ fail:
+	ACPI_FREE(buf.pointer);
+	kfree(dn);
+	return false;
+}
+
+static int acpi_add_nondev_subnodes(acpi_handle scope,
+				    const union acpi_object *links,
+				    struct list_head *list)
+{
+	bool ret = false;
+	int i;
+
+	for (i = 0; i < links->package.count; i++) {
+		const union acpi_object *link;
+
+		link = &links->package.elements[i];
+		/* Only two elements allowed, both must be strings. */
+		if (link->package.count == 2
+		    && link->package.elements[0].type == ACPI_TYPE_STRING
+		    && link->package.elements[1].type == ACPI_TYPE_STRING
+		    && acpi_nondev_subnode_ok(scope, link, list))
+			ret = true;
+	}
+
+	return ret;
+}
+
+static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
+					   const union acpi_object *desc,
+					   struct acpi_device_data *data)
+{
+	int i;
+
+	/* Look for the ACPI data subnodes UUID. */
+	for (i = 0; i < desc->package.count; i += 2) {
+		const union acpi_object *uuid, *links;
+
+		uuid = &desc->package.elements[i];
+		links = &desc->package.elements[i + 1];
+
+		/*
+		 * The first element must be a UUID and the second one must be
+		 * a package.
+		 */
+		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
+		    || links->type != ACPI_TYPE_PACKAGE)
+			break;
+
+		if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid)))
+			continue;
+
+		return acpi_add_nondev_subnodes(scope, links, &data->subnodes);
+	}
+
+	return false;
+}
 
 static bool acpi_property_value_ok(const union acpi_object *value)
 {
@@ -81,8 +203,8 @@
 	const union acpi_object *of_compatible;
 	int ret;
 
-	ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
-					  &of_compatible);
+	ret = acpi_data_get_property_array(&adev->data, "compatible",
+					   ACPI_TYPE_STRING, &of_compatible);
 	if (ret) {
 		ret = acpi_dev_get_property(adev, "compatible",
 					    ACPI_TYPE_STRING, &of_compatible);
@@ -100,34 +222,13 @@
 	adev->flags.of_compatible_ok = 1;
 }
 
-void acpi_init_properties(struct acpi_device *adev)
+static bool acpi_extract_properties(const union acpi_object *desc,
+				    struct acpi_device_data *data)
 {
-	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
-	bool acpi_of = false;
-	struct acpi_hardware_id *hwid;
-	const union acpi_object *desc;
-	acpi_status status;
 	int i;
 
-	/*
-	 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
-	 * Device Tree compatible properties for this device.
-	 */
-	list_for_each_entry(hwid, &adev->pnp.ids, list) {
-		if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) {
-			acpi_of = true;
-			break;
-		}
-	}
-
-	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
-					    ACPI_TYPE_PACKAGE);
-	if (ACPI_FAILURE(status))
-		goto out;
-
-	desc = buf.pointer;
 	if (desc->package.count % 2)
-		goto fail;
+		return false;
 
 	/* Look for the device properties UUID. */
 	for (i = 0; i < desc->package.count; i += 2) {
@@ -154,18 +255,50 @@
 		if (!acpi_properties_format_valid(properties))
 			break;
 
-		adev->data.pointer = buf.pointer;
-		adev->data.properties = properties;
-
-		if (acpi_of)
-			acpi_init_of_compatible(adev);
-
-		goto out;
+		data->properties = properties;
+		return true;
 	}
 
- fail:
-	dev_dbg(&adev->dev, "Returned _DSD data is not valid, skipping\n");
-	ACPI_FREE(buf.pointer);
+	return false;
+}
+
+void acpi_init_properties(struct acpi_device *adev)
+{
+	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+	struct acpi_hardware_id *hwid;
+	acpi_status status;
+	bool acpi_of = false;
+
+	INIT_LIST_HEAD(&adev->data.subnodes);
+
+	/*
+	 * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
+	 * Device Tree compatible properties for this device.
+	 */
+	list_for_each_entry(hwid, &adev->pnp.ids, list) {
+		if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) {
+			acpi_of = true;
+			break;
+		}
+	}
+
+	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
+					    ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status))
+		goto out;
+
+	if (acpi_extract_properties(buf.pointer, &adev->data)) {
+		adev->data.pointer = buf.pointer;
+		if (acpi_of)
+			acpi_init_of_compatible(adev);
+	}
+	if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data))
+		adev->data.pointer = buf.pointer;
+
+	if (!adev->data.pointer) {
+		acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n");
+		ACPI_FREE(buf.pointer);
+	}
 
  out:
 	if (acpi_of && !adev->flags.of_compatible_ok)
@@ -173,8 +306,25 @@
 			 ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n");
 }
 
+static void acpi_destroy_nondev_subnodes(struct list_head *list)
+{
+	struct acpi_data_node *dn, *next;
+
+	if (list_empty(list))
+		return;
+
+	list_for_each_entry_safe_reverse(dn, next, list, sibling) {
+		acpi_destroy_nondev_subnodes(&dn->data.subnodes);
+		wait_for_completion(&dn->kobj_done);
+		list_del(&dn->sibling);
+		ACPI_FREE((void *)dn->data.pointer);
+		kfree(dn);
+	}
+}
+
 void acpi_free_properties(struct acpi_device *adev)
 {
+	acpi_destroy_nondev_subnodes(&adev->data.subnodes);
 	ACPI_FREE((void *)adev->data.pointer);
 	adev->data.of_compatible = NULL;
 	adev->data.pointer = NULL;
@@ -182,8 +332,8 @@
 }
 
 /**
- * acpi_dev_get_property - return an ACPI property with given name
- * @adev: ACPI device to get property
+ * acpi_data_get_property - return an ACPI property with given name
+ * @data: ACPI device deta object to get the property from
  * @name: Name of the property
  * @type: Expected property type
  * @obj: Location to store the property value (if not %NULL)
@@ -192,26 +342,27 @@
  * object at the location pointed to by @obj if found.
  *
  * Callers must not attempt to free the returned objects.  These objects will be
- * freed by the ACPI core automatically during the removal of @adev.
+ * freed by the ACPI core automatically during the removal of @data.
  *
  * Return: %0 if property with @name has been found (success),
  *         %-EINVAL if the arguments are invalid,
  *         %-ENODATA if the property doesn't exist,
  *         %-EPROTO if the property value type doesn't match @type.
  */
-int acpi_dev_get_property(struct acpi_device *adev, const char *name,
-			  acpi_object_type type, const union acpi_object **obj)
+static int acpi_data_get_property(struct acpi_device_data *data,
+				  const char *name, acpi_object_type type,
+				  const union acpi_object **obj)
 {
 	const union acpi_object *properties;
 	int i;
 
-	if (!adev || !name)
+	if (!data || !name)
 		return -EINVAL;
 
-	if (!adev->data.pointer || !adev->data.properties)
+	if (!data->pointer || !data->properties)
 		return -ENODATA;
 
-	properties = adev->data.properties;
+	properties = data->properties;
 	for (i = 0; i < properties->package.count; i++) {
 		const union acpi_object *propname, *propvalue;
 		const union acpi_object *property;
@@ -232,11 +383,50 @@
 	}
 	return -ENODATA;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_get_property);
 
 /**
- * acpi_dev_get_property_array - return an ACPI array property with given name
- * @adev: ACPI device to get property
+ * acpi_dev_get_property - return an ACPI property with given name.
+ * @adev: ACPI device to get the property from.
+ * @name: Name of the property.
+ * @type: Expected property type.
+ * @obj: Location to store the property value (if not %NULL).
+ */
+int acpi_dev_get_property(struct acpi_device *adev, const char *name,
+			  acpi_object_type type, const union acpi_object **obj)
+{
+	return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_property);
+
+static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode)
+{
+	if (fwnode->type == FWNODE_ACPI) {
+		struct acpi_device *adev = to_acpi_device_node(fwnode);
+		return &adev->data;
+	} else if (fwnode->type == FWNODE_ACPI_DATA) {
+		struct acpi_data_node *dn = to_acpi_data_node(fwnode);
+		return &dn->data;
+	}
+	return NULL;
+}
+
+/**
+ * acpi_node_prop_get - return an ACPI property with given name.
+ * @fwnode: Firmware node to get the property from.
+ * @propname: Name of the property.
+ * @valptr: Location to store a pointer to the property value (if not %NULL).
+ */
+int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
+		       void **valptr)
+{
+	return acpi_data_get_property(acpi_device_data_of_node(fwnode),
+				      propname, ACPI_TYPE_ANY,
+				      (const union acpi_object **)valptr);
+}
+
+/**
+ * acpi_data_get_property_array - return an ACPI array property with given name
+ * @adev: ACPI data object to get the property from
  * @name: Name of the property
  * @type: Expected type of array elements
  * @obj: Location to store a pointer to the property value (if not NULL)
@@ -245,7 +435,7 @@
  * ACPI object at the location pointed to by @obj if found.
  *
  * Callers must not attempt to free the returned objects.  Those objects will be
- * freed by the ACPI core automatically during the removal of @adev.
+ * freed by the ACPI core automatically during the removal of @data.
  *
  * Return: %0 if array property (package) with @name has been found (success),
  *         %-EINVAL if the arguments are invalid,
@@ -253,14 +443,15 @@
  *         %-EPROTO if the property is not a package or the type of its elements
  *           doesn't match @type.
  */
-int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
-				acpi_object_type type,
-				const union acpi_object **obj)
+static int acpi_data_get_property_array(struct acpi_device_data *data,
+					const char *name,
+					acpi_object_type type,
+					const union acpi_object **obj)
 {
 	const union acpi_object *prop;
 	int ret, i;
 
-	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop);
+	ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop);
 	if (ret)
 		return ret;
 
@@ -275,12 +466,11 @@
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
 
 /**
- * acpi_dev_get_property_reference - returns handle to the referenced object
- * @adev: ACPI device to get property
- * @name: Name of the property
+ * acpi_data_get_property_reference - returns handle to the referenced object
+ * @data: ACPI device data object containing the property
+ * @propname: Name of the property
  * @index: Index of the reference to return
  * @args: Location to store the returned reference with optional arguments
  *
@@ -294,16 +484,16 @@
  *
  * Return: %0 on success, negative error code on failure.
  */
-int acpi_dev_get_property_reference(struct acpi_device *adev,
-				    const char *name, size_t index,
-				    struct acpi_reference_args *args)
+static int acpi_data_get_property_reference(struct acpi_device_data *data,
+					    const char *propname, size_t index,
+					    struct acpi_reference_args *args)
 {
 	const union acpi_object *element, *end;
 	const union acpi_object *obj;
 	struct acpi_device *device;
 	int ret, idx = 0;
 
-	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj);
+	ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
 	if (ret)
 		return ret;
 
@@ -378,17 +568,27 @@
 
 	return -EPROTO;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
 
-int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
-		      void **valptr)
+/**
+ * acpi_node_get_property_reference - get a handle to the referenced object.
+ * @fwnode: Firmware node to get the property from.
+ * @propname: Name of the property.
+ * @index: Index of the reference to return.
+ * @args: Location to store the returned reference with optional arguments.
+ */
+int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+				     const char *name, size_t index,
+				     struct acpi_reference_args *args)
 {
-	return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
-				     (const union acpi_object **)valptr);
-}
+	struct acpi_device_data *data = acpi_device_data_of_node(fwnode);
 
-int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
-			      enum dev_prop_type proptype, void *val)
+	return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(acpi_node_get_property_reference);
+
+static int acpi_data_prop_read_single(struct acpi_device_data *data,
+				      const char *propname,
+				      enum dev_prop_type proptype, void *val)
 {
 	const union acpi_object *obj;
 	int ret;
@@ -397,7 +597,7 @@
 		return -EINVAL;
 
 	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
-		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj);
+		ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj);
 		if (ret)
 			return ret;
 
@@ -422,7 +622,7 @@
 			break;
 		}
 	} else if (proptype == DEV_PROP_STRING) {
-		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj);
+		ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj);
 		if (ret)
 			return ret;
 
@@ -433,6 +633,12 @@
 	return ret;
 }
 
+int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
+			      enum dev_prop_type proptype, void *val)
+{
+	return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL;
+}
+
 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
 				       size_t nval)
 {
@@ -509,20 +715,22 @@
 	return 0;
 }
 
-int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
-		       enum dev_prop_type proptype, void *val, size_t nval)
+static int acpi_data_prop_read(struct acpi_device_data *data,
+			       const char *propname,
+			       enum dev_prop_type proptype,
+			       void *val, size_t nval)
 {
 	const union acpi_object *obj;
 	const union acpi_object *items;
 	int ret;
 
 	if (val && nval == 1) {
-		ret = acpi_dev_prop_read_single(adev, propname, proptype, val);
+		ret = acpi_data_prop_read_single(data, propname, proptype, val);
 		if (!ret)
 			return ret;
 	}
 
-	ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
+	ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj);
 	if (ret)
 		return ret;
 
@@ -558,3 +766,84 @@
 	}
 	return ret;
 }
+
+int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
+		       enum dev_prop_type proptype, void *val, size_t nval)
+{
+	return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL;
+}
+
+/**
+ * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
+ * @fwnode: Firmware node to get the property from.
+ * @propname: Name of the property.
+ * @proptype: Expected property type.
+ * @val: Location to store the property value (if not %NULL).
+ * @nval: Size of the array pointed to by @val.
+ *
+ * If @val is %NULL, return the number of array elements comprising the value
+ * of the property.  Otherwise, read at most @nval values to the array at the
+ * location pointed to by @val.
+ */
+int acpi_node_prop_read(struct fwnode_handle *fwnode,  const char *propname,
+		        enum dev_prop_type proptype, void *val, size_t nval)
+{
+	return acpi_data_prop_read(acpi_device_data_of_node(fwnode),
+				   propname, proptype, val, nval);
+}
+
+/**
+ * acpi_get_next_subnode - Return the next child node handle for a device.
+ * @dev: Device to find the next child node for.
+ * @child: Handle to one of the device's child nodes or a null handle.
+ */
+struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+					    struct fwnode_handle *child)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct list_head *head, *next;
+
+	if (!adev)
+		return NULL;
+
+	if (!child || child->type == FWNODE_ACPI) {
+		head = &adev->children;
+		if (list_empty(head))
+			goto nondev;
+
+		if (child) {
+			adev = to_acpi_device_node(child);
+			next = adev->node.next;
+			if (next == head) {
+				child = NULL;
+				goto nondev;
+			}
+			adev = list_entry(next, struct acpi_device, node);
+		} else {
+			adev = list_first_entry(head, struct acpi_device, node);
+		}
+		return acpi_fwnode_handle(adev);
+	}
+
+ nondev:
+	if (!child || child->type == FWNODE_ACPI_DATA) {
+		struct acpi_data_node *dn;
+
+		head = &adev->data.subnodes;
+		if (list_empty(head))
+			return NULL;
+
+		if (child) {
+			dn = to_acpi_data_node(child);
+			next = dn->sibling.next;
+			if (next == head)
+				return NULL;
+
+			dn = list_entry(next, struct acpi_data_node, sibling);
+		} else {
+			dn = list_first_entry(head, struct acpi_data_node, sibling);
+		}
+		return &dn->fwnode;
+	}
+	return NULL;
+}
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 15d22db..cdc5c25 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -119,7 +119,7 @@
 EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
 
 static void acpi_dev_ioresource_flags(struct resource *res, u64 len,
-				      u8 io_decode)
+				      u8 io_decode, u8 translation_type)
 {
 	res->flags = IORESOURCE_IO;
 
@@ -131,6 +131,8 @@
 
 	if (io_decode == ACPI_DECODE_16)
 		res->flags |= IORESOURCE_IO_16BIT_ADDR;
+	if (translation_type == ACPI_SPARSE_TRANSLATION)
+		res->flags |= IORESOURCE_IO_SPARSE;
 }
 
 static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
@@ -138,7 +140,7 @@
 {
 	res->start = start;
 	res->end = start + len - 1;
-	acpi_dev_ioresource_flags(res, len, io_decode);
+	acpi_dev_ioresource_flags(res, len, io_decode, 0);
 }
 
 /**
@@ -231,7 +233,8 @@
 		acpi_dev_memresource_flags(res, len, wp);
 		break;
 	case ACPI_IO_RANGE:
-		acpi_dev_ioresource_flags(res, len, iodec);
+		acpi_dev_ioresource_flags(res, len, iodec,
+					  addr->info.io.translation_type);
 		break;
 	case ACPI_BUS_NUMBER_RANGE:
 		res->flags = IORESOURCE_BUS;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 01136b8..daf9fc8 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -695,26 +695,6 @@
 	return result;
 }
 
-struct acpi_device *acpi_get_next_child(struct device *dev,
-					struct acpi_device *child)
-{
-	struct acpi_device *adev = ACPI_COMPANION(dev);
-	struct list_head *head, *next;
-
-	if (!adev)
-		return NULL;
-
-	head = &adev->children;
-	if (list_empty(head))
-		return NULL;
-
-	if (!child)
-		return list_first_entry(head, struct acpi_device, node);
-
-	next = child->node.next;
-	return next == head ? NULL : list_entry(next, struct acpi_device, node);
-}
-
 /* --------------------------------------------------------------------------
                                  Device Enumeration
    -------------------------------------------------------------------------- */
@@ -1184,7 +1164,7 @@
 	if (!id)
 		return;
 
-	id->id = kstrdup(dev_id, GFP_KERNEL);
+	id->id = kstrdup_const(dev_id, GFP_KERNEL);
 	if (!id->id) {
 		kfree(id);
 		return;
@@ -1322,7 +1302,7 @@
 	struct acpi_hardware_id *id, *tmp;
 
 	list_for_each_entry_safe(id, tmp, &pnp->ids, list) {
-		kfree(id->id);
+		kfree_const(id->id);
 		kfree(id);
 	}
 	kfree(pnp->unique_id);
@@ -1472,7 +1452,7 @@
 }
 
 static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
-				       char *idstr,
+				       const char *idstr,
 				       const struct acpi_device_id **matchid)
 {
 	const struct acpi_device_id *devid;
@@ -1491,7 +1471,7 @@
 	return false;
 }
 
-static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr,
+static struct acpi_scan_handler *acpi_scan_match_handler(const char *idstr,
 					const struct acpi_device_id **matchid)
 {
 	struct acpi_scan_handler *handler;
@@ -1933,3 +1913,42 @@
 	mutex_unlock(&acpi_scan_lock);
 	return result;
 }
+
+static struct acpi_probe_entry *ape;
+static int acpi_probe_count;
+static DEFINE_SPINLOCK(acpi_probe_lock);
+
+static int __init acpi_match_madt(struct acpi_subtable_header *header,
+				  const unsigned long end)
+{
+	if (!ape->subtable_valid || ape->subtable_valid(header, ape))
+		if (!ape->probe_subtbl(header, end))
+			acpi_probe_count++;
+
+	return 0;
+}
+
+int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr)
+{
+	int count = 0;
+
+	if (acpi_disabled)
+		return 0;
+
+	spin_lock(&acpi_probe_lock);
+	for (ape = ap_head; nr; ape++, nr--) {
+		if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) {
+			acpi_probe_count = 0;
+			acpi_table_parse_madt(ape->type, acpi_match_madt, 0);
+			count += acpi_probe_count;
+		} else {
+			int res;
+			res = acpi_table_parse(ape->id, ape->probe_table);
+			if (!res)
+				count++;
+		}
+	}
+	spin_unlock(&acpi_probe_lock);
+
+	return count;
+}
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 40a4265..0243d37 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -878,6 +878,9 @@
 		return result;
 
 	hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj);
+	if (!hotplug_kobj)
+		return -ENOMEM;
+
 	result = sysfs_create_file(hotplug_kobj, &force_remove_attr.attr);
 	if (result)
 		return result;
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 17a6fa0..6c0f079 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -210,20 +210,39 @@
 	}
 }
 
-int __init
-acpi_parse_entries(char *id, unsigned long table_size,
-		acpi_tbl_entry_handler handler,
+/**
+ * acpi_parse_entries_array - for each proc_num find a suitable subtable
+ *
+ * @id: table id (for debugging purposes)
+ * @table_size: single entry size
+ * @table_header: where does the table start?
+ * @proc: array of acpi_subtable_proc struct containing entry id
+ *        and associated handler with it
+ * @proc_num: how big proc is?
+ * @max_entries: how many entries can we process?
+ *
+ * For each proc_num find a subtable with proc->id and run proc->handler
+ * on it. Assumption is that there's only single handler for particular
+ * entry id.
+ *
+ * On success returns sum of all matching entries for all proc handlers.
+ * Otherwise, -ENODEV or -EINVAL is returned.
+ */
+static int __init
+acpi_parse_entries_array(char *id, unsigned long table_size,
 		struct acpi_table_header *table_header,
-		int entry_id, unsigned int max_entries)
+		struct acpi_subtable_proc *proc, int proc_num,
+		unsigned int max_entries)
 {
 	struct acpi_subtable_header *entry;
-	int count = 0;
 	unsigned long table_end;
+	int count = 0;
+	int i;
 
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (!id || !handler)
+	if (!id)
 		return -EINVAL;
 
 	if (!table_size)
@@ -243,20 +262,28 @@
 
 	while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
 	       table_end) {
-		if (entry->type == entry_id
-		    && (!max_entries || count < max_entries)) {
-			if (handler(entry, table_end))
+		if (max_entries && count >= max_entries)
+			break;
+
+		for (i = 0; i < proc_num; i++) {
+			if (entry->type != proc[i].id)
+				continue;
+			if (!proc[i].handler ||
+			     proc[i].handler(entry, table_end))
 				return -EINVAL;
 
-			count++;
+			proc->count++;
+			break;
 		}
+		if (i != proc_num)
+			count++;
 
 		/*
 		 * If entry->length is 0, break from this loop to avoid
 		 * infinite loop.
 		 */
 		if (entry->length == 0) {
-			pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+			pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id);
 			return -EINVAL;
 		}
 
@@ -266,17 +293,32 @@
 
 	if (max_entries && count > max_entries) {
 		pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
-			id, entry_id, count - max_entries, count);
+			id, proc->id, count - max_entries, count);
 	}
 
 	return count;
 }
 
 int __init
-acpi_table_parse_entries(char *id,
+acpi_parse_entries(char *id,
+			unsigned long table_size,
+			acpi_tbl_entry_handler handler,
+			struct acpi_table_header *table_header,
+			int entry_id, unsigned int max_entries)
+{
+	struct acpi_subtable_proc proc = {
+		.id		= entry_id,
+		.handler	= handler,
+	};
+
+	return acpi_parse_entries_array(id, table_size, table_header,
+			&proc, 1, max_entries);
+}
+
+int __init
+acpi_table_parse_entries_array(char *id,
 			 unsigned long table_size,
-			 int entry_id,
-			 acpi_tbl_entry_handler handler,
+			 struct acpi_subtable_proc *proc, int proc_num,
 			 unsigned int max_entries)
 {
 	struct acpi_table_header *table_header = NULL;
@@ -287,7 +329,7 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (!id || !handler)
+	if (!id)
 		return -EINVAL;
 
 	if (!strncmp(id, ACPI_SIG_MADT, 4))
@@ -299,14 +341,30 @@
 		return -ENODEV;
 	}
 
-	count = acpi_parse_entries(id, table_size, handler, table_header,
-			entry_id, max_entries);
+	count = acpi_parse_entries_array(id, table_size, table_header,
+			proc, proc_num, max_entries);
 
 	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
 	return count;
 }
 
 int __init
+acpi_table_parse_entries(char *id,
+			unsigned long table_size,
+			int entry_id,
+			acpi_tbl_entry_handler handler,
+			unsigned int max_entries)
+{
+	struct acpi_subtable_proc proc = {
+		.id		= entry_id,
+		.handler	= handler,
+	};
+
+	return acpi_table_parse_entries_array(id, table_size, &proc, 1,
+						max_entries);
+}
+
+int __init
 acpi_table_parse_madt(enum acpi_madt_type id,
 		      acpi_tbl_entry_handler handler, unsigned int max_entries)
 {
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 2922f1f..0d3a384 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -244,6 +244,15 @@
 
 	/* Non win8 machines which need native backlight nevertheless */
 	{
+	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */
+	 .callback = video_detect_force_native,
+	 .ident = "Lenovo Ideapad S405",
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
+		},
+	},
+	{
 	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
 	 .callback = video_detect_force_native,
 	 .ident = "Lenovo Ideapad Z570",
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 2d75366..de40623 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -134,7 +134,7 @@
 	if (is_of_node(fwnode))
 		return of_property_read_bool(to_of_node(fwnode), propname);
 	else if (is_acpi_node(fwnode))
-		return !acpi_dev_prop_get(to_acpi_node(fwnode), propname, NULL);
+		return !acpi_node_prop_get(fwnode, propname, NULL);
 
 	return !!pset_prop_get(to_pset(fwnode), propname);
 }
@@ -287,6 +287,28 @@
 }
 EXPORT_SYMBOL_GPL(device_property_read_string);
 
+/**
+ * device_property_match_string - find a string in an array and return index
+ * @dev: Device to get the property of
+ * @propname: Name of the property holding the array
+ * @string: String to look for
+ *
+ * Find a given string in a string array and if it is found return the
+ * index back.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not have a value,
+ *	   %-EPROTO if the property is not an array of strings,
+ *	   %-ENXIO if no suitable firmware interface is present.
+ */
+int device_property_match_string(struct device *dev, const char *propname,
+				 const char *string)
+{
+	return fwnode_property_match_string(dev_fwnode(dev), propname, string);
+}
+EXPORT_SYMBOL_GPL(device_property_match_string);
+
 #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
 	(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
 	      : of_property_count_elems_of_size((node), (propname), sizeof(type))
@@ -298,8 +320,8 @@
 		_ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
 					       _type_, _val_, _nval_); \
 	else if (is_acpi_node(_fwnode_)) \
-		_ret_ = acpi_dev_prop_read(to_acpi_node(_fwnode_), _propname_, \
-					   _proptype_, _val_, _nval_); \
+		_ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
+					    _val_, _nval_); \
 	else if (is_pset(_fwnode_)) \
 		_ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
 					     _proptype_, _val_, _nval_); \
@@ -440,8 +462,8 @@
 						      propname, val, nval) :
 			of_property_count_strings(to_of_node(fwnode), propname);
 	else if (is_acpi_node(fwnode))
-		return acpi_dev_prop_read(to_acpi_node(fwnode), propname,
-					  DEV_PROP_STRING, val, nval);
+		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
+					   val, nval);
 	else if (is_pset(fwnode))
 		return pset_prop_read_array(to_pset(fwnode), propname,
 					    DEV_PROP_STRING, val, nval);
@@ -470,8 +492,8 @@
 	if (is_of_node(fwnode))
 		return of_property_read_string(to_of_node(fwnode), propname, val);
 	else if (is_acpi_node(fwnode))
-		return acpi_dev_prop_read(to_acpi_node(fwnode), propname,
-					  DEV_PROP_STRING, val, 1);
+		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
+					   val, 1);
 
 	return pset_prop_read_array(to_pset(fwnode), propname,
 				    DEV_PROP_STRING, val, 1);
@@ -479,6 +501,52 @@
 EXPORT_SYMBOL_GPL(fwnode_property_read_string);
 
 /**
+ * fwnode_property_match_string - find a string in an array and return index
+ * @fwnode: Firmware node to get the property of
+ * @propname: Name of the property holding the array
+ * @string: String to look for
+ *
+ * Find a given string in a string array and if it is found return the
+ * index back.
+ *
+ * Return: %0 if the property was found (success),
+ *	   %-EINVAL if given arguments are not valid,
+ *	   %-ENODATA if the property does not have a value,
+ *	   %-EPROTO if the property is not an array of strings,
+ *	   %-ENXIO if no suitable firmware interface is present.
+ */
+int fwnode_property_match_string(struct fwnode_handle *fwnode,
+	const char *propname, const char *string)
+{
+	const char **values;
+	int nval, ret, i;
+
+	nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
+	if (nval < 0)
+		return nval;
+
+	values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
+	if (!values)
+		return -ENOMEM;
+
+	ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
+	if (ret < 0)
+		goto out;
+
+	ret = -ENODATA;
+	for (i = 0; i < nval; i++) {
+		if (!strcmp(values[i], string)) {
+			ret = i;
+			break;
+		}
+	}
+out:
+	kfree(values);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(fwnode_property_match_string);
+
+/**
  * device_get_next_child_node - Return the next child node handle for a device
  * @dev: Device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
@@ -493,11 +561,7 @@
 		if (node)
 			return &node->fwnode;
 	} else if (IS_ENABLED(CONFIG_ACPI)) {
-		struct acpi_device *node;
-
-		node = acpi_get_next_child(dev, to_acpi_node(child));
-		if (node)
-			return acpi_fwnode_handle(node);
+		return acpi_get_next_subnode(dev, child);
 	}
 	return NULL;
 }
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a7726db..1a9c5dc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -2,6 +2,14 @@
 
 config CLKSRC_OF
 	bool
+	select CLKSRC_PROBE
+
+config CLKSRC_ACPI
+	bool
+	select CLKSRC_PROBE
+
+config CLKSRC_PROBE
+	bool
 
 config CLKSRC_I8253
 	bool
@@ -123,6 +131,7 @@
 config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
+	select CLKSRC_ACPI if ACPI
 
 config ARM_ARCH_TIMER_EVTSTREAM
 	bool "Support for ARM architected timer event stream generation"
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 5c00863..51856d5 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_CLKSRC_OF)	+= clksrc-of.o
+obj-$(CONFIG_CLKSRC_PROBE)	+= clksrc-probe.o
 obj-$(CONFIG_ATMEL_PIT)		+= timer-atmel-pit.o
 obj-$(CONFIG_ATMEL_ST)		+= timer-atmel-st.o
 obj-$(CONFIG_ATMEL_TCB_CLKSRC)	+= tcb_clksrc.o
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index d6e3e49..c64d543 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -864,13 +864,5 @@
 	arch_timer_init();
 	return 0;
 }
-
-/* Initialize all the generic timers presented in GTDT */
-void __init acpi_generic_timer_init(void)
-{
-	if (acpi_disabled)
-		return;
-
-	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
-}
+CLOCKSOURCE_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init);
 #endif
diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-probe.c
similarity index 91%
rename from drivers/clocksource/clksrc-of.c
rename to drivers/clocksource/clksrc-probe.c
index 0093a8e..7cb6c92 100644
--- a/drivers/clocksource/clksrc-of.c
+++ b/drivers/clocksource/clksrc-probe.c
@@ -14,6 +14,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/clocksource.h>
@@ -23,7 +24,7 @@
 static const struct of_device_id __clksrc_of_table_sentinel
 	__used __section(__clksrc_of_table_end);
 
-void __init clocksource_of_init(void)
+void __init clocksource_probe(void)
 {
 	struct device_node *np;
 	const struct of_device_id *match;
@@ -38,6 +39,9 @@
 		init_func(np);
 		clocksources++;
 	}
+
+	clocksources += acpi_probe_device_table(clksrc);
+
 	if (!clocksources)
 		pr_crit("%s: no matching clocksources found\n", __func__);
 }
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index cd0391e..642fd49 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -227,3 +227,20 @@
 	  This add the CPUFreq driver support for Intel PXA2xx SOCs.
 
 	  If in doubt, say N.
+
+config ACPI_CPPC_CPUFREQ
+	tristate "CPUFreq driver based on the ACPI CPPC spec"
+	depends on ACPI
+	select ACPI_CPPC_LIB
+	default n
+	help
+	  This adds a CPUFreq driver which uses CPPC methods
+	  as described in the ACPIv5.1 spec. CPPC stands for
+	  Collaborative Processor Performance Controls. It
+	  is based on an abstract continuous scale of CPU
+	  performance values which allows the remote power
+	  processor to flexibly optimize for power and
+	  performance. CPPC relies on power management firmware
+	  support for its operation.
+
+	  If in doubt, say N.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 4134038..47a7ebb 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -76,6 +76,8 @@
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)	+= tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)	+= tegra124-cpufreq.o
 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ)	+= vexpress-spc-cpufreq.o
+obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
+
 
 ##################################################################################
 # PowerPC platform drivers
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
new file mode 100644
index 0000000..93c219f
--- /dev/null
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -0,0 +1,176 @@
+/*
+ * CPPC (Collaborative Processor Performance Control) driver for
+ * interfacing with the CPUfreq layer and governors. See
+ * cppc_acpi.c for CPPC specific methods.
+ *
+ * (C) Copyright 2014, 2015 Linaro Ltd.
+ * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#define pr_fmt(fmt)	"CPPC Cpufreq:"	fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/vmalloc.h>
+
+#include <acpi/cppc_acpi.h>
+
+/*
+ * These structs contain information parsed from per CPU
+ * ACPI _CPC structures.
+ * e.g. For each CPU the highest, lowest supported
+ * performance capabilities, desired performance level
+ * requested etc.
+ */
+static struct cpudata **all_cpu_data;
+
+static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
+		unsigned int target_freq,
+		unsigned int relation)
+{
+	struct cpudata *cpu;
+	struct cpufreq_freqs freqs;
+	int ret = 0;
+
+	cpu = all_cpu_data[policy->cpu];
+
+	cpu->perf_ctrls.desired_perf = target_freq;
+	freqs.old = policy->cur;
+	freqs.new = target_freq;
+
+	cpufreq_freq_transition_begin(policy, &freqs);
+	ret = cppc_set_perf(cpu->cpu, &cpu->perf_ctrls);
+	cpufreq_freq_transition_end(policy, &freqs, ret != 0);
+
+	if (ret)
+		pr_debug("Failed to set target on CPU:%d. ret:%d\n",
+				cpu->cpu, ret);
+
+	return ret;
+}
+
+static int cppc_verify_policy(struct cpufreq_policy *policy)
+{
+	cpufreq_verify_within_cpu_limits(policy);
+	return 0;
+}
+
+static void cppc_cpufreq_stop_cpu(struct cpufreq_policy *policy)
+{
+	int cpu_num = policy->cpu;
+	struct cpudata *cpu = all_cpu_data[cpu_num];
+	int ret;
+
+	cpu->perf_ctrls.desired_perf = cpu->perf_caps.lowest_perf;
+
+	ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls);
+	if (ret)
+		pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n",
+				cpu->perf_caps.lowest_perf, cpu_num, ret);
+}
+
+static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpudata *cpu;
+	unsigned int cpu_num = policy->cpu;
+	int ret = 0;
+
+	cpu = all_cpu_data[policy->cpu];
+
+	cpu->cpu = cpu_num;
+	ret = cppc_get_perf_caps(policy->cpu, &cpu->perf_caps);
+
+	if (ret) {
+		pr_debug("Err reading CPU%d perf capabilities. ret:%d\n",
+				cpu_num, ret);
+		return ret;
+	}
+
+	policy->min = cpu->perf_caps.lowest_perf;
+	policy->max = cpu->perf_caps.highest_perf;
+	policy->cpuinfo.min_freq = policy->min;
+	policy->cpuinfo.max_freq = policy->max;
+
+	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+		cpumask_copy(policy->cpus, cpu->shared_cpu_map);
+	else {
+		/* Support only SW_ANY for now. */
+		pr_debug("Unsupported CPU co-ord type\n");
+		return -EFAULT;
+	}
+
+	cpumask_set_cpu(policy->cpu, policy->cpus);
+	cpu->cur_policy = policy;
+
+	/* Set policy->cur to max now. The governors will adjust later. */
+	policy->cur = cpu->perf_ctrls.desired_perf = cpu->perf_caps.highest_perf;
+
+	ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls);
+	if (ret)
+		pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n",
+				cpu->perf_caps.highest_perf, cpu_num, ret);
+
+	return ret;
+}
+
+static struct cpufreq_driver cppc_cpufreq_driver = {
+	.flags = CPUFREQ_CONST_LOOPS,
+	.verify = cppc_verify_policy,
+	.target = cppc_cpufreq_set_target,
+	.init = cppc_cpufreq_cpu_init,
+	.stop_cpu = cppc_cpufreq_stop_cpu,
+	.name = "cppc_cpufreq",
+};
+
+static int __init cppc_cpufreq_init(void)
+{
+	int i, ret = 0;
+	struct cpudata *cpu;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	all_cpu_data = kzalloc(sizeof(void *) * num_possible_cpus(), GFP_KERNEL);
+	if (!all_cpu_data)
+		return -ENOMEM;
+
+	for_each_possible_cpu(i) {
+		all_cpu_data[i] = kzalloc(sizeof(struct cpudata), GFP_KERNEL);
+		if (!all_cpu_data[i])
+			goto out;
+
+		cpu = all_cpu_data[i];
+		if (!zalloc_cpumask_var(&cpu->shared_cpu_map, GFP_KERNEL))
+			goto out;
+	}
+
+	ret = acpi_get_psd_map(all_cpu_data);
+	if (ret) {
+		pr_debug("Error parsing PSD data. Aborting cpufreq registration.\n");
+		goto out;
+	}
+
+	ret = cpufreq_register_driver(&cppc_cpufreq_driver);
+	if (ret)
+		goto out;
+
+	return ret;
+
+out:
+	for_each_possible_cpu(i)
+		if (all_cpu_data[i])
+			kfree(all_cpu_data[i]);
+
+	kfree(all_cpu_data);
+	return -ENODEV;
+}
+
+late_initcall(cppc_cpufreq_init);
diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c
index 5a63564..981a38f 100644
--- a/drivers/dma/acpi-dma.c
+++ b/drivers/dma/acpi-dma.c
@@ -21,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/acpi.h>
 #include <linux/acpi_dma.h>
+#include <linux/property.h>
 
 static LIST_HEAD(acpi_dma_list);
 static DEFINE_MUTEX(acpi_dma_lock);
@@ -413,21 +414,29 @@
  * translate the names "tx" and "rx" here based on the most common case where
  * the first FixedDMA descriptor is TX and second is RX.
  *
+ * If the device has "dma-names" property the FixedDMA descriptor indices
+ * are retrieved based on those. Otherwise the function falls back using
+ * hardcoded indices.
+ *
  * Return:
  * Pointer to appropriate dma channel on success or an error pointer.
  */
 struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev,
 		const char *name)
 {
-	size_t index;
+	int index;
 
-	if (!strcmp(name, "tx"))
-		index = 0;
-	else if (!strcmp(name, "rx"))
-		index = 1;
-	else
-		return ERR_PTR(-ENODEV);
+	index = device_property_match_string(dev, "dma-names", name);
+	if (index < 0) {
+		if (!strcmp(name, "tx"))
+			index = 0;
+		else if (!strcmp(name, "rx"))
+			index = 1;
+		else
+			return ERR_PTR(-ENODEV);
+	}
 
+	dev_dbg(dev, "found DMA channel \"%s\" at index %d\n", name, index);
 	return acpi_dma_request_slave_chan_by_index(dev, index);
 }
 EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_name);
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 143a9bd..69a8362 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -389,6 +389,8 @@
 	struct acpi_gpio_info info;
 	int index;
 	int pin_index;
+	bool active_low;
+	struct acpi_device *adev;
 	struct gpio_desc *desc;
 	int n;
 };
@@ -425,6 +427,65 @@
 	return 1;
 }
 
+static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup,
+				     struct acpi_gpio_info *info)
+{
+	struct list_head res_list;
+	int ret;
+
+	INIT_LIST_HEAD(&res_list);
+
+	ret = acpi_dev_get_resources(lookup->adev, &res_list, acpi_find_gpio,
+				     lookup);
+	if (ret < 0)
+		return ret;
+
+	acpi_dev_free_resource_list(&res_list);
+
+	if (!lookup->desc)
+		return -ENOENT;
+
+	if (info) {
+		*info = lookup->info;
+		if (lookup->active_low)
+			info->active_low = lookup->active_low;
+	}
+	return 0;
+}
+
+static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
+				     const char *propname, int index,
+				     struct acpi_gpio_lookup *lookup)
+{
+	struct acpi_reference_args args;
+	int ret;
+
+	memset(&args, 0, sizeof(args));
+	ret = acpi_node_get_property_reference(fwnode, propname, index, &args);
+	if (ret) {
+		struct acpi_device *adev = to_acpi_device_node(fwnode);
+
+		if (!adev)
+			return ret;
+
+		if (!acpi_get_driver_gpio_data(adev, propname, index, &args))
+			return ret;
+	}
+	/*
+	 * The property was found and resolved, so need to lookup the GPIO based
+	 * on returned args.
+	 */
+	lookup->adev = args.adev;
+	if (args.nargs >= 2) {
+		lookup->index = args.args[0];
+		lookup->pin_index = args.args[1];
+		/* 3rd argument, if present is used to specify active_low. */
+		if (args.nargs >= 3)
+			lookup->active_low = !!args.args[2];
+	}
+	return 0;
+}
+
 /**
  * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
  * @adev: pointer to a ACPI device to get GPIO from
@@ -452,8 +513,6 @@
 					  struct acpi_gpio_info *info)
 {
 	struct acpi_gpio_lookup lookup;
-	struct list_head resource_list;
-	bool active_low = false;
 	int ret;
 
 	if (!adev)
@@ -463,58 +522,64 @@
 	lookup.index = index;
 
 	if (propname) {
-		struct acpi_reference_args args;
-
 		dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
 
-		memset(&args, 0, sizeof(args));
-		ret = acpi_dev_get_property_reference(adev, propname,
-						      index, &args);
-		if (ret) {
-			bool found = acpi_get_driver_gpio_data(adev, propname,
-							       index, &args);
-			if (!found)
-				return ERR_PTR(ret);
-		}
+		ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev),
+						propname, index, &lookup);
+		if (ret)
+			return ERR_PTR(ret);
 
-		/*
-		 * The property was found and resolved so need to
-		 * lookup the GPIO based on returned args instead.
-		 */
-		adev = args.adev;
-		if (args.nargs >= 2) {
-			lookup.index = args.args[0];
-			lookup.pin_index = args.args[1];
-			/*
-			 * 3rd argument, if present is used to
-			 * specify active_low.
-			 */
-			if (args.nargs >= 3)
-				active_low = !!args.args[2];
-		}
-
-		dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
-			dev_name(&adev->dev), args.nargs,
-			args.args[0], args.args[1], args.args[2]);
+		dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n",
+			dev_name(&lookup.adev->dev), lookup.index,
+			lookup.pin_index, lookup.active_low);
 	} else {
 		dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
+		lookup.adev = adev;
 	}
 
-	INIT_LIST_HEAD(&resource_list);
-	ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
-				     &lookup);
-	if (ret < 0)
+	ret = acpi_gpio_resource_lookup(&lookup, info);
+	return ret ? ERR_PTR(ret) : lookup.desc;
+}
+
+/**
+ * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
+ * @fwnode: pointer to an ACPI firmware node to get the GPIO information from
+ * @propname: Property name of the GPIO
+ * @index: index of GpioIo/GpioInt resource (starting from %0)
+ * @info: info pointer to fill in (optional)
+ *
+ * If @fwnode is an ACPI device object, call %acpi_get_gpiod_by_index() for it.
+ * Otherwise (ie. it is a data-only non-device object), use the property-based
+ * GPIO lookup to get to the GPIO resource with the relevant information and use
+ * that to obtain the GPIO descriptor to return.
+ */
+struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+				      const char *propname, int index,
+				      struct acpi_gpio_info *info)
+{
+	struct acpi_gpio_lookup lookup;
+	struct acpi_device *adev;
+	int ret;
+
+	adev = to_acpi_device_node(fwnode);
+	if (adev)
+		return acpi_get_gpiod_by_index(adev, propname, index, info);
+
+	if (!is_acpi_data_node(fwnode))
+		return ERR_PTR(-ENODEV);
+
+	if (!propname)
+		return ERR_PTR(-EINVAL);
+
+	memset(&lookup, 0, sizeof(lookup));
+	lookup.index = index;
+
+	ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup);
+	if (ret)
 		return ERR_PTR(ret);
 
-	acpi_dev_free_resource_list(&resource_list);
-
-	if (lookup.desc && info) {
-		*info = lookup.info;
-		if (active_low)
-			info->active_low = active_low;
-	}
-
-	return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
+	ret = acpi_gpio_resource_lookup(&lookup, info);
+	return ret ? ERR_PTR(ret) : lookup.desc;
 }
 
 /**
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5db3445..c52a70f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2093,8 +2093,7 @@
 	} else if (is_acpi_node(fwnode)) {
 		struct acpi_gpio_info info;
 
-		desc = acpi_get_gpiod_by_index(to_acpi_node(fwnode), propname, 0,
-					       &info);
+		desc = acpi_node_get_gpiod(fwnode, propname, 0, &info);
 		if (!IS_ERR(desc))
 			active_low = info.active_low;
 	}
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index bf34300..e69c715 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -42,6 +42,9 @@
 struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
 					  const char *propname, int index,
 					  struct acpi_gpio_info *info);
+struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+				      const char *propname, int index,
+				      struct acpi_gpio_info *info);
 
 int acpi_gpio_count(struct device *dev, const char *con_id);
 #else
@@ -60,7 +63,12 @@
 {
 	return ERR_PTR(-ENOSYS);
 }
-
+static inline struct gpio_desc *
+acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
+		    int index, struct acpi_gpio_info *info)
+{
+	return ERR_PTR(-ENXIO);
+}
 static inline int acpi_gpio_count(struct device *dev, const char *con_id)
 {
 	return -ENODEV;
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 982c09c..d4add30 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -41,7 +41,6 @@
 #include <linux/irqchip.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqchip/arm-gic.h>
-#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -1195,7 +1194,7 @@
 #endif
 
 #ifdef CONFIG_ACPI
-static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
+static phys_addr_t cpu_phy_base __initdata;
 
 static int __init
 gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
@@ -1223,60 +1222,56 @@
 	return 0;
 }
 
-static int __init
-gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-				const unsigned long end)
+/* The things you have to do to just *count* something... */
+static int __init acpi_dummy_func(struct acpi_subtable_header *header,
+				  const unsigned long end)
 {
-	struct acpi_madt_generic_distributor *dist;
-
-	dist = (struct acpi_madt_generic_distributor *)header;
-
-	if (BAD_MADT_ENTRY(dist, end))
-		return -EINVAL;
-
-	dist_phy_base = dist->base_address;
 	return 0;
 }
 
-int __init
-gic_v2_acpi_init(struct acpi_table_header *table)
+static bool __init acpi_gic_redist_is_present(void)
 {
+	return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+				     acpi_dummy_func, 0) > 0;
+}
+
+static bool __init gic_validate_dist(struct acpi_subtable_header *header,
+				     struct acpi_probe_entry *ape)
+{
+	struct acpi_madt_generic_distributor *dist;
+	dist = (struct acpi_madt_generic_distributor *)header;
+
+	return (dist->version == ape->driver_data &&
+		(dist->version != ACPI_MADT_GIC_VERSION_NONE ||
+		 !acpi_gic_redist_is_present()));
+}
+
+#define ACPI_GICV2_DIST_MEM_SIZE	(SZ_4K)
+#define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
+
+static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
+				   const unsigned long end)
+{
+	struct acpi_madt_generic_distributor *dist;
 	void __iomem *cpu_base, *dist_base;
 	int count;
 
 	/* Collect CPU base addresses */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				   sizeof(struct acpi_table_madt),
-				   gic_acpi_parse_madt_cpu, table,
-				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+				      gic_acpi_parse_madt_cpu, 0);
 	if (count <= 0) {
 		pr_err("No valid GICC entries exist\n");
 		return -EINVAL;
 	}
 
-	/*
-	 * Find distributor base address. We expect one distributor entry since
-	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
-	 */
-	count = acpi_parse_entries(ACPI_SIG_MADT,
-				   sizeof(struct acpi_table_madt),
-				   gic_acpi_parse_madt_distributor, table,
-				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-	if (count <= 0) {
-		pr_err("No valid GICD entries exist\n");
-		return -EINVAL;
-	} else if (count > 1) {
-		pr_err("More than one GICD entry detected\n");
-		return -EINVAL;
-	}
-
 	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
 	if (!cpu_base) {
 		pr_err("Unable to map GICC registers\n");
 		return -ENOMEM;
 	}
 
-	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
+	dist = (struct acpi_madt_generic_distributor *)header;
+	dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE);
 	if (!dist_base) {
 		pr_err("Unable to map GICD registers\n");
 		iounmap(cpu_base);
@@ -1302,4 +1297,10 @@
 	acpi_irq_model = ACPI_IRQ_MODEL_GIC;
 	return 0;
 }
+IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+		     gic_validate_dist, ACPI_MADT_GIC_VERSION_V2,
+		     gic_v2_acpi_init);
+IRQCHIP_ACPI_DECLARE(gic_v2_maybe, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+		     gic_validate_dist, ACPI_MADT_GIC_VERSION_NONE,
+		     gic_v2_acpi_init);
 #endif
diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c
index afd1af3..2b35e68 100644
--- a/drivers/irqchip/irqchip.c
+++ b/drivers/irqchip/irqchip.c
@@ -8,7 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/acpi_irq.h>
+#include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/of_irq.h>
 #include <linux/irqchip.h>
@@ -27,6 +27,5 @@
 void __init irqchip_init(void)
 {
 	of_irq_init(__irqchip_of_table);
-
-	acpi_irq_init();
+	acpi_probe_device_table(irqchip);
 }
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 5153d1d..9113876 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -207,7 +207,7 @@
 };
 EXPORT_SYMBOL(pnpacpi_protocol);
 
-static char *__init pnpacpi_get_id(struct acpi_device *device)
+static const char *__init pnpacpi_get_id(struct acpi_device *device)
 {
 	struct acpi_hardware_id *id;
 
@@ -222,7 +222,7 @@
 static int __init pnpacpi_add_device(struct acpi_device *device)
 {
 	struct pnp_dev *dev;
-	char *pnpid;
+	const char *pnpid;
 	struct acpi_hardware_id *id;
 	int error;
 
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 9f20eb4a..204f581 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -193,8 +193,9 @@
 #define AE_AML_ILLEGAL_ADDRESS          EXCEP_AML (0x0020)
 #define AE_AML_INFINITE_LOOP            EXCEP_AML (0x0021)
 #define AE_AML_UNINITIALIZED_NODE       EXCEP_AML (0x0022)
+#define AE_AML_TARGET_TYPE              EXCEP_AML (0x0023)
 
-#define AE_CODE_AML_MAX                 0x0022
+#define AE_CODE_AML_MAX                 0x0023
 
 /*
  * Internal exceptions used for control
@@ -358,7 +359,9 @@
 	EXCEP_TXT("AE_AML_INFINITE_LOOP",
 		  "An apparent infinite AML While loop, method was aborted"),
 	EXCEP_TXT("AE_AML_UNINITIALIZED_NODE",
-		  "A namespace node is uninitialized or unresolved")
+		  "A namespace node is uninitialized or unresolved"),
+	EXCEP_TXT("AE_AML_TARGET_TYPE",
+		  "A target operand of an incorrect type was encountered")
 };
 
 static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 5ba8fb6..d11eff8 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -129,7 +129,7 @@
 struct acpi_scan_handler {
 	const struct acpi_device_id *ids;
 	struct list_head list_node;
-	bool (*match)(char *idstr, const struct acpi_device_id **matchid);
+	bool (*match)(const char *idstr, const struct acpi_device_id **matchid);
 	int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
 	void (*detach)(struct acpi_device *dev);
 	void (*bind)(struct device *phys_dev);
@@ -227,7 +227,7 @@
 
 struct acpi_hardware_id {
 	struct list_head list;
-	char *id;
+	const char *id;
 };
 
 struct acpi_pnp_type {
@@ -343,6 +343,7 @@
 	const union acpi_object *pointer;
 	const union acpi_object *properties;
 	const union acpi_object *of_compatible;
+	struct list_head subnodes;
 };
 
 struct acpi_gpio_mapping;
@@ -378,6 +379,17 @@
 	void (*remove)(struct acpi_device *);
 };
 
+/* Non-device subnode */
+struct acpi_data_node {
+	const char *name;
+	acpi_handle handle;
+	struct fwnode_handle fwnode;
+	struct acpi_device_data data;
+	struct list_head sibling;
+	struct kobject kobj;
+	struct completion kobj_done;
+};
+
 static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 {
 	bool ret = false;
@@ -413,15 +425,32 @@
 
 static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 {
+	return fwnode && (fwnode->type == FWNODE_ACPI
+		|| fwnode->type == FWNODE_ACPI_DATA);
+}
+
+static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
+{
 	return fwnode && fwnode->type == FWNODE_ACPI;
 }
 
-static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode)
+static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
 {
-	return is_acpi_node(fwnode) ?
+	return is_acpi_device_node(fwnode) ?
 		container_of(fwnode, struct acpi_device, fwnode) : NULL;
 }
 
+static inline bool is_acpi_data_node(struct fwnode_handle *fwnode)
+{
+	return fwnode && fwnode->type == FWNODE_ACPI_DATA;
+}
+
+static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode)
+{
+	return is_acpi_data_node(fwnode) ?
+		container_of(fwnode, struct acpi_data_node, fwnode) : NULL;
+}
+
 static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
 {
 	return &adev->fwnode;
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index a54ad1c..fbc2baf 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -55,7 +55,8 @@
 	OSL_GLOBAL_LOCK_HANDLER,
 	OSL_NOTIFY_HANDLER,
 	OSL_GPE_HANDLER,
-	OSL_DEBUGGER_THREAD,
+	OSL_DEBUGGER_MAIN_THREAD,
+	OSL_DEBUGGER_EXEC_THREAD,
 	OSL_EC_POLL_HANDLER,
 	OSL_EC_BURST_HANDLER
 } acpi_execute_type;
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index c33eeab..3aaaa86 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20150818
+#define ACPI_CA_VERSION                 0x20150930
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
@@ -393,15 +393,11 @@
  */
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_subsystem_status(void))
-#endif
 
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			    acpi_get_system_info(struct acpi_buffer
 						 *ret_buffer))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_get_statistics(struct acpi_statistics *stats))
 ACPI_EXTERNAL_RETURN_PTR(const char
@@ -625,11 +621,9 @@
 							       space_id,
 							       acpi_adr_space_handler
 							       handler))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_install_exception_handler
 			     (acpi_exception_handler handler))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_install_interface_handler
 			     (acpi_interface_handler handler))
@@ -750,12 +744,10 @@
 			     acpi_get_current_resources(acpi_handle device,
 							struct acpi_buffer
 							*ret_buffer))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_get_possible_resources(acpi_handle device,
 							 struct acpi_buffer
 							 *ret_buffer))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_get_event_resources(acpi_handle device_handle,
 						      struct acpi_buffer
@@ -844,7 +836,6 @@
 /*
  * ACPI Timer interfaces
  */
-#ifdef ACPI_FUTURE_USAGE
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 				acpi_get_timer_resolution(u32 *resolution))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks))
@@ -853,7 +844,6 @@
 				acpi_get_timer_duration(u32 start_ticks,
 							u32 end_ticks,
 							u32 *time_elapsed))
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * Error/Warning output
@@ -939,4 +929,6 @@
 					       void **data,
 					       void (*callback)(void *)))
 
+void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
+
 #endif				/* __ACXFACE_H__ */
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index fcd5709..1bb979e 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -1012,7 +1012,7 @@
 #define ACPI_NFIT_MEM_SAVE_FAILED       (1)	/* 00: Last SAVE to Memory Device failed */
 #define ACPI_NFIT_MEM_RESTORE_FAILED    (1<<1)	/* 01: Last RESTORE from Memory Device failed */
 #define ACPI_NFIT_MEM_FLUSH_FAILED      (1<<2)	/* 02: Platform flush failed */
-#define ACPI_NFIT_MEM_ARMED             (1<<3)	/* 03: Memory Device observed to be not armed */
+#define ACPI_NFIT_MEM_NOT_ARMED         (1<<3)	/* 03: Memory Device is not armed */
 #define ACPI_NFIT_MEM_HEALTH_OBSERVED   (1<<4)	/* 04: Memory Device observed SMART/health events */
 #define ACPI_NFIT_MEM_HEALTH_ENABLED    (1<<5)	/* 05: SMART/health events enabled */
 
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
new file mode 100644
index 0000000..717a298
--- /dev/null
+++ b/include/acpi/cppc_acpi.h
@@ -0,0 +1,138 @@
+/*
+ * CPPC (Collaborative Processor Performance Control) methods used
+ * by CPUfreq drivers.
+ *
+ * (C) Copyright 2014, 2015 Linaro Ltd.
+ * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef _CPPC_ACPI_H
+#define _CPPC_ACPI_H
+
+#include <linux/acpi.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+#include <linux/types.h>
+
+#include <acpi/processor.h>
+
+/* Only support CPPCv2 for now. */
+#define CPPC_NUM_ENT	21
+#define CPPC_REV	2
+
+#define PCC_CMD_COMPLETE 1
+#define MAX_CPC_REG_ENT 19
+
+/* CPPC specific PCC commands. */
+#define	CMD_READ 0
+#define	CMD_WRITE 1
+
+/* Each register has the folowing format. */
+struct cpc_reg {
+	u8 descriptor;
+	u16 length;
+	u8 space_id;
+	u8 bit_width;
+	u8 bit_offset;
+	u8 access_width;
+	u64 __iomem address;
+} __packed;
+
+/*
+ * Each entry in the CPC table is either
+ * of type ACPI_TYPE_BUFFER or
+ * ACPI_TYPE_INTEGER.
+ */
+struct cpc_register_resource {
+	acpi_object_type type;
+	union {
+		struct cpc_reg reg;
+		u64 int_value;
+	} cpc_entry;
+};
+
+/* Container to hold the CPC details for each CPU */
+struct cpc_desc {
+	int num_entries;
+	int version;
+	int cpu_id;
+	struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
+	struct acpi_psd_package domain_info;
+};
+
+/* These are indexes into the per-cpu cpc_regs[]. Order is important. */
+enum cppc_regs {
+	HIGHEST_PERF,
+	NOMINAL_PERF,
+	LOW_NON_LINEAR_PERF,
+	LOWEST_PERF,
+	GUARANTEED_PERF,
+	DESIRED_PERF,
+	MIN_PERF,
+	MAX_PERF,
+	PERF_REDUC_TOLERANCE,
+	TIME_WINDOW,
+	CTR_WRAP_TIME,
+	REFERENCE_CTR,
+	DELIVERED_CTR,
+	PERF_LIMITED,
+	ENABLE,
+	AUTO_SEL_ENABLE,
+	AUTO_ACT_WINDOW,
+	ENERGY_PERF,
+	REFERENCE_PERF,
+};
+
+/*
+ * Categorization of registers as described
+ * in the ACPI v.5.1 spec.
+ * XXX: Only filling up ones which are used by governors
+ * today.
+ */
+struct cppc_perf_caps {
+	u32 highest_perf;
+	u32 nominal_perf;
+	u32 reference_perf;
+	u32 lowest_perf;
+};
+
+struct cppc_perf_ctrls {
+	u32 max_perf;
+	u32 min_perf;
+	u32 desired_perf;
+};
+
+struct cppc_perf_fb_ctrs {
+	u64 reference;
+	u64 prev_reference;
+	u64 delivered;
+	u64 prev_delivered;
+};
+
+/* Per CPU container for runtime CPPC management. */
+struct cpudata {
+	int cpu;
+	struct cppc_perf_caps perf_caps;
+	struct cppc_perf_ctrls perf_ctrls;
+	struct cppc_perf_fb_ctrs perf_fb_ctrs;
+	struct cpufreq_policy *cur_policy;
+	unsigned int shared_type;
+	cpumask_var_t shared_cpu_map;
+};
+
+extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
+extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
+extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
+extern int acpi_get_psd_map(struct cpudata **);
+
+/* Methods to interact with the PCC mailbox controller. */
+extern struct mbox_chan *
+	pcc_mbox_request_channel(struct mbox_client *, unsigned int);
+extern int mbox_send_message(struct mbox_chan *chan, void *mssg);
+
+#endif /* _CPPC_ACPI_H*/
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index ec00e2b..056f245 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -142,7 +142,7 @@
 
 #ifdef ACPI_LIBRARY
 #define ACPI_USE_LOCAL_CACHE
-#define ACPI_FUTURE_USAGE
+#define ACPI_FULL_DEBUG
 #endif
 
 /* Common for all ACPICA applications */
@@ -304,11 +304,11 @@
  * multi-threaded if ACPI_APPLICATION is not set.
  */
 #ifndef DEBUGGER_THREADING
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
+#if !defined (ACPI_APPLICATION) || defined (ACPI_EXEC_APP)
+#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
 
 #else
-#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
+#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
 #endif
 #endif				/* !DEBUGGER_THREADING */
 
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 74ba46c8..323e5da 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -63,12 +63,16 @@
 
 #define ACPI_USE_SYSTEM_INTTYPES
 
-/* Compile for reduced hardware mode only with this kernel config */
+/* Kernel specific ACPICA configuration */
 
 #ifdef CONFIG_ACPI_REDUCED_HARDWARE_ONLY
 #define ACPI_REDUCED_HARDWARE 1
 #endif
 
+#ifdef CONFIG_ACPI_DEBUGGER
+#define ACPI_DEBUGGER
+#endif
+
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
@@ -151,7 +155,6 @@
  * OSL interfaces used by utilities
  */
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_name
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_index
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_address
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h
index acedc3f..fd6d70f 100644
--- a/include/acpi/platform/aclinuxex.h
+++ b/include/acpi/platform/aclinuxex.h
@@ -124,6 +124,11 @@
 		lock ? AE_OK : AE_NO_MEMORY; \
 	})
 
+static inline u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return TRUE;
+}
+
 /*
  * OSL interfaces added by Linux
  */
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index ff5f135..07fb100 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -311,6 +311,20 @@
 int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id);
 int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
 
+#ifdef CONFIG_ACPI_CPPC_LIB
+extern int acpi_cppc_processor_probe(struct acpi_processor *pr);
+extern void acpi_cppc_processor_exit(struct acpi_processor *pr);
+#else
+static inline int acpi_cppc_processor_probe(struct acpi_processor *pr)
+{
+	return 0;
+}
+static inline void acpi_cppc_processor_exit(struct acpi_processor *pr)
+{
+	return;
+}
+#endif	/* CONFIG_ACPI_CPPC_LIB */
+
 /* in processor_pdc.c */
 void acpi_processor_set_pdc(acpi_handle handle);
 
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 1781e54..c4bd0e2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -181,6 +181,16 @@
 #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
 #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
 
+#ifdef CONFIG_ACPI
+#define ACPI_PROBE_TABLE(name)						\
+	. = ALIGN(8);							\
+	VMLINUX_SYMBOL(__##name##_acpi_probe_table) = .;		\
+	*(__##name##_acpi_probe_table)					\
+	VMLINUX_SYMBOL(__##name##_acpi_probe_table_end) = .;
+#else
+#define ACPI_PROBE_TABLE(name)
+#endif
+
 #define KERNEL_DTB()							\
 	STRUCT_ALIGN();							\
 	VMLINUX_SYMBOL(__dtb_start) = .;				\
@@ -514,6 +524,8 @@
 	CPUIDLE_METHOD_OF_TABLES()					\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
+	ACPI_PROBE_TABLE(irqchip)					\
+	ACPI_PROBE_TABLE(clksrc)					\
 	EARLYCON_TABLE()						\
 	EARLYCON_OF_TABLES()
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 1ae6ba0..82f56bb 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -49,7 +49,7 @@
 	return adev ? adev->handle : NULL;
 }
 
-#define ACPI_COMPANION(dev)		to_acpi_node((dev)->fwnode)
+#define ACPI_COMPANION(dev)		to_acpi_device_node((dev)->fwnode)
 #define ACPI_COMPANION_SET(dev, adev)	set_primary_fwnode(dev, (adev) ? \
 	acpi_fwnode_handle(adev) : NULL)
 #define ACPI_HANDLE(dev)		acpi_device_handle(ACPI_COMPANION(dev))
@@ -69,7 +69,7 @@
 
 static inline bool has_acpi_companion(struct device *dev)
 {
-	return is_acpi_node(dev->fwnode);
+	return is_acpi_device_node(dev->fwnode);
 }
 
 static inline void acpi_preset_companion(struct device *dev,
@@ -131,6 +131,12 @@
 		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
 		((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
 
+struct acpi_subtable_proc {
+	int id;
+	acpi_tbl_entry_handler handler;
+	int count;
+};
+
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
 int early_acpi_boot_init(void);
@@ -146,9 +152,16 @@
 			      struct acpi_table_header *table_header,
 			      int entry_id, unsigned int max_entries);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
-				    int entry_id,
-				    acpi_tbl_entry_handler handler,
-				    unsigned int max_entries);
+			      int entry_id,
+			      acpi_tbl_entry_handler handler,
+			      unsigned int max_entries);
+int __init acpi_table_parse_entries(char *id, unsigned long table_size,
+			      int entry_id,
+			      acpi_tbl_entry_handler handler,
+			      unsigned int max_entries);
+int __init acpi_table_parse_entries_array(char *id, unsigned long table_size,
+			      struct acpi_subtable_proc *proc, int proc_num,
+			      unsigned int max_entries);
 int acpi_table_parse_madt(enum acpi_madt_type id,
 			  acpi_tbl_entry_handler handler,
 			  unsigned int max_entries);
@@ -468,7 +481,22 @@
 	return false;
 }
 
-static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode)
+static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
+{
+	return false;
+}
+
+static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
+{
+	return NULL;
+}
+
+static inline bool is_acpi_data_node(struct fwnode_handle *fwnode)
+{
+	return false;
+}
+
+static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode)
 {
 	return NULL;
 }
@@ -750,22 +778,76 @@
 #ifdef CONFIG_ACPI
 int acpi_dev_get_property(struct acpi_device *adev, const char *name,
 			  acpi_object_type type, const union acpi_object **obj);
-int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
-				acpi_object_type type,
-				const union acpi_object **obj);
-int acpi_dev_get_property_reference(struct acpi_device *adev,
-				    const char *name, size_t index,
-				    struct acpi_reference_args *args);
+int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+				     const char *name, size_t index,
+				     struct acpi_reference_args *args);
 
-int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
-		      void **valptr);
+int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
+		       void **valptr);
 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
 			      enum dev_prop_type proptype, void *val);
+int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname,
+		        enum dev_prop_type proptype, void *val, size_t nval);
 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
 		       enum dev_prop_type proptype, void *val, size_t nval);
 
-struct acpi_device *acpi_get_next_child(struct device *dev,
-					struct acpi_device *child);
+struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+					    struct fwnode_handle *subnode);
+
+struct acpi_probe_entry;
+typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *,
+						 struct acpi_probe_entry *);
+
+#define ACPI_TABLE_ID_LEN	5
+
+/**
+ * struct acpi_probe_entry - boot-time probing entry
+ * @id:			ACPI table name
+ * @type:		Optional subtable type to match
+ *			(if @id contains subtables)
+ * @subtable_valid:	Optional callback to check the validity of
+ *			the subtable
+ * @probe_table:	Callback to the driver being probed when table
+ *			match is successful
+ * @probe_subtbl:	Callback to the driver being probed when table and
+ *			subtable match (and optional callback is successful)
+ * @driver_data:	Sideband data provided back to the driver
+ */
+struct acpi_probe_entry {
+	__u8 id[ACPI_TABLE_ID_LEN];
+	__u8 type;
+	acpi_probe_entry_validate_subtbl subtable_valid;
+	union {
+		acpi_tbl_table_handler probe_table;
+		acpi_tbl_entry_handler probe_subtbl;
+	};
+	kernel_ulong_t driver_data;
+};
+
+#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn)	\
+	static const struct acpi_probe_entry __acpi_probe_##name	\
+		__used __section(__##table##_acpi_probe_table)		\
+		 = {							\
+			.id = table_id,					\
+			.type = subtable,				\
+			.subtable_valid = valid,			\
+			.probe_table = (acpi_tbl_table_handler)fn,	\
+			.driver_data = data, 				\
+		   }
+
+#define ACPI_PROBE_TABLE(name)		__##name##_acpi_probe_table
+#define ACPI_PROBE_TABLE_END(name)	__##name##_acpi_probe_table_end
+
+int __acpi_probe_device_table(struct acpi_probe_entry *start, int nr);
+
+#define acpi_probe_device_table(t)					\
+	({ 								\
+		extern struct acpi_probe_entry ACPI_PROBE_TABLE(t),	\
+			                       ACPI_PROBE_TABLE_END(t);	\
+		__acpi_probe_device_table(&ACPI_PROBE_TABLE(t),		\
+					  (&ACPI_PROBE_TABLE_END(t) -	\
+					   &ACPI_PROBE_TABLE(t)));	\
+	})
 #else
 static inline int acpi_dev_get_property(struct acpi_device *adev,
 					const char *name, acpi_object_type type,
@@ -773,16 +855,17 @@
 {
 	return -ENXIO;
 }
-static inline int acpi_dev_get_property_array(struct acpi_device *adev,
-					      const char *name,
-					      acpi_object_type type,
-					      const union acpi_object **obj)
+
+static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+				const char *name, const char *cells_name,
+				size_t index, struct acpi_reference_args *args)
 {
 	return -ENXIO;
 }
-static inline int acpi_dev_get_property_reference(struct acpi_device *adev,
-				const char *name, const char *cells_name,
-				size_t index, struct acpi_reference_args *args)
+
+static inline int acpi_node_prop_get(struct fwnode_handle *fwnode,
+				     const char *propname,
+				     void **valptr)
 {
 	return -ENXIO;
 }
@@ -802,6 +885,14 @@
 	return -ENXIO;
 }
 
+static inline int acpi_node_prop_read(struct fwnode_handle *fwnode,
+				      const char *propname,
+				      enum dev_prop_type proptype,
+				      void *val, size_t nval)
+{
+	return -ENXIO;
+}
+
 static inline int acpi_dev_prop_read(struct acpi_device *adev,
 				     const char *propname,
 				     enum dev_prop_type proptype,
@@ -810,12 +901,22 @@
 	return -ENXIO;
 }
 
-static inline struct acpi_device *acpi_get_next_child(struct device *dev,
-						      struct acpi_device *child)
+static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+						struct fwnode_handle *subnode)
 {
 	return NULL;
 }
 
+#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, validate, data, fn) \
+	static const void * __acpi_table_##name[]			\
+		__attribute__((unused))					\
+		 = { (void *) table_id,					\
+		     (void *) subtable,					\
+		     (void *) valid,					\
+		     (void *) fn,					\
+		     (void *) data }
+
+#define acpi_probe_device_table(t)	({ int __r = 0; __r;})
 #endif
 
 #endif	/*_LINUX_ACPI_H*/
diff --git a/include/linux/acpi_irq.h b/include/linux/acpi_irq.h
deleted file mode 100644
index f10c872..0000000
--- a/include/linux/acpi_irq.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _LINUX_ACPI_IRQ_H
-#define _LINUX_ACPI_IRQ_H
-
-#include <linux/irq.h>
-
-#ifndef acpi_irq_init
-static inline void acpi_irq_init(void) { }
-#endif
-
-#endif /* _LINUX_ACPI_IRQ_H */
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 278dd27..7784b59 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -246,16 +246,13 @@
 #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \
 	OF_DECLARE_1(clksrc, name, compat, fn)
 
-#ifdef CONFIG_CLKSRC_OF
-extern void clocksource_of_init(void);
+#ifdef CONFIG_CLKSRC_PROBE
+extern void clocksource_probe(void);
 #else
-static inline void clocksource_of_init(void) {}
+static inline void clocksource_probe(void) {}
 #endif
 
-#ifdef CONFIG_ACPI
-void acpi_generic_timer_init(void);
-#else
-static inline void acpi_generic_timer_init(void) { }
-#endif
+#define CLOCKSOURCE_ACPI_DECLARE(name, table_id, fn)		\
+	ACPI_DECLARE_PROBE_ENTRY(clksrc, name, table_id, 0, NULL, 0, fn)
 
 #endif /* _LINUX_CLOCKSOURCE_H */
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 0408545..b08d6ba 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -16,6 +16,7 @@
 	FWNODE_INVALID = 0,
 	FWNODE_OF,
 	FWNODE_ACPI,
+	FWNODE_ACPI_DATA,
 	FWNODE_PDATA,
 };
 
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 388e3ae..24bea08 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -94,6 +94,7 @@
 /* PnP I/O specific bits (IORESOURCE_BITS) */
 #define IORESOURCE_IO_16BIT_ADDR	(1<<0)
 #define IORESOURCE_IO_FIXED		(1<<1)
+#define IORESOURCE_IO_SPARSE		(1<<2)
 
 /* PCI ROM control bits (IORESOURCE_BITS) */
 #define IORESOURCE_ROM_ENABLE		(1<<0)	/* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h
index 6388873..89c34b2 100644
--- a/include/linux/irqchip.h
+++ b/include/linux/irqchip.h
@@ -11,6 +11,7 @@
 #ifndef _LINUX_IRQCHIP_H
 #define _LINUX_IRQCHIP_H
 
+#include <linux/acpi.h>
 #include <linux/of.h>
 
 /*
@@ -25,6 +26,22 @@
  */
 #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
 
+/*
+ * This macro must be used by the different irqchip drivers to declare
+ * the association between their version and their initialization function.
+ *
+ * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
+ * same file.
+ * @subtable: Subtable to be identified in MADT
+ * @validate: Function to be called on that subtable to check its validity.
+ *            Can be NULL.
+ * @data: data to be checked by the validate function.
+ * @fn: initialization function
+ */
+#define IRQCHIP_ACPI_DECLARE(name, subtable, validate, data, fn)	\
+	ACPI_DECLARE_PROBE_ENTRY(irqchip, name, ACPI_SIG_MADT, 		\
+				 subtable, validate, data, fn)
+
 #ifdef CONFIG_IRQCHIP
 void irqchip_init(void);
 #else
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
deleted file mode 100644
index de3419e..0000000
--- a/include/linux/irqchip/arm-gic-acpi.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2014, Linaro Ltd.
- *	Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef ARM_GIC_ACPI_H_
-#define ARM_GIC_ACPI_H_
-
-#ifdef CONFIG_ACPI
-
-/*
- * Hard code here, we can not get memory size from MADT (but FDT does),
- * Actually no need to do that, because this size can be inferred
- * from GIC spec.
- */
-#define ACPI_GICV2_DIST_MEM_SIZE	(SZ_4K)
-#define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
-
-struct acpi_table_header;
-
-int gic_v2_acpi_init(struct acpi_table_header *table);
-void acpi_gic_init(void);
-#else
-static inline void acpi_gic_init(void) { }
-#endif
-
-#endif /* ARM_GIC_ACPI_H_ */
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index a965efa..89ab057 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -52,6 +52,30 @@
 	return ACPI_HANDLE(dev);
 }
 
+struct acpi_pci_root;
+struct acpi_pci_root_ops;
+
+struct acpi_pci_root_info {
+	struct acpi_pci_root		*root;
+	struct acpi_device		*bridge;
+	struct acpi_pci_root_ops	*ops;
+	struct list_head		resources;
+	char				name[16];
+};
+
+struct acpi_pci_root_ops {
+	struct pci_ops *pci_ops;
+	int (*init_info)(struct acpi_pci_root_info *info);
+	void (*release_info)(struct acpi_pci_root_info *info);
+	int (*prepare_resources)(struct acpi_pci_root_info *info);
+};
+
+extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info);
+extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
+					    struct acpi_pci_root_ops *ops,
+					    struct acpi_pci_root_info *info,
+					    void *sd);
+
 void acpi_pci_add_bus(struct pci_bus *bus);
 void acpi_pci_remove_bus(struct pci_bus *bus);
 
diff --git a/include/linux/property.h b/include/linux/property.h
index a59c6ee..463de52 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -40,6 +40,8 @@
 				      const char **val, size_t nval);
 int device_property_read_string(struct device *dev, const char *propname,
 				const char **val);
+int device_property_match_string(struct device *dev,
+				 const char *propname, const char *string);
 
 bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
 int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
@@ -59,6 +61,8 @@
 				      size_t nval);
 int fwnode_property_read_string(struct fwnode_handle *fwnode,
 				const char *propname, const char **val);
+int fwnode_property_match_string(struct fwnode_handle *fwnode,
+				 const char *propname, const char *string);
 
 struct fwnode_handle *device_get_next_child_node(struct device *dev,
 						 struct fwnode_handle *child);
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c
index a37f970..a1c62de 100644
--- a/tools/power/acpi/tools/acpidump/apfiles.c
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -150,7 +150,7 @@
 		strcat(filename, instance_str);
 	}
 
-	strcat(filename, ACPI_TABLE_FILE_SUFFIX);
+	strcat(filename, FILE_SUFFIX_BINARY_TABLE);
 
 	if (gbl_verbose_mode) {
 		acpi_log_error