--- /dev/null
+From b064a8fa77dfead647564c46ac8fc5b13bd1ab73 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Wed, 10 Jun 2015 01:33:36 +0200
+Subject: ACPI / init: Switch over platform to the ACPI mode later
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+
+commit b064a8fa77dfead647564c46ac8fc5b13bd1ab73 upstream.
+
+Commit 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before
+timekeeping_init()" moved the ACPI subsystem initialization,
+including the ACPI mode enabling, to an earlier point in the
+initialization sequence, to allow the timekeeping subsystem
+use ACPI early. Unfortunately, that resulted in boot regressions
+on some systems and the early ACPI initialization was moved toward
+its original position in the kernel initialization code by commit
+c4e1acbb35e4 "ACPI / init: Invoke early ACPI initialization later".
+
+However, that turns out to be insufficient, as boot is still broken
+on the Tyan S8812 mainboard.
+
+To fix that issue, split the ACPI early initialization code into
+two pieces so the majority of it still located in acpi_early_init()
+and the part switching over the platform into the ACPI mode goes into
+a new function, acpi_subsystem_init(), executed at the original early
+ACPI initialization spot.
+
+That fixes the Tyan S8812 boot problem, but still allows ACPI
+tables to be loaded earlier which is useful to the EFI code in
+efi_enter_virtual_mode().
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=97141
+Fixes: 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before timekeeping_init()"
+Reported-and-tested-by: Marius Tolzmann <tolzmann@molgen.mpg.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Toshi Kani <toshi.kani@hp.com>
+Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
+Reviewed-by: Lee, Chun-Yi <jlee@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/bus.c | 56 +++++++++++++++++++++++++++++++++++++--------------
+ include/linux/acpi.h | 2 +
+ init/main.c | 1
+ 3 files changed, 44 insertions(+), 15 deletions(-)
+
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -450,6 +450,16 @@ static int __init acpi_bus_init_irq(void
+ u8 acpi_gbl_permanent_mmap;
+
+
++/**
++ * acpi_early_init - Initialize ACPICA and populate the ACPI namespace.
++ *
++ * The ACPI tables are accessible after this, but the handling of events has not
++ * been initialized and the global lock is not available yet, so AML should not
++ * be executed at this point.
++ *
++ * Doing this before switching the EFI runtime services to virtual mode allows
++ * the EfiBootServices memory to be freed slightly earlier on boot.
++ */
+ void __init acpi_early_init(void)
+ {
+ acpi_status status;
+@@ -510,26 +520,42 @@ void __init acpi_early_init(void)
+ acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
+ }
+ #endif
++ return;
++
++ error0:
++ disable_acpi();
++}
++
++/**
++ * acpi_subsystem_init - Finalize the early initialization of ACPI.
++ *
++ * Switch over the platform to the ACPI mode (if possible), initialize the
++ * handling of ACPI events, install the interrupt and global lock handlers.
++ *
++ * Doing this too early is generally unsafe, but at the same time it needs to be
++ * done before all things that really depend on ACPI. The right spot appears to
++ * be before finalizing the EFI initialization.
++ */
++void __init acpi_subsystem_init(void)
++{
++ acpi_status status;
++
++ if (acpi_disabled)
++ return;
+
+ status = acpi_enable_subsystem(~ACPI_NO_ACPI_ENABLE);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
+- goto error0;
++ disable_acpi();
++ } else {
++ /*
++ * If the system is using ACPI then we can be reasonably
++ * confident that any regulators are managed by the firmware
++ * so tell the regulator core it has everything it needs to
++ * know.
++ */
++ regulator_has_full_constraints();
+ }
+-
+- /*
+- * If the system is using ACPI then we can be reasonably
+- * confident that any regulators are managed by the firmware
+- * so tell the regulator core it has everything it needs to
+- * know.
+- */
+- regulator_has_full_constraints();
+-
+- return;
+-
+- error0:
+- disable_acpi();
+- return;
+ }
+
+ static int __init acpi_bus_init(void)
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -402,6 +402,7 @@ extern acpi_status acpi_pci_osc_control_
+ #define ACPI_OST_SC_INSERT_NOT_SUPPORTED 0x82
+
+ extern void acpi_early_init(void);
++extern void acpi_subsystem_init(void);
+
+ extern int acpi_nvs_register(__u64 start, __u64 size);
+
+@@ -436,6 +437,7 @@ static inline const char *acpi_dev_name(
+ }
+
+ static inline void acpi_early_init(void) { }
++static inline void acpi_subsystem_init(void) { }
+
+ static inline int early_acpi_boot_init(void)
+ {
+--- a/init/main.c
++++ b/init/main.c
+@@ -643,6 +643,7 @@ asmlinkage void __init start_kernel(void
+
+ check_bugs();
+
++ acpi_subsystem_init();
+ sfi_init_late();
+
+ if (efi_enabled(EFI_RUNTIME_SERVICES)) {