/* * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology * Author: Fuxin Zhang, zhangfx@lemote.com * Copyright (C) 2009 Lemote, Inc. * Author: Zhangjin Wu, wuzhangjin@gmail.com */ #include #include #include #include #include #include static inline void loongson_reboot(void) { #ifndef CONFIG_CPU_JUMP_WORKAROUNDS ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); #else void (*func)(void); func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4); __asm__ __volatile__( " .set noat \n" " jr %[func] \n" " .set at \n" : /* No outputs */ : [func] "r" (func)); #endif } static void loongson_restart(char *command) { #ifndef CONFIG_LEFI_FIRMWARE_INTERFACE /* do preparation for reboot */ mach_prepare_reboot(); /* reboot via jumping to boot base address */ loongson_reboot(); #else void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr; fw_restart(); while (1) { if (cpu_wait) cpu_wait(); } #endif } static void loongson_poweroff(void) { #ifndef CONFIG_LEFI_FIRMWARE_INTERFACE mach_prepare_shutdown(); unreachable(); #else void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; fw_poweroff(); while (1) { if (cpu_wait) cpu_wait(); } #endif } static void loongson_halt(void) { pr_notice("\n\n** You can safely turn off the power now **\n\n"); while (1) { if (cpu_wait) cpu_wait(); } } static int __init mips_reboot_setup(void) { _machine_restart = loongson_restart; _machine_halt = loongson_halt; pm_power_off = loongson_poweroff; return 0; } arch_initcall(mips_reboot_setup);