1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * 4 * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology 5 * Author: Fuxin Zhang, zhangfx@lemote.com 6 * Copyright (C) 2009 Lemote, Inc. 7 * Author: Zhangjin Wu, wuzhangjin@gmail.com 8 */ 9 #include <linux/init.h> 10 #include <linux/pm.h> 11 12 #include <asm/idle.h> 13 #include <asm/reboot.h> 14 15 #include <loongson.h> 16 #include <boot_param.h> 17 loongson_reboot(void)18static inline void loongson_reboot(void) 19 { 20 #ifndef CONFIG_CPU_JUMP_WORKAROUNDS 21 ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); 22 #else 23 void (*func)(void); 24 25 func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4); 26 27 __asm__ __volatile__( 28 " .set noat \n" 29 " jr %[func] \n" 30 " .set at \n" 31 : /* No outputs */ 32 : [func] "r" (func)); 33 #endif 34 } 35 loongson_restart(char * command)36static void loongson_restart(char *command) 37 { 38 #ifndef CONFIG_LEFI_FIRMWARE_INTERFACE 39 /* do preparation for reboot */ 40 mach_prepare_reboot(); 41 42 /* reboot via jumping to boot base address */ 43 loongson_reboot(); 44 #else 45 void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr; 46 47 fw_restart(); 48 while (1) { 49 if (cpu_wait) 50 cpu_wait(); 51 } 52 #endif 53 } 54 loongson_poweroff(void)55static void loongson_poweroff(void) 56 { 57 #ifndef CONFIG_LEFI_FIRMWARE_INTERFACE 58 mach_prepare_shutdown(); 59 60 /* 61 * It needs a wait loop here, but mips/kernel/reset.c already calls 62 * a generic delay loop, machine_hang(), so simply return. 63 */ 64 return; 65 #else 66 void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; 67 68 fw_poweroff(); 69 while (1) { 70 if (cpu_wait) 71 cpu_wait(); 72 } 73 #endif 74 } 75 loongson_halt(void)76static void loongson_halt(void) 77 { 78 pr_notice("\n\n** You can safely turn off the power now **\n\n"); 79 while (1) { 80 if (cpu_wait) 81 cpu_wait(); 82 } 83 } 84 mips_reboot_setup(void)85static int __init mips_reboot_setup(void) 86 { 87 _machine_restart = loongson_restart; 88 _machine_halt = loongson_halt; 89 pm_power_off = loongson_poweroff; 90 91 return 0; 92 } 93 94 arch_initcall(mips_reboot_setup); 95