diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index 7b27b9cc5916..4c8196adb98e 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -56,6 +56,8 @@
  */
 acpi_status acpi_ns_initialize_objects(void);
 
+acpi_status acpi_ns_early_initialize_devices(void);
+
 acpi_status acpi_ns_initialize_devices(u32 flags);
 
 acpi_status
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 3e6207ad18d8..f5364d44fdb8 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -86,6 +86,59 @@ acpi_status acpi_ns_initialize_objects(void)
 	return_ACPI_STATUS(AE_OK);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_early_initialize_devices
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      acpi_status
+ *
+ * DESCRIPTION: Call _INI on various root devices, this must be done
+ *              before any other evaluations as those might depend on this.
+ *
+ ******************************************************************************/
+static acpi_string const acpi_ns_early_init_paths[] = {
+	/* Global \_INI method. Provided for Windows compatibility (Vista+),
+	 * not part of the ACPI specification. */
+	ACPI_NS_ROOT_PATH,
+	/* There appears to be a strict order requirement for \_SB._INI,
+	 * which should be evaluated before any _REG evaluations. */
+	"\\_SB",
+};
+
+acpi_status acpi_ns_early_initialize_devices(void)
+{
+	struct acpi_evaluate_info *info;
+	acpi_status status;
+	acpi_handle handle;
+	int i;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Initializing Early ACPI Devices\n"));
+
+	info = ACPI_ALLOCATE(sizeof(struct acpi_evaluate_info));
+	if (!info)
+		return AE_NO_MEMORY;
+
+	for (i = 0; i < ARRAY_SIZE(acpi_ns_early_init_paths); i++) {
+		status = acpi_get_handle(NULL, acpi_ns_early_init_paths[i], &handle);
+		if (!ACPI_SUCCESS(status))
+			continue;
+
+		memset(info, 0, sizeof(struct acpi_evaluate_info));
+		info->prefix_node = handle;
+		info->relative_pathname = METHOD_NAME__INI;
+		info->parameters = NULL;
+		info->flags = ACPI_IGNORE_RETURN_VALUE;
+
+		acpi_ns_evaluate(info);
+	}
+
+	ACPI_FREE(info);
+	return AE_OK;
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_initialize_devices
@@ -105,12 +158,41 @@ acpi_status acpi_ns_initialize_objects(void)
 acpi_status acpi_ns_initialize_devices(u32 flags)
 {
 	acpi_status status = AE_OK;
-	struct acpi_device_walk_info info;
-	acpi_handle handle;
 
 	ACPI_FUNCTION_TRACE(ns_initialize_devices);
 
+	if (!(flags & (ACPI_NO_DEVICE_INIT | ACPI_NO_EARLY_DEVICE_INIT))) {
+		status = acpi_ns_early_initialize_devices();
+		if (ACPI_FAILURE(status))
+			goto error_exit;
+	}
+
+	/*
+	 * Run all _REG methods
+	 *
+	 * Note: Any objects accessed by the _REG methods will be automatically
+	 * initialized, even if they contain executable AML (see the call to
+	 * acpi_ns_initialize_objects below).
+	 *
+	 * Note: According to the ACPI specification, we actually needn't execute
+	 * _REG for system_memory/system_io operation regions, but for PCI_Config
+	 * operation regions, it is required to evaluate _REG for those on a PCI
+	 * root bus that doesn't contain _BBN object. So this code is kept here
+	 * in order not to break things.
+	 */
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Executing _REG OpRegion methods\n"));
+
+		status = acpi_ev_initialize_op_regions();
+		if (ACPI_FAILURE(status)) {
+			goto error_exit;
+		}
+	}
+
 	if (!(flags & ACPI_NO_DEVICE_INIT)) {
+		struct acpi_device_walk_info info;
+
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "[Init] Initializing ACPI Devices\n"));
 
@@ -143,68 +225,6 @@ acpi_status acpi_ns_initialize_devices(u32 flags)
 			goto error_exit;
 		}
 
-		/*
-		 * Execute the "global" _INI method that may appear at the root.
-		 * This support is provided for Windows compatibility (Vista+) and
-		 * is not part of the ACPI specification.
-		 */
-		info.evaluate_info->prefix_node = acpi_gbl_root_node;
-		info.evaluate_info->relative_pathname = METHOD_NAME__INI;
-		info.evaluate_info->parameters = NULL;
-		info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
-
-		status = acpi_ns_evaluate(info.evaluate_info);
-		if (ACPI_SUCCESS(status)) {
-			info.num_INI++;
-		}
-
-		/*
-		 * Execute \_SB._INI.
-		 * There appears to be a strict order requirement for \_SB._INI,
-		 * which should be evaluated before any _REG evaluations.
-		 */
-		status = acpi_get_handle(NULL, "\\_SB", &handle);
-		if (ACPI_SUCCESS(status)) {
-			memset(info.evaluate_info, 0,
-			       sizeof(struct acpi_evaluate_info));
-			info.evaluate_info->prefix_node = handle;
-			info.evaluate_info->relative_pathname =
-			    METHOD_NAME__INI;
-			info.evaluate_info->parameters = NULL;
-			info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
-
-			status = acpi_ns_evaluate(info.evaluate_info);
-			if (ACPI_SUCCESS(status)) {
-				info.num_INI++;
-			}
-		}
-	}
-
-	/*
-	 * Run all _REG methods
-	 *
-	 * Note: Any objects accessed by the _REG methods will be automatically
-	 * initialized, even if they contain executable AML (see the call to
-	 * acpi_ns_initialize_objects below).
-	 *
-	 * Note: According to the ACPI specification, we actually needn't execute
-	 * _REG for system_memory/system_io operation regions, but for PCI_Config
-	 * operation regions, it is required to evaluate _REG for those on a PCI
-	 * root bus that doesn't contain _BBN object. So this code is kept here
-	 * in order not to break things.
-	 */
-	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Executing _REG OpRegion methods\n"));
-
-		status = acpi_ev_initialize_op_regions();
-		if (ACPI_FAILURE(status)) {
-			goto error_exit;
-		}
-	}
-
-	if (!(flags & ACPI_NO_DEVICE_INIT)) {
-
 		/* Walk namespace to execute all _INIs on present devices */
 
 		status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
@@ -497,6 +517,21 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle,
 	return (AE_OK);
 }
 
+static u8 acpi_ns_is_early_init_device(struct acpi_namespace_node *device_node)
+{
+	char path[ACPI_PATH_SEGMENT_LENGTH + 2];
+	int i;
+
+	acpi_ns_build_normalized_path(device_node, path, sizeof(path), TRUE);
+
+	for (i = 0; i < ARRAY_SIZE(acpi_ns_early_init_paths); i++) {
+		if (!strcmp(path, acpi_ns_early_init_paths[i]))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_init_one_device
@@ -630,8 +665,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
 	 * Note: We know there is an _INI within this subtree, but it may not be
 	 * under this particular device, it may be lower in the branch.
 	 */
-	if (!ACPI_COMPARE_NAMESEG(device_node->name.ascii, "_SB_") ||
-	    device_node->parent != acpi_gbl_root_node) {
+	if (!acpi_ns_is_early_init_device(device_node)) {
 		ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
 				(ACPI_TYPE_METHOD, device_node,
 				 METHOD_NAME__INI));
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
index f2acec3a0ee3..4396ec7f1246 100644
--- a/drivers/acpi/acpica/utxfinit.c
+++ b/drivers/acpi/acpica/utxfinit.c
@@ -193,6 +193,27 @@ acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)
 
 ACPI_EXPORT_SYMBOL_INIT(acpi_enable_subsystem)
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_early_initialize_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Call _INI on various root objects, this must be done before
+ *              any other AML evaluations as those might depend on this.
+ *              This is automatically called by acpi_initialize_objects(),
+ *              unless ACPI_NO_EARLY_DEVICE_INIT is passed.
+ *
+ ******************************************************************************/
+acpi_status ACPI_INIT_FUNCTION acpi_early_initialize_objects(void)
+{
+	return acpi_ns_early_initialize_devices();
+}
+
+ACPI_EXPORT_SYMBOL_INIT(acpi_early_initialize_objects)
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_initialize_objects
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 67c0b9e734b6..4b8d19f48071 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -410,6 +410,8 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
 			     acpi_initialize_subsystem(void))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
 			     acpi_enable_subsystem(u32 flags))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
+			     acpi_early_initialize_objects(void))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
 			     acpi_initialize_objects(u32 flags))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 3491e454b2ab..e377b7daec54 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -565,7 +565,8 @@ typedef u64 acpi_integer;
 #define ACPI_NO_HANDLER_INIT            0x0010
 #define ACPI_NO_OBJECT_INIT             0x0020
 #define ACPI_NO_DEVICE_INIT             0x0040
-#define ACPI_NO_ADDRESS_SPACE_INIT      0x0080
+#define ACPI_NO_EARLY_DEVICE_INIT       0x0080
+#define ACPI_NO_ADDRESS_SPACE_INIT      0x0100
 
 /*
  * Initialization state
