1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 #include <linux/kernel.h> 6 #include <linux/acpi.h> 7 #include <linux/efi.h> 8 #include <linux/export.h> 9 #include <linux/pm.h> 10 #include <linux/types.h> 11 #include <linux/reboot.h> 12 #include <linux/delay.h> 13 #include <linux/console.h> 14 15 #include <acpi/reboot.h> 16 #include <asm/idle.h> 17 #include <asm/loongarch.h> 18 #include <asm/reboot.h> 19 20 static void default_halt(void) 21 { 22 local_irq_disable(); 23 clear_csr_ecfg(ECFG0_IM); 24 25 pr_notice("\n\n** You can safely turn off the power now **\n\n"); 26 console_flush_on_panic(CONSOLE_FLUSH_PENDING); 27 28 while (true) { 29 __arch_cpu_idle(); 30 } 31 } 32 33 static void default_poweroff(void) 34 { 35 #ifdef CONFIG_EFI 36 efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); 37 #endif 38 while (true) { 39 __arch_cpu_idle(); 40 } 41 } 42 43 static void default_restart(void) 44 { 45 #ifdef CONFIG_EFI 46 if (efi_capsule_pending(NULL)) 47 efi_reboot(REBOOT_WARM, NULL); 48 else 49 efi_reboot(REBOOT_COLD, NULL); 50 #endif 51 if (!acpi_disabled) 52 acpi_reboot(); 53 54 while (true) { 55 __arch_cpu_idle(); 56 } 57 } 58 59 void (*pm_restart)(void); 60 EXPORT_SYMBOL(pm_restart); 61 62 void (*pm_power_off)(void); 63 EXPORT_SYMBOL(pm_power_off); 64 65 void machine_halt(void) 66 { 67 #ifdef CONFIG_SMP 68 preempt_disable(); 69 smp_send_stop(); 70 #endif 71 default_halt(); 72 } 73 74 void machine_power_off(void) 75 { 76 #ifdef CONFIG_SMP 77 preempt_disable(); 78 smp_send_stop(); 79 #endif 80 pm_power_off(); 81 } 82 83 void machine_restart(char *command) 84 { 85 #ifdef CONFIG_SMP 86 preempt_disable(); 87 smp_send_stop(); 88 #endif 89 do_kernel_restart(command); 90 pm_restart(); 91 } 92 93 static int __init loongarch_reboot_setup(void) 94 { 95 pm_restart = default_restart; 96 pm_power_off = default_poweroff; 97 98 return 0; 99 } 100 101 arch_initcall(loongarch_reboot_setup); 102