1 /* 1 /* 2 * Copyright (C) 2009 Michal Simek <monstr@mon << 3 * Copyright (C) 2009 PetaLogix << 4 * << 5 * This file is subject to the terms and condi 2 * This file is subject to the terms and conditions of the GNU General Public 6 * License. See the file "COPYING" in the main !! 3 * License. See the file "COPYING" in the main directory of this archive 7 * for more details. 4 * for more details. >> 5 * >> 6 * Copyright (C) 2001, 06 by Ralf Baechle (ralf@linux-mips.org) >> 7 * Copyright (C) 2001 MIPS Technologies, Inc. 8 */ 8 */ 9 !! 9 #include <linux/kernel.h> 10 #include <linux/init.h> !! 10 #include <linux/export.h> 11 #include <linux/delay.h> !! 11 #include <linux/pm.h> >> 12 #include <linux/types.h> 12 #include <linux/reboot.h> 13 #include <linux/reboot.h> >> 14 #include <linux/delay.h> >> 15 >> 16 #include <asm/compiler.h> >> 17 #include <asm/idle.h> >> 18 #include <asm/mipsregs.h> >> 19 #include <asm/reboot.h> 13 20 14 void machine_shutdown(void) !! 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) 15 { 33 { 16 pr_notice("Machine shutdown...\n"); !! 34 /* 17 while (1) !! 35 * We're hanging the system so we don't want to be interrupted anymore. 18 ; !! 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 } 19 } 86 } 20 87 21 void machine_halt(void) !! 88 void machine_restart(char *command) 22 { 89 { 23 pr_notice("Machine halt...\n"); !! 90 if (_machine_restart) 24 while (1) !! 91 _machine_restart(command); 25 ; !! 92 >> 93 #ifdef CONFIG_SMP >> 94 preempt_disable(); >> 95 smp_send_stop(); >> 96 #endif >> 97 do_kernel_restart(command); >> 98 mdelay(1000); >> 99 pr_emerg("Reboot failed -- System halted\n"); >> 100 machine_hang(); 26 } 101 } 27 102 28 void machine_power_off(void) !! 103 void machine_halt(void) 29 { 104 { 30 pr_notice("Machine power off...\n"); !! 105 if (_machine_halt) 31 while (1) !! 106 _machine_halt(); 32 ; !! 107 >> 108 #ifdef CONFIG_SMP >> 109 preempt_disable(); >> 110 smp_send_stop(); >> 111 #endif >> 112 machine_hang(); 33 } 113 } 34 114 35 void machine_restart(char *cmd) !! 115 void machine_power_off(void) 36 { 116 { 37 do_kernel_restart(cmd); !! 117 do_kernel_power_off(); 38 /* Give the restart hook 1 s to take u !! 118 39 mdelay(1000); !! 119 #ifdef CONFIG_SMP 40 pr_emerg("Reboot failed -- System halt !! 120 preempt_disable(); 41 while (1); !! 121 smp_send_stop(); >> 122 #endif >> 123 machine_hang(); 42 } 124 } 43 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.