1 // SPDX-License-Identifier: GPL-2.0-only << 2 /* 1 /* 3 * Copyright (c) 2010-2011, The Linux Foundati !! 2 * This file is subject to the terms and conditions of the GNU General Public >> 3 * License. See the file "COPYING" in the main directory of this archive >> 4 * for more details. >> 5 * >> 6 * Copyright (C) 2001, 06 by Ralf Baechle (ralf@linux-mips.org) >> 7 * Copyright (C) 2001 MIPS Technologies, Inc. 4 */ 8 */ 5 !! 9 #include <linux/kernel.h> >> 10 #include <linux/export.h> >> 11 #include <linux/pm.h> >> 12 #include <linux/types.h> 6 #include <linux/reboot.h> 13 #include <linux/reboot.h> 7 #include <linux/smp.h> !! 14 #include <linux/delay.h> 8 #include <asm/hexagon_vm.h> << 9 15 10 void machine_power_off(void) !! 16 #include <asm/compiler.h> >> 17 #include <asm/idle.h> >> 18 #include <asm/mipsregs.h> >> 19 #include <asm/reboot.h> >> 20 >> 21 /* >> 22 * Urgs ... Too many MIPS machines to handle this in a generic way. >> 23 * So handle all using function pointers to machine specific >> 24 * functions. >> 25 */ >> 26 void (*_machine_restart)(char *command); >> 27 void (*_machine_halt)(void); >> 28 void (*pm_power_off)(void); >> 29 >> 30 EXPORT_SYMBOL(pm_power_off); >> 31 >> 32 static void machine_hang(void) >> 33 { >> 34 /* >> 35 * We're hanging the system so we don't want to be interrupted anymore. >> 36 * Any interrupt handlers that ran would at best be useless & at worst >> 37 * go awry because the system isn't in a functional state. >> 38 */ >> 39 local_irq_disable(); >> 40 >> 41 /* >> 42 * Mask all interrupts, giving us a better chance of remaining in the >> 43 * low power wait state. >> 44 */ >> 45 clear_c0_status(ST0_IM); >> 46 >> 47 while (true) { >> 48 if (cpu_has_mips_r) { >> 49 /* >> 50 * We know that the wait instruction is supported so >> 51 * make use of it directly, leaving interrupts >> 52 * disabled. >> 53 */ >> 54 asm volatile( >> 55 ".set push\n\t" >> 56 ".set " MIPS_ISA_ARCH_LEVEL "\n\t" >> 57 "wait\n\t" >> 58 ".set pop"); >> 59 } else if (cpu_wait) { >> 60 /* >> 61 * Try the cpu_wait() callback. This isn't ideal since >> 62 * it'll re-enable interrupts, but that ought to be >> 63 * harmless given that they're all masked. >> 64 */ >> 65 cpu_wait(); >> 66 local_irq_disable(); >> 67 } else { >> 68 /* >> 69 * We're going to burn some power running round the >> 70 * loop, but we don't really have a choice. This isn't >> 71 * a path we should expect to run for long during >> 72 * typical use anyway. >> 73 */ >> 74 } >> 75 >> 76 /* >> 77 * In most modern MIPS CPUs interrupts will cause the wait >> 78 * instruction to graduate even when disabled, and in some >> 79 * cases even when masked. In order to prevent a timer >> 80 * interrupt from continuously taking us out of the low power >> 81 * wait state, we clear any pending timer interrupt here. >> 82 */ >> 83 if (cpu_has_counter) >> 84 write_c0_compare(0); >> 85 } >> 86 } >> 87 >> 88 void machine_restart(char *command) 11 { 89 { >> 90 if (_machine_restart) >> 91 _machine_restart(command); >> 92 >> 93 #ifdef CONFIG_SMP >> 94 preempt_disable(); 12 smp_send_stop(); 95 smp_send_stop(); 13 __vmstop(); !! 96 #endif >> 97 do_kernel_restart(command); >> 98 mdelay(1000); >> 99 pr_emerg("Reboot failed -- System halted\n"); >> 100 machine_hang(); 14 } 101 } 15 102 16 void machine_halt(void) 103 void machine_halt(void) 17 { 104 { >> 105 if (_machine_halt) >> 106 _machine_halt(); >> 107 >> 108 #ifdef CONFIG_SMP >> 109 preempt_disable(); >> 110 smp_send_stop(); >> 111 #endif >> 112 machine_hang(); 18 } 113 } 19 114 20 void machine_restart(char *cmd) !! 115 void machine_power_off(void) 21 { 116 { 22 } !! 117 do_kernel_power_off(); 23 118 24 void (*pm_power_off)(void) = NULL; !! 119 #ifdef CONFIG_SMP 25 EXPORT_SYMBOL(pm_power_off); !! 120 preempt_disable(); >> 121 smp_send_stop(); >> 122 #endif >> 123 machine_hang(); >> 124 } 26 125
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.