]>
Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
85749d24 | 2 | /* |
85749d24 WZ |
3 | * |
4 | * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology | |
5 | * Author: Fuxin Zhang, zhangfx@lemote.com | |
6f320965 | 6 | * Copyright (C) 2009 Lemote, Inc. |
f7a904df | 7 | * Author: Zhangjin Wu, wuzhangjin@gmail.com |
85749d24 WZ |
8 | */ |
9 | #include <linux/init.h> | |
10 | #include <linux/pm.h> | |
11 | ||
bdc92d74 | 12 | #include <asm/idle.h> |
85749d24 WZ |
13 | #include <asm/reboot.h> |
14 | ||
15 | #include <loongson.h> | |
1a08f152 | 16 | #include <boot_param.h> |
85749d24 | 17 | |
64fc74f5 WZ |
18 | static 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__( | |
70342287 RB |
28 | " .set noat \n" |
29 | " jr %[func] \n" | |
30 | " .set at \n" | |
64fc74f5 WZ |
31 | : /* No outputs */ |
32 | : [func] "r" (func)); | |
33 | #endif | |
34 | } | |
35 | ||
85749d24 WZ |
36 | static void loongson_restart(char *command) |
37 | { | |
1a08f152 | 38 | #ifndef CONFIG_LEFI_FIRMWARE_INTERFACE |
85749d24 WZ |
39 | /* do preparation for reboot */ |
40 | mach_prepare_reboot(); | |
41 | ||
42 | /* reboot via jumping to boot base address */ | |
64fc74f5 | 43 | loongson_reboot(); |
1a08f152 HC |
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 | |
85749d24 WZ |
53 | } |
54 | ||
fc48c41a | 55 | static void loongson_poweroff(void) |
85749d24 | 56 | { |
1a08f152 | 57 | #ifndef CONFIG_LEFI_FIRMWARE_INTERFACE |
85749d24 | 58 | mach_prepare_shutdown(); |
8a96669d YL |
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; | |
1a08f152 HC |
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 | |
85749d24 WZ |
74 | } |
75 | ||
fc48c41a WZ |
76 | static 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 | ||
85749d24 WZ |
85 | static int __init mips_reboot_setup(void) |
86 | { | |
87 | _machine_restart = loongson_restart; | |
88 | _machine_halt = loongson_halt; | |
fc48c41a | 89 | pm_power_off = loongson_poweroff; |
85749d24 WZ |
90 | |
91 | return 0; | |
92 | } | |
93 | ||
94 | arch_initcall(mips_reboot_setup); |