diff options
-rw-r--r-- | drivers/firmware/efi/reboot.c | 22 | ||||
-rw-r--r-- | include/linux/efi.h | 2 |
2 files changed, 24 insertions, 0 deletions
diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c index 81bf925f70f5..e9eeeb3c6345 100644 --- a/drivers/firmware/efi/reboot.c +++ b/drivers/firmware/efi/reboot.c @@ -24,3 +24,25 @@ void efi_reboot(enum reboot_mode reboot_mode, const char *__unused) efi.reset_system(efi_mode, EFI_SUCCESS, 0, NULL); } + +bool __weak efi_poweroff_required(void) +{ + return false; +} + +static void efi_power_off(void) +{ + efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); +} + +static int __init efi_shutdown_init(void) +{ + if (!efi_enabled(EFI_RUNTIME_SERVICES)) + return -ENODEV; + + if (efi_poweroff_required()) + pm_power_off = efi_power_off; + + return 0; +} +late_initcall(efi_shutdown_init); diff --git a/include/linux/efi.h b/include/linux/efi.h index e6980ba528ec..9917f58ee83e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -878,6 +878,8 @@ extern void efi_reserve_boot_services(void); extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose); extern struct efi_memory_map memmap; +extern bool efi_poweroff_required(void); + /* Iterate through an efi_memory_map */ #define for_each_efi_memory_desc(m, md) \ for ((md) = (m)->map; \ |