diff options
author | Nate Lawson <njl@FreeBSD.org> | 2004-03-19 07:05:01 +0000 |
---|---|---|
committer | Nate Lawson <njl@FreeBSD.org> | 2004-03-19 07:05:01 +0000 |
commit | eeb3a05f9a9c93cddef556c33ed91b037c95eecd (patch) | |
tree | 68c529b021df291a706bfaa2e63792e232ff81d3 /sys/dev/acpica/acpi.c | |
parent | 4de762365a9b9a7abf2c4f8634a18d2c79e9fb8d (diff) | |
download | src-eeb3a05f9a9c93cddef556c33ed91b037c95eecd.tar.gz src-eeb3a05f9a9c93cddef556c33ed91b037c95eecd.zip |
Move the poweroff handler to a separate function. Make sure it is run
on the boot processor (cpuid == 0). Some chipsets do not power off the
system if the shutdown handler runs on an AP.
Notes
Notes:
svn path=/head/; revision=127193
Diffstat (limited to 'sys/dev/acpica/acpi.c')
-rw-r--r-- | sys/dev/acpica/acpi.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 41b2cdf738fe..2e3d3d1e029b 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -44,6 +44,7 @@ #include <sys/linker.h> #include <sys/power.h> #include <sys/sbuf.h> +#include <sys/smp.h> #include <machine/clock.h> #include <machine/resource.h> @@ -132,6 +133,7 @@ static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status); static void acpi_shutdown_pre_sync(void *arg, int howto); static void acpi_shutdown_final(void *arg, int howto); +static void acpi_shutdown_poweroff(void *arg); static void acpi_enable_fixed_events(struct acpi_softc *sc); static void acpi_system_eventhandler_sleep(void *arg, int state); static void acpi_system_eventhandler_wakeup(void *arg, int state); @@ -1177,26 +1179,17 @@ acpi_shutdown_pre_sync(void *arg, int howto) static void acpi_shutdown_final(void *arg, int howto) { - ACPI_STATUS status; ACPI_ASSERTLOCK; + /* + * If powering off, run the actual shutdown code on each processor. + * It will only perform the shutdown on the BSP. Some chipsets do + * not power off the system correctly if called from an AP. + */ if ((howto & RB_POWEROFF) != 0) { printf("Powering system off using ACPI\n"); - status = AcpiEnterSleepStatePrep(acpi_off_state); - if (ACPI_FAILURE(status)) { - printf("AcpiEnterSleepStatePrep failed - %s\n", - AcpiFormatException(status)); - return; - } - ACPI_DISABLE_IRQS(); - status = AcpiEnterSleepState(acpi_off_state); - if (ACPI_FAILURE(status)) { - printf("ACPI power-off failed - %s\n", AcpiFormatException(status)); - } else { - DELAY(1000000); - printf("ACPI power-off failed - timeout\n"); - } + smp_rendezvous(NULL, acpi_shutdown_poweroff, NULL, NULL); } else { printf("Shutting down ACPI\n"); AcpiTerminate(); @@ -1204,6 +1197,33 @@ acpi_shutdown_final(void *arg, int howto) } static void +acpi_shutdown_poweroff(void *arg) +{ + ACPI_STATUS status; + + ACPI_ASSERTLOCK; + + /* Only attempt to power off if this is the BSP (cpuid 0). */ + if (PCPU_GET(cpuid) != 0) + return; + + status = AcpiEnterSleepStatePrep(acpi_off_state); + if (ACPI_FAILURE(status)) { + printf("AcpiEnterSleepStatePrep failed - %s\n", + AcpiFormatException(status)); + return; + } + ACPI_DISABLE_IRQS(); + status = AcpiEnterSleepState(acpi_off_state); + if (ACPI_FAILURE(status)) { + printf("ACPI power-off failed - %s\n", AcpiFormatException(status)); + } else { + DELAY(1000000); + printf("ACPI power-off failed - timeout\n"); + } +} + +static void acpi_enable_fixed_events(struct acpi_softc *sc) { static int first_time = 1; |