]>
Commit | Line | Data |
---|---|---|
fc3fed8a GKH |
1 | From 6f389a8f1dd22a24f3d9afc2812b30d639e94625 Mon Sep 17 00:00:00 2001 |
2 | From: Huacai Chen <chenhc@lemote.com> | |
3 | Date: Sun, 7 Apr 2013 02:14:14 +0000 | |
4 | Subject: PM / reboot: call syscore_shutdown() after disable_nonboot_cpus() | |
5 | ||
6 | From: Huacai Chen <chenhc@lemote.com> | |
7 | ||
8 | commit 6f389a8f1dd22a24f3d9afc2812b30d639e94625 upstream. | |
9 | ||
10 | As commit 40dc166c (PM / Core: Introduce struct syscore_ops for core | |
11 | subsystems PM) say, syscore_ops operations should be carried with one | |
12 | CPU on-line and interrupts disabled. However, after commit f96972f2d | |
13 | (kernel/sys.c: call disable_nonboot_cpus() in kernel_restart()), | |
14 | syscore_shutdown() is called before disable_nonboot_cpus(), so break | |
15 | the rules. We have a MIPS machine with a 8259A PIC, and there is an | |
16 | external timer (HPET) linked at 8259A. Since 8259A has been shutdown | |
17 | too early (by syscore_shutdown()), disable_nonboot_cpus() runs without | |
18 | timer interrupt, so it hangs and reboot fails. This patch call | |
19 | syscore_shutdown() a little later (after disable_nonboot_cpus()) to | |
20 | avoid reboot failure, this is the same way as poweroff does. | |
21 | ||
22 | For consistency, add disable_nonboot_cpus() to kernel_halt(). | |
23 | ||
24 | Signed-off-by: Huacai Chen <chenhc@lemote.com> | |
25 | Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | |
26 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
27 | ||
28 | --- | |
29 | kernel/sys.c | 3 ++- | |
30 | 1 file changed, 2 insertions(+), 1 deletion(-) | |
31 | ||
32 | --- a/kernel/sys.c | |
33 | +++ b/kernel/sys.c | |
34 | @@ -323,7 +323,6 @@ void kernel_restart_prepare(char *cmd) | |
35 | system_state = SYSTEM_RESTART; | |
36 | usermodehelper_disable(); | |
37 | device_shutdown(); | |
38 | - syscore_shutdown(); | |
39 | } | |
40 | ||
41 | /** | |
42 | @@ -369,6 +368,7 @@ void kernel_restart(char *cmd) | |
43 | { | |
44 | kernel_restart_prepare(cmd); | |
45 | disable_nonboot_cpus(); | |
46 | + syscore_shutdown(); | |
47 | if (!cmd) | |
48 | printk(KERN_EMERG "Restarting system.\n"); | |
49 | else | |
50 | @@ -394,6 +394,7 @@ static void kernel_shutdown_prepare(enum | |
51 | void kernel_halt(void) | |
52 | { | |
53 | kernel_shutdown_prepare(SYSTEM_HALT); | |
54 | + disable_nonboot_cpus(); | |
55 | syscore_shutdown(); | |
56 | printk(KERN_EMERG "System halted.\n"); | |
57 | kmsg_dump(KMSG_DUMP_HALT); |