Merge tag 'arm-dt-6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / arch / loongarch / kernel / reset.c
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);